fx
The atago project wrote these specs on its own initiative and runs them in its own CI, to exercise atago against a real program. They are not fx’s official test suite, and the fx project is not affiliated with atago.
Summary #
4 suites · 50 scenarios
Contents #
- fx (side effects on disk) — 7 scenarios
- save rewrites the file it was given and touches nothing else
- running the same normalization twice changes nothing the second time
- a reducer that only reads leaves the workdir alone
- save without a file argument fails and writes nothing
- save refuses to write through a symlink and leaves the target intact
- a .fxrc.js in the working directory adds a function reducers can call
- a .fxrc.js in the home directory is loaded too, and fx writes nothing there
- fx (input formats, strictness, round trips) — 19 scenarios
- –yaml parses YAML into the JSON model
- –toml parses TOML into the JSON model
- a .yaml file argument switches parsers with no flag at all
- a .toml file argument does the same
- extension detection ignores case
- an unknown extension stays on the JSON parser
- –raw treats each input line as a string
- -s collects a stream of documents into one array
- -rs combines raw lines into an array of strings
- the default parser accepts comments and a trailing comma
- –strict rejects a comment
- –strict rejects a trailing comma
- –raw and –yaml together are refused
- –yaml and –toml together are refused
- base64 encoding round-trips through a second fx
- a document survives a JSON to YAML to JSON round trip byte for byte
- –no-inline expands the containers the default output packs onto one line
- malformed YAML fails with a diagnostic that points at the line
- malformed TOML fails without writing to stdout
- fx (third-party CLI, JSON reducer contract) — 16 scenarios
- version prints a semantic version
- the identity reducer pretty-prints the document and keeps key order
- a dotted path selects a nested value and prints strings unquoted
- reducers compose left to right
- an arrow function transforms the document
- a missing key reports undefined on stderr and still exits 0
- dereferencing through a missing key is a hard error
- exit() hands the reducer’s own code to the shell
- invalid JSON fails loudly and keeps stdout clean
- a missing input file fails before anything is printed
- empty input succeeds with no output at all
- each document in a stream produces its own result
- filter drops documents from a stream instead of emitting them
- the identity path keeps number literals JavaScript would rewrite
- piped output carries no terminal escapes
- a directory given as input fails without writing to stdout
- fx (interactive viewer, pty testbed) — 8 scenarios
- the viewer renders the document and quits cleanly on q
- esc leaves the viewer with a success code
- the interface goes to stderr, so a redirected stdout stays empty
- P prints the value under the cursor to stdout
- collapse-all folds the containers and expand-all brings them back
- search moves the cursor to the match and the status bar shows its path
- the rendered frame shows the tree and the status bar together
- with a terminal and no file, fx prints its usage instead of opening the viewer
fx (side effects on disk) #
A JSON viewer sounds like a read-only program, and mostly it is — which is exactly why the places where fx writes deserve an exhaustive delta rather than a per-file check.
Two of them exist. save rewrites the file fx was given, in place, and
refuses to do so when there is no file or when the path is a symlink. And
before any reducer runs, fx loads .fxrc.js from the working directory and
from the user’s home, so a stray file in either place changes what a
reducer means. changes: states the whole picture in one assertion —
what was written and, just as importantly, that nothing else was — and
sandbox_home puts the home directory inside the workdir so a write there
would show up in the same delta.
Source: test/e2e/thirdparty/fx/changes.atago.yaml
Scenario: save rewrites the file it was given and touches nothing else #
only when fx --version succeeds
Given #
- Fixture file
config.jsonis created. - Fixture file
untouched.jsonis created. - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture config.json:
{"b":2,"a":1}
Fixture untouched.json:
{"keep":true}
When #
fx config.json sortKeys save
Then #
- exit code is
0 - the step changed exactly created nothing, modified
config.json, deleted nothing - file
config.jsonequals exact bytes
Scenario: running the same normalization twice changes nothing the second time #
only when fx --version succeeds
Given #
- Fixture file
config.jsonis created. - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected). - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture config.json:
{"b":2,"a":1}
When #
fx config.json sortKeys save
fx config.json sortKeys save
Then #
- after
fx config.json sortKeys save:- exit code is
0 - the step changed exactly modified
config.json
- exit code is
- after
fx config.json sortKeys save:- exit code is
0 - the step changed exactly created nothing, modified nothing, deleted nothing
- exit code is
Scenario: a reducer that only reads leaves the workdir alone #
only when fx --version succeeds
Given #
- Fixture file
config.jsonis created. - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture config.json:
{"a":1}
When #
fx config.json .a
Then #
- exit code is
0 - stdout equals an exact value
- the step changed exactly created nothing, modified nothing, deleted nothing
Scenario: save without a file argument fails and writes nothing #
only when fx --version succeeds
Given #
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
stdin for fx:
{"a":1}
When #
fx save
Then #
- exit code is
1 - stderr contains
specify a file as the first argument - the step changed exactly created nothing, modified nothing, deleted nothing
Scenario: save refuses to write through a symlink and leaves the target intact #
only when fx --version succeeds · skipped on Windows
Given #
- Fixture file
real.jsonis created. - Fixture file
link.jsonis created. - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture real.json:
{"b":2,"a":1}
When #
fx link.json sortKeys save
Then #
- exit code is
1 - stderr contains
cannot save to a symbolic link - the step changed exactly created nothing, modified nothing, deleted nothing
- file
real.jsonequals exact bytes
Scenario: a .fxrc.js in the working directory adds a function reducers can call #
only when fx --version succeeds
Given #
- Fixture file
.fxrc.jsis created. - Fixture file
data.jsonis created. - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture .fxrc.js:
function double(x) {
return x * 2
}
Fixture data.json:
{"n":21}
When #
fx data.json .n double
Then #
- exit code is
0 - stdout equals an exact value
- the step changed exactly created nothing, modified nothing, deleted nothing
Scenario: a .fxrc.js in the home directory is loaded too, and fx writes nothing there #
only when fx --version succeeds · skipped on Windows
Given #
- Fixture file
.atago-home/.fxrc.jsis created. - Fixture file
data.jsonis created. - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture .atago-home/.fxrc.js:
function shout(x) {
return String(x).toUpperCase()
}
Fixture data.json:
{"word":"atago"}
When #
fx data.json .word shout
Then #
- exit code is
0 - stdout equals an exact value
- the step changed exactly created nothing, modified nothing, deleted nothing
fx (input formats, strictness, round trips) #
fx accepts more than JSON, and how it decides what it is holding is a
contract of its own: --yaml and --toml switch parsers explicitly, but a
file argument ending in .yaml, .yml or .toml switches them implicitly, and
the two flags are mutually exclusive with each other and with --raw.
Strictness is the other half. By default fx reads JSON the way a human
writes it — comments and trailing commas included — and --strict turns
exactly those tolerances back into errors. The round-trip scenarios use fx
twice in a pipeline so the assertion is about a relationship (encode then
decode returns the original bytes) rather than about one recorded output.
Source: test/e2e/thirdparty/fx/formats.atago.yaml
Scenario: –yaml parses YAML into the JSON model #
only when fx --version succeeds
Given #
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
stdin for fx:
service:
name: api
port: 8080
When #
fx --yaml .service.port
Then #
- exit code is
0 - stdout equals an exact value
Scenario: –toml parses TOML into the JSON model #
only when fx --version succeeds
Given #
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
stdin for fx:
[package]
name = "atago"
version = "1.2.3"
When #
fx --toml .package.name
Then #
- exit code is
0 - stdout equals an exact value
Scenario: a .yaml file argument switches parsers with no flag at all #
only when fx --version succeeds
Given #
- Fixture file
config.yamlis created. - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture config.yaml:
service:
name: api
replicas: 3
When #
fx config.yaml .service.replicas
Then #
- exit code is
0 - stdout equals an exact value
Scenario: a .toml file argument does the same #
only when fx --version succeeds
Given #
- Fixture file
config.tomlis created. - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture config.toml:
[package]
name = "atago"
When #
fx config.toml .package.name
Then #
- exit code is
0 - stdout equals an exact value
Scenario: extension detection ignores case #
only when fx --version succeeds
Given #
- Fixture file
CONFIG.YAMLis created. - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture CONFIG.YAML:
service:
name: api
When #
fx CONFIG.YAML .service.name
Then #
- exit code is
0 - stdout equals an exact value
Scenario: an unknown extension stays on the JSON parser #
only when fx --version succeeds
Given #
- Fixture file
payload.txtis created. - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture payload.txt:
{"a":1}
When #
fx payload.txt .a
Then #
- exit code is
0 - stdout equals an exact value
Scenario: –raw treats each input line as a string #
only when fx --version succeeds
Given #
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
stdin for fx:
hello
hi
When #
fx -r len
Then #
- exit code is
0 - stdout line
1equals an exact value - stdout line
2equals an exact value
Scenario: -s collects a stream of documents into one array #
only when fx --version succeeds
Given #
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
stdin for fx:
{"n":1}
{"n":2}
{"n":3}
When #
fx -s len
Then #
- exit code is
0 - stdout equals an exact value
Scenario: -rs combines raw lines into an array of strings #
only when fx --version succeeds
Given #
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
stdin for fx:
alpha
beta
When #
fx -rs .
Then #
- exit code is
0 - stdout equals an exact value
Expected output #
expected stdout:
[
"alpha",
"beta"
]
Scenario: the default parser accepts comments and a trailing comma #
only when fx --version succeeds
Given #
- Fixture file
loose.jsonis created. - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture loose.json:
{
// the service this config belongs to
"name": "api",
"port": 8080,
}
When #
fx loose.json .port
Then #
- exit code is
0 - stdout equals an exact value
Scenario: –strict rejects a comment #
only when fx --version succeeds
Given #
- Fixture file
loose.jsonis created. - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture loose.json:
{
// the service this config belongs to
"name": "api"
}
When #
fx --strict loose.json .name
Then #
- exit code is
1 - stdout is empty
- stderr contains
Comments are not allowed in strict mode
Scenario: –strict rejects a trailing comma #
only when fx --version succeeds
Given #
- Fixture file
trailing.jsonis created. - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture trailing.json:
{
"name": "api",
}
When #
fx --strict trailing.json .name
Then #
- exit code is
1 - stdout is empty
- stderr contains
Trailing comma is not allowed in strict mode
Scenario: –raw and –yaml together are refused #
only when fx --version succeeds
Given #
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
stdin for fx:
a: 1
When #
fx --yaml --raw .
Then #
- exit code is
1 - stdout is empty
- stderr contains
can't use --yaml/--toml and --raw flags together
Scenario: –yaml and –toml together are refused #
only when fx --version succeeds
Given #
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
stdin for fx:
a: 1
When #
fx --yaml --toml .
Then #
- exit code is
1 - stdout is empty
- stderr contains
can't use both --yaml and --toml flags together
Scenario: base64 encoding round-trips through a second fx #
only when fx --version succeeds · skipped on Windows
Given #
- Fixture file
secret.jsonis created. - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture secret.json:
{"token":"s3cr3t value"}
When #
fx secret.json .token toBase64 | fx -r fromBase64
Then #
- exit code is
0 - stdout equals an exact value
Scenario: a document survives a JSON to YAML to JSON round trip byte for byte #
only when fx --version succeeds
Given #
- Fixture file
source.jsonis created. - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected). - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected). - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture source.json:
{"name":"atago","nums":[1,2,3],"nested":{"leaf":true}}
When #
fx source.json .
fx source.json YAML.stringify
fx round_trip.yaml .
Then #
- after
fx source.json .:- exit code is
0
- exit code is
- after
fx source.json YAML.stringify:- exit code is
0
- exit code is
- after
fx round_trip.yaml .:- exit code is
0 - file
after.txtis byte-identical tobefore.txt
- exit code is
Generated artifacts #
before.txtround_trip.yamlafter.txt
Scenario: –no-inline expands the containers the default output packs onto one line #
only when fx --version succeeds
Given #
- Fixture file
doc.jsonis created. - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected). - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture doc.json:
{"nums":[1,2],"nested":{"leaf":1}}
When #
fx doc.json .
fx --no-inline doc.json .
Then #
- after
fx doc.json .:- exit code is
0 - stdout contains
"nums": [ 1, 2 ]
- exit code is
- after
fx --no-inline doc.json .:- exit code is
0 - stdout equals an exact value
- exit code is
Expected output #
expected stdout:
{
"nums": [
1,
2
],
"nested": {
"leaf": 1
}
}
Scenario: malformed YAML fails with a diagnostic that points at the line #
only when fx --version succeeds
Given #
- Fixture file
broken.yamlis created. - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture broken.yaml:
service:
name: api
port: 8080
When #
fx broken.yaml .
Then #
- exit code is
1 - stdout contains
mapping value is not allowed - stderr is empty
Scenario: malformed TOML fails without writing to stdout #
only when fx --version succeeds
Given #
- Fixture file
broken.tomlis created. - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture broken.toml:
a =
When #
fx broken.toml .
Then #
- exit code is not
0 - stdout is empty
fx (third-party CLI, JSON reducer contract) #
fx is two programs wearing one name. Hand it a reducer and it behaves like a filter — JSON in, a value out, an exit code for the shell. Hand it nothing and it opens a full-screen viewer instead. This file pins the filter half; the viewer lives in tui.atago.yaml and the parser flags in formats.atago.yaml.
The filter contract is worth pinning precisely because it is not the one a
jq user expects. A reducer is JavaScript, not a query language, so an
absent key is undefined rather than an error: fx reports it on stderr and
still exits 0, while dereferencing THROUGH that undefined is a hard exit 1.
Strings print unquoted, exit() lets the reducer choose the process’s exit
code, and the identity path hands back the original number literals instead
of what a float64 round trip would leave.
Source: test/e2e/thirdparty/fx/fx.atago.yaml
Scenario: version prints a semantic version #
only when fx --version succeeds
Given #
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
When #
fx --version
Then #
- exit code is
0 - stdout matches
/^[0-9]+\.[0-9]+\.[0-9]+/ - stderr is empty
Scenario: the identity reducer pretty-prints the document and keeps key order #
only when fx --version succeeds
Given #
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
stdin for fx:
{"b":2,"a":1}
When #
fx .
Then #
- exit code is
0 - stdout equals an exact value
- stderr is empty
Expected output #
expected stdout:
{
"b": 2,
"a": 1
}
Scenario: a dotted path selects a nested value and prints strings unquoted #
only when fx --version succeeds
Given #
- Fixture file
user.jsonis created. - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture user.json:
{"profile":{"name":"alice","admin":true}}
When #
fx user.json .profile.name
Then #
- exit code is
0 - stdout equals an exact value
Scenario: reducers compose left to right #
only when fx --version succeeds
Given #
- Fixture file
items.jsonis created. - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture items.json:
{"items":["a","b","c"]}
When #
fx items.json .items len
Then #
- exit code is
0 - stdout equals an exact value
Scenario: an arrow function transforms the document #
only when fx --version succeeds
Given #
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
stdin for fx:
{"nums":[1,2,3]}
When #
fx '.nums.map(n => n * 2)'
Then #
- exit code is
0 - stdout equals an exact value
Expected output #
expected stdout:
[
2,
4,
6
]
Scenario: a missing key reports undefined on stderr and still exits 0 #
only when fx --version succeeds
Given #
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
stdin for fx:
{"a":1}
When #
fx .nope
Then #
- exit code is
0 - stdout is empty
- stderr equals an exact value
Scenario: dereferencing through a missing key is a hard error #
only when fx --version succeeds
Given #
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
stdin for fx:
{"a":1}
When #
fx .a.b.c
Then #
- exit code is
1 - stdout is empty
- stderr contains
TypeError
Scenario: exit() hands the reducer’s own code to the shell #
only when fx --version succeeds
Given #
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected). - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
stdin for fx:
{}
stdin for fx:
{}
When #
fx 'exit(3)'
fx 'exit(0)'
Then #
- after
fx 'exit(3)':- exit code is
3
- exit code is
- after
fx 'exit(0)':- exit code is
0
- exit code is
Scenario: invalid JSON fails loudly and keeps stdout clean #
only when fx --version succeeds
Given #
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
stdin for fx:
{"bad"
When #
fx .
Then #
- exit code is
1 - stdout is empty
- stderr contains
Expected colon after object key
Scenario: a missing input file fails before anything is printed #
only when fx --version succeeds
Given #
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
When #
fx no-such.json .
Then #
- exit code is
1 - stdout is empty
- stderr contains
no-such.json
Scenario: empty input succeeds with no output at all #
only when fx --version succeeds
Given #
- Fixture file
empty.jsonis created. - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
stdin for fx:
(read from file empty.json)
When #
fx .
Then #
- exit code is
0 - stdout is empty
- stderr is empty
Scenario: each document in a stream produces its own result #
only when fx --version succeeds
Given #
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
stdin for fx:
{"n":1}
{"n":2}
When #
fx .n
Then #
- exit code is
0 - stdout line
1equals an exact value - stdout line
2equals an exact value
Scenario: filter drops documents from a stream instead of emitting them #
only when fx --version succeeds
Given #
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
stdin for fx:
{"n":1}
{"n":2}
{"n":3}
When #
fx 'filter(x => x.n > 2)'
Then #
- exit code is
0 - stdout equals an exact value
Expected output #
expected stdout:
{
"n": 3
}
Scenario: the identity path keeps number literals JavaScript would rewrite #
only when fx --version succeeds
Given #
- Fixture file
numbers.jsonis created. - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected). - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture numbers.json:
{"exact":1.0,"big":10000000000000000001}
When #
fx numbers.json .
fx numbers.json 'x => x'
Then #
- after
fx numbers.json .:- exit code is
0 - stdout contains
"exact": 1.0,"big": 10000000000000000001
- exit code is
- after
fx numbers.json 'x => x':- exit code is
0 - stdout contains
"exact": 1,"big": 10000000000000000001 - stdout does not contain
"exact": 1.0
- exit code is
Scenario: piped output carries no terminal escapes #
only when fx --version succeeds
Given #
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
stdin for fx:
{"a":"text","b":42,"c":null}
When #
fx .
Then #
- exit code is
0 - stdout does not match
/\x1b\[/
Scenario: a directory given as input fails without writing to stdout #
only when fx --version succeeds · skipped on Windows
Given #
- Fixture file
subdir/keep.txtis created. - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture subdir/keep.txt:
placeholder
When #
fx subdir .
Then #
- exit code is not
0 - stdout is empty
fx (interactive viewer, pty testbed) #
Given a file and no reducer, fx stops being a filter and becomes a full-screen JSON viewer: a foldable tree, a regexp search, and a cursor whose position is reported as a JSON path in the status bar.
What makes it an unusual TUI to test is where it draws. fx paints the whole
interface on stderr and keeps stdout for the one value the user asks it to
print, so fx data.json > picked.txt is a real workflow: the UI still
appears on the terminal and the file receives only the selected node. The
scenarios below drive the viewer inside a pseudo-terminal and assert both
sides of that split — the rendered screen, and what the pipeline behind it
received.
The waits are expect_screen, not expect: fx negotiates with the
terminal before its first paint, so the interesting condition is a rendered
frame rather than a byte on the wire.
Source: test/e2e/thirdparty/fx/tui.atago.yaml
Scenario: the viewer renders the document and quits cleanly on q #
only when fx --version succeeds · skipped on Windows
Given #
- Fixture file
viewer.jsonis created. - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture viewer.json:
{"name":"atago","tags":["cli","e2e"],"nested":{"deep":{"leaf":42}}}
When #
# interactive (pty): fx viewer.json
Then #
- exit code is
0
Scenario: esc leaves the viewer with a success code #
only when fx --version succeeds · skipped on Windows
Given #
- Fixture file
viewer.jsonis created. - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture viewer.json:
{"name":"atago"}
When #
# interactive (pty): fx viewer.json
Then #
- exit code is
0
Scenario: the interface goes to stderr, so a redirected stdout stays empty #
only when fx --version succeeds · skipped on Windows
Given #
- Fixture file
viewer.jsonis created. - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture viewer.json:
{"name":"atago","tags":["cli","e2e"]}
When #
# interactive (pty): fx viewer.json > picked.txt
Then #
- exit code is
0 - file
picked.txtequals exact bytes
Scenario: P prints the value under the cursor to stdout #
only when fx --version succeeds · skipped on Windows
Given #
- Fixture file
viewer.jsonis created. - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture viewer.json:
{"name":"atago","tags":["cli","e2e"]}
When #
# interactive (pty): fx viewer.json > picked.txt
Then #
- exit code is
0 - file
picked.txtequals exact bytes
Scenario: collapse-all folds the containers and expand-all brings them back #
only when fx --version succeeds · skipped on Windows
Given #
- Fixture file
viewer.jsonis created. - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture viewer.json:
{"name":"atago","tags":["cli","e2e"],"nested":{"deep":{"leaf":42}}}
When #
# interactive (pty): fx viewer.json
Then #
- exit code is
0
Scenario: search moves the cursor to the match and the status bar shows its path #
only when fx --version succeeds · skipped on Windows
Given #
- Fixture file
viewer.jsonis created. - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture viewer.json:
{"name":"atago","tags":["cli","e2e"],"nested":{"deep":{"leaf":42}}}
When #
# interactive (pty): fx viewer.json
Then #
- exit code is
0
Scenario: the rendered frame shows the tree and the status bar together #
only when fx --version succeeds · skipped on Windows
Given #
- Fixture file
viewer.jsonis created. - The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture viewer.json:
{"name":"atago","tags":["cli","e2e"],"nested":{"deep":{"leaf":42}}}
When #
# interactive (pty): fx viewer.json
Then #
- rendered screen line
1contains{ - rendered screen contains
"leaf": 42 - rendered screen contains
viewer.json
Scenario: with a terminal and no file, fx prints its usage instead of opening the viewer #
only when fx --version succeeds · skipped on Windows
Given #
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
When #
# interactive (pty): fx
Then #
- exit code is
0 - stdout contains
https://fx.wtf