1
1
mirror of https://github.com/wader/fq.git synced 2024-12-23 05:13:30 +03:00

dev,test: Use jqtest code from jqjq for jq tests

This commit is contained in:
Mattias Wadman 2022-12-05 20:42:26 +01:00
parent 92eadf9876
commit 423bab9e33
10 changed files with 234 additions and 154 deletions

View File

@ -20,8 +20,10 @@ testgo: always
testgo-race: RACE=-race
testgo-race: testgo
testjq: fq
@pkg/interp/testjq.sh ./fq pkg/interp/*_test.jq
testjq: $(shell find . -name "*.jq.test")
%.jq.test: fq
@echo $@
@./fq -rRs -L pkg/interp 'include "jqtest"; run_tests' $@
testcli: fq
@pkg/cli/test_exp.sh ./fq pkg/cli/test_repl.exp

4
pkg/interp/args.jq.test Normal file
View File

@ -0,0 +1,4 @@
# basic usage
_args_parse(.args; .opts)
{"args": ["-a", "123", "b"], "opts": {"a": {"short": "-a", "long": "--abc", "description": "Set abc", "string": true}}}
{"parsed": {"a": "123"}, "rest": ["b"]}

View File

@ -1,21 +0,0 @@
include "assert";
include "args";
[ { name: "Basic parse",
args: ["-a", "123", "b"],
opts: {
"a": {
short: "-a",
long: "--abc",
description: "Set abc",
string: true
}
},
expected: {
"parsed": {
"a": "123"
},
"rest": ["b"]
}
}
][] | assert(.name; _args_parse(.args; .opts); .expected)

View File

@ -1,13 +0,0 @@
include "internal";
def log: if env.VERBOSE then printerrln else empty end;
def assert($name; $expected; $actual):
( if $expected == $actual then
"PASS \($name)" | log
else
( "FAIL \($name): expected \($expected) got \($actual)" | printerrln
, (null | halt_error(1))
)
end
);

73
pkg/interp/funcs.jq.test Normal file
View File

@ -0,0 +1,73 @@
map(expr_to_path | path_to_expr)
[".", ".a", ".a[0]", ".a[123].bb", ".[123].a", ".[123][123].a", ".\"b b\"", ".\"a \\\\ b\"", ".\"a \\\" b\""]
[".", ".a", ".a[0]", ".a[123].bb", ".[123].a", ".[123][123].a", ".\"b b\"", ".\"a \\\\ b\"", ".\"a \\\" b\""]
.[] | group
[[1], [1,2], [1,2,2], [1,2,2,3]]
[[1]]
[[1],[2]]
[[1],[2,2]]
[[1],[2,2],[3]]
.[] | count
[[1], [1,2], [1,2,2,2], [1,2,2,2,3]]
[[1,1]]
[[1,1],[2,1]]
[[1,1],[2,3]]
[[1,1],[2,3],[3,1]]
.[] | count_by(.%2)
[[1], [1,2], [1,2,2,2], [1,2,2,2,3]]
[[1,1]]
[[0,1],[1,1]]
[[0,3],[1,1]]
[[0,3],[1,2]]
.[] | streaks
[[], [1], [1,1], [1,1,2], [1,1,2,2], [1,2,2,1]]
[]
[[1]]
[[1,1]]
[[1,1],[2]]
[[1,1],[2,2]]
[[1],[2,2],[1]]
.[] | delta
[[], [1], [1,2], [1,2,2,2], [1,2,2,2,3]]
[]
[]
[1]
[1,0,0]
[1,0,0,1]
.[] | delta_by(.a+.b)
[[], [1], [1,2], [1,2,2,2], [1,2,2,2,3]]
[]
[]
[3]
[3,4,4]
[3,4,4,5]
streaks_by(.a)
[{"a":1},{"a":1},{"a":2}]
[[{"a":1},{"a":1}],[{"a":2}]]
.[] as [$input, $size] | $input | chunk($size)
[[[], 1], [[], 2], [[1], 1], [[1], 2], [[1,2], 1], [[1,2], 2], [[1,2,3,4], 2], [[1,2,3,4], 3], ["", 1], ["", 2], ["1", 1], ["1", 2], ["12", 1], ["12", 2], ["1234", 2], ["1234", 3]]
[]
[]
[[1]]
[[1]]
[[1],[2]]
[[1,2]]
[[1,2],[3,4]]
[[1,2,3],[4]]
[]
[]
["1"]
["1"]
["1","2"]
["12"]
["12","34"]
["123","4"]

View File

@ -1,83 +0,0 @@
include "assert";
include "funcs";
(
([
".",
".a",
".a[0]",
".a[123].bb",
".[123].a",
".[123][123].a",
".\"b b\"",
".\"a \\\\ b\"",
".\"a \\\" b\""
][] | assert("\(.) | expr_to_path | path_to_expr"; .; expr_to_path | path_to_expr))
,
(([[], []]
, [[1], [[1]]]
, [[1,2], [[1], [2]]]
, [[1,2,2], [[1], [2,2]]]
, [[1,2,2,3], [[1], [2,2], [3]]]
) | assert("\(.[0]) | group"; .[1]; .[0] | group))
,
(([[], []]
, [[1], [[1,1]]]
, [[1,2], [[1,1], [2,1]]]
, [[1,2,2,2], [[1,1], [2,3]]]
, [[1,2,2,2,3], [[1,1], [2,3], [3,1]]]
) | assert("\(.[0]) | count"; .[1]; .[0] | count))
,
(([[], []]
, [[1], [[1,1]]]
, [[1,2], [[0,1], [1,1]]]
, [[1,2,2,2], [[0,3],[1,1]]]
, [[1,2,2,2,3], [[0,3],[1,2]]]
) | assert("\(.[0]) | count_by(.%2)"; .[1]; .[0] | count_by(.%2)))
,
([
[[], []],
[[1], [[1]]],
[[1,1], [[1,1]]],
[[1,1,2], [[1,1],[2]]],
[[1,1,2,2], [[1,1],[2,2]]],
[[1,2,2,1], [[1],[2,2],[1]]]
][] | assert("\(.) | streaks"; .[1]; .[0] | streaks))
,
(([[], []]
, [[1], []]
, [[1,2], [1]]
, [[1,2,2,2], [1,0,0]]
, [[1,2,2,2,3], [1,0,0,1]]
) | assert("\(.[0]) | delta"; .[1]; .[0] | delta))
,
(([[], []]
, [[1], []]
, [[1,2], [3]]
, [[1,2,2,2], [3,4,4]]
, [[1,2,2,2,3], [3,4,4,5]]
) | assert("\(.[0]) | delta_by(.a+.b)"; .[1]; .[0] | delta_by(.a+.b)))
,
([
[[{a:1},{a:1},{a:2}], [[{a:1},{a:1}],[{a:2}]]]
][] | assert("\(.) | streaks_by"; .[1]; .[0] | streaks_by(.a)))
,
([
[[], 1, []],
[[], 2, []],
[[1], 1, [[1]]],
[[1], 2, [[1]]],
[[1,2], 1, [[1],[2]]],
[[1,2], 2, [[1,2]]],
[[1,2,3,4], 2, [[1,2],[3,4]]],
[[1,2,3,4], 3, [[1,2,3],[4]]],
["", 1, []],
["", 2, []],
["1", 1, ["1"]],
["1", 2, ["1"]],
["12", 1, ["1","2"]],
["12", 2, ["12"]],
["1234", 2, ["12","34"]],
["1234", 3, ["123","4"]]
][] | . as $t | assert("\($t[0]) | chunk(\($t[1]))"; $t[2]; $t[0] | chunk($t[1])))
)

140
pkg/interp/jqtest.jq Normal file
View File

@ -0,0 +1,140 @@
# read jq test format:
# # comment
# expr
# input
# output*
# <blank>+
# ...
# <next test>
def fromjqtest:
[ foreach (split("\n")[], "") as $l (
{ current_line: 0
, nr: 1
, emit: true
};
( .current_line += 1
| if .emit then
( .expr = null
| .input = null
| .output = []
| .fail = null
| .emit = null
| .error = null
)
else .
end
| if $l | test("^\\s*#") then .
elif $l | test("^\\s*$") then
if .expr then
( .emit =
{ line
, nr
, expr
, input
, output
, fail
, error
}
| .nr += 1
)
else .
end
elif $l | test("^\\s*%%FAIL") then
.fail = $l
else
if .expr == null then
( .line = .current_line
| .expr = $l
)
elif .fail and .error == null then .error = $l
elif .input == null then .input = $l
else .output += [$l]
end
end
);
if .emit then .emit
else empty
end
)
];
def run_tests:
def _f:
( fromjqtest[]
| . as $c
| try
if .error | not then
( ( .input
, .output[]
) |= fromjson
)
else .
end
catch
( . as $err
| $c
| .fromjson_error = $err
)
| select(.fromjson_error | not)
| "\(.nr) (line \(.line)): [\(.input | tojson) | \(.expr)] -> \(.output | tojson)" as $test_name
| . as $test
| try
( $test.input
| [ eval($test.expr)] as $actual_output
| if $test.output == $actual_output then
( empty # "OK: \($test_name)"
, {ok: true}
)
else
( "DIFF: \($test_name)"
, " Expected: \($test.output | tojson)"
, " Actual: \($actual_output | tojson)"
, {error: true}
)
end
)
catch
if $test.fail then
if . == $test.error then
( empty #"OK: \($test_name)"
, {ok: true}
)
else
( "FAIL DIFF: \($test_name)"
, " Expected: \($test.error)"
, " Actual: \(.)"
, {error: true}
)
end
else
( "ERROR: \($test_name)"
, " \(.)"
, {error: true}
)
end
);
# this mess make it possible to run all tests and exit with non-zero if any test failed
( foreach (_f, {end: true}) as $l (
{ errors: 0
, oks: 0
};
if ($l | type) == "object" then
( .line = false
| if $l.error then .errors +=1
elif $l.ok then .oks += 1
elif $l.end then .end = true
else .
end
)
else . + {line: $l}
end;
.
)
| if .end then
( "\(.oks) of \(.oks + .errors) tests passed"
, if .errors > 0 then null | halt_error(1) else empty end
)
elif .line then .line
else empty
end
);

13
pkg/interp/query.jq.test Normal file
View File

@ -0,0 +1,13 @@
.[] | _query_fromstring | _query_pipe_last | _query_tostring
["", ".", "a", "1, 2", "1 | 2", "1 | 2 | 3", "(1 | 2) | 3", "1 | (2 | 3)", "1 as $_ | 2", "def f: 1; 1", "def f: 1; 1 | 2"]
"."
"."
"a"
"1, 2"
"2"
"3"
"3"
"(2 | 3)"
"2"
"def f: 1; 1"
"2"

View File

@ -1,24 +0,0 @@
include "assert";
include "query";
(
([
["", "."],
[".", "."],
["a", "a"],
["1, 2", "1, 2"],
["1 | 2", "2"],
["1 | 2 | 3", "3"],
["(1 | 2) | 3", "3"],
["1 | (2 | 3)", "(2 | 3)"],
["1 as $_ | 2", "2"],
["def f: 1; 1", "def f: 1; 1"],
["def f: 1; 1 | 2", "2"],
empty
][] | assert(
"\(.) | _query_pipe_last";
.[1];
.[0] | _query_fromstring | _query_pipe_last | _query_tostring
)
)
)

View File

@ -1,11 +0,0 @@
#!/bin/sh
# help script to run jq tests
set -eu
FQ="$1"
shift
for f in "$@"; do
echo "testjq $f"
"$FQ" -nr -L "$(dirname "$f")" -f "$f"
done