-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Normalize and correct tests #2939
Comments
How is it wrong? should state that there are new lines between?
Not sure what is going on with these. Hack that uses no output to assert that it did fail? tests added in 0673dee
But
The format is a bit hackish but i would argue that it's designed to be convenient for writing jq tests and not much else. Also the same reason i think using JSON as test format would be annoying as you would have escape all string literals and whatnot.
BOM as in byte-order-marker? not sure i follow. You mean the
Can you give some examples lines? you mean the lines that uses jq syntax and not JSON? no quotes for keys etc?
You mean it should always be using compact output? currently i think output lines are parsed as JSON and then compared. Looking at the code it seems to be done by serializing back to JSON and then compare with serialized output. Could you give some background about why these things are a problem for you? are you implementing your own jq-test parser/runner? |
@wader ,
Let me show example:
This test results into: $ echo {(0):1} | jq "%%FAIL"
jq: error: syntax error, unexpected '%', expecting end of file (Windows cmd shell quoting issues?) at <top-level>, line 1:
%%FAIL
jq: 1 compile error
I can only guess that this is like $ echo [[3],[4],[5],6] | jq ".[] as {a:$a} ?// {a:$a} ?// {a:$a} | $a"
jq: error (at <stdin>:1): Cannot index array with string "a"
Sure, because two lines - not three lines stated in header.
What about normalizing this format? I mean use explicit errors assertion, explicit markers/modifiers/e.t.c.
It could be something like:
or any other marker/header/escape sequence.
Sure, but again this is not obvious especially in raw bytes view. It should be line modifier like
Unquoted keys are ok, but:
I thought too unless $ echo 42 | jq "{x: -1}"
{
"x": -1
}
$ echo 42 | jq "{x: -1}" --compact-output
{"x":-1} |
Sure. I use jq in my python applications and really tired of incompatible windows builds. What the heck jq runs on windows and python runs on windows but python bindings of jq do not support windows? So I just want to rollout my own python binding that just works. Indeed, I implemented tests and pulled form this repo test files. But unfortunately I can not understand this floating syntax by only inner vision. Wouldn't you be bothered helping a bit with this please? p.s. |
Aha I see,
Yes I think it might be a hacky way to assert that an error happens error. But I wonder why it's not done using try/catch intead?
Yes
Yes it can probably be improved a lot. Maybe @nicowilliams can give some history why it works the way it does?
This probably because jq support to preserve big integers. There has been talks about having some arguments to configure this like #2643
Huh yes something is a bit fishy with this: $ echo '[nan,nAn,NAN]' | jq -c
[null,null,null] |
I see. Is there some public URL for the project? So you want to use the tests in jq.test to test the bindings? Yeah i've kind of reverse-engineered the syntax also by looking at the code. Why it's a bit floating i guess is because it has only been designed to test jq itself.
Can promise anything but i can try. What do you need help with? there are probably others that can help also |
@baterflyrity if you use |
As for BOMs, we don't have any BOM in |
Also, regarding (8) I get the feeling that you don't understand what jq is. jq is a programming language, and jq programs are not JSON texts, though JSON texts are jq programs. Of course jq programs exist that are not parseable as JSON -- that's OK! But the output of jq should always be parseable JSON unless the I don't understand (9) at all. (1) through (6) should be addressed by using |
@nicowilliams Thanks, now I definitely understand how to run tests. But my question is about how to read and write these tests. Do you have any specification? As I can see tests are intended to be stdin + filter = stdout but actually are like black magical boxes. |
https://jqlang.github.io/jq/manual/v1.7/#invoking-jq
|
Unfortunately this description is simply wrong. Please checkout unstated syntaxes in discussion header. |
@wader Thanks. Yes, I would like to integrate jq tests into my python bindings as end-to-end. But I really do not understand how to check correctness when some cases are wrong in stdout, others - in json values. All in all It would be cool to see at least test file specification. |
Your original issue description is not useful to me to understand what you mean about the quoted manual text being wrong. |
I don't see why you would need this. You need tests, but you don't need to use all of jq's own tests. |
I saw them, and I don't understand how you mean that description is wrong.
The test runner is not comparing the outputs of the script with the lines that would be printed by |
You Python bindings should be tested using the bound API, and jq does NOT export an API for |
According to the description this test must fail because since comment lines are ignore result must be asserted as empty output.
This is just magical prefix.
So values like
Am i right there is no chance structured tests can appear soon in jq? It's a pity but really seems like writing my own tests will be more efficient than parsing random syntax. |
What's happening here is that this test declares that there is no output, and indeed, there isn't. The run-time error is being ignored. The What we should have done here is used
What of this? What's the problem with this? Yes, it's at the start of a line, so what? This is NOT a JSON file. This is NOT a file with any format that any other tool should support. This is a file used internally by jq. Bindings for Python or whatever language should NOT use this file. You can adapt tests from this file to test your bindings, sure, but with some care.
It's JSON. RFC 7259 JSON. We should make sure it's also RFC 8259 JSON. It is NOT JSON5. I don't believe we've ever claimed that jq supports JSON5 -- it does not. EDIT: I should point out that we don't actually test conformance to RFC 7259 / 8259, but that is what we aim to support at this time.
You can use |
What do you mean? Do you know what The input is $ jq -n '[[3]] | .[] as { $a } | $a'
jq: error (at <unknown>): Cannot index array with string "a"
$ jq -n '[[3]] | try .[] as { $a } | $a catch .'
"Cannot index array with string \"a\"" The comment has nothing to do with test, that script for the given input returns nothing, and that is correct because no outputs are listed. Without the comment it would work the same. The output part of a test case is optional, you may have something like this for example: numbers
"hello"
numbers
"hello"
[123] If you mean that you should have used $ jq -n '. as $a'
jq: error: syntax error, unexpected end of file, expecting '|' (Unix shell quoting issues?) at <top-level>, line 1:
. as $a
jq: 1 compile error
$ jq -n '. as $a | 12'
12 Or using a variable outside of the scope in which it is defined does not compile: $ jq -n '(tostring | length as $a | $a) + $a * 10, .'
jq: error: $a is not defined at <top-level>, line 1:
(tostring | length as $a | $a) + $a * 10, .
jq: 1 compile error
$ jq -n '(tostring | length) as $a | $a + $a * 10, .'
44
null You use %%FAIL
. as $a
jq: error: syntax error, unexpected end of file, expecting '|' (Unix shell quoting issues?) at <top-level>, line 1:
. as $a | 12
null
12
%%FAIL
(tostring | length as $a | $a) + $a * 10, .
jq: error: $a is not defined at <top-level>, line 1:
(tostring | length) as $a | $a + $a * 10, .
null
44
null If you want to write a test for a runtime error, you write
$ jq . <<< $'\ufeff''1'
1
$ jq . <<< $'\ufeff\ufeff''1'
jq: parse error: Invalid numeric literal at line 2, column 0 The input line of a test case is treated as the content of an input file (though only one input value will be accepted from that input; basically the same as calling
What is a magic prefix? It is just:
That is exactly what that test is trying to test, and there is nothing special about that test. If you don't understand that because you think Note that $ jq -n $'\ufeff''1'
jq: error: syntax error, unexpected INVALID_CHARACTER, expecting end of file (Unix shell quoting issues?) at <top-level>, line 1:
1
jq: 1 compile error
$ jq -nf /dev/stdin <<< $'\ufeff''1'
jq: error: syntax error, unexpected INVALID_CHARACTER, expecting end of file (Unix shell quoting issues?) at <top-level>, line 1:
1
jq: 1 compile error
That is a weird question. $ jq -sR 'gsub("^\\s+$|[[:blank:]]*#.*"; "") | scan("(?s)(.*?)(?:\n{2,}|\n*$)")[] / "\n" | if first | IN ("%%FAIL"|.,.+" IGNORE MSG") then { script: .[1], input: null, outputs: null, error: (if first != "%%FAIL" then null else .[2] end) } else select(. != []) | { script: .[0], input: .[1], outputs: [ .[2:][] | fromjson ], error: null } end' tests/jq.test
{
"script": "true",
"input": "null",
"outputs": [
true
],
"error": null
}
{
"script": "false",
"input": "null",
"outputs": [
false
],
"error": null
}
{
"script": "null",
"input": "42",
"outputs": [
null
],
"error": null
}
{
"script": "1",
"input": "null",
"outputs": [
1
],
[...] full output
{
"script": "true",
"input": "null",
"outputs": [
true
],
"error": null
}
{
"script": "false",
"input": "null",
"outputs": [
false
],
"error": null
}
{
"script": "null",
"input": "42",
"outputs": [
null
],
"error": null
}
{
"script": "1",
"input": "null",
"outputs": [
1
],
"error": null
}
{
"script": "-1",
"input": "null",
"outputs": [
-1
],
"error": null
}
{
"script": "{}",
"input": "null",
"outputs": [
{}
],
"error": null
}
{
"script": "[]",
"input": "null",
"outputs": [
[]
],
"error": null
}
{
"script": "{x: -1}",
"input": "null",
"outputs": [
{
"x": -1
}
],
"error": null
}
{
"script": ".",
"input": "\"byte order mark\"",
"outputs": [
"byte order mark"
],
"error": null
}
{
"script": "\"Aa\\r\\n\\t\\b\\f\\u03bc\"",
"input": "null",
"outputs": [
"Aa\r\n\t\b\fμ"
],
"error": null
}
{
"script": ".",
"input": "\"Aa\\r\\n\\t\\b\\f\\u03bc\"",
"outputs": [
"Aa\r\n\t\b\fμ"
],
"error": null
}
{
"script": "\"inter\\(\"pol\" + \"ation\")\"",
"input": "null",
"outputs": [
"interpolation"
],
"error": null
}
{
"script": "@text,@json,([1,.]|@csv,@tsv),@html,@uri,@sh,(@base64|.,@base64d)",
"input": "\"!()<>&'\\\"\\t\"",
"outputs": [
"!()<>&'\"\t",
"\"!()<>&'\\\"\\t\"",
"1,\"!()<>&'\"\"\t\"",
"1\t!()<>&'\"\\t",
"!()<>&'"\t",
"%21%28%29%3C%3E%26%27%22%09",
"'!()<>&'\\''\"\t'",
"ISgpPD4mJyIJ",
"!()<>&'\"\t"
],
"error": null
}
{
"script": "@base64",
"input": "\"foóbar\\n\"",
"outputs": [
"Zm/Ds2Jhcgo="
],
"error": null
}
{
"script": "@base64d",
"input": "\"Zm/Ds2Jhcgo=\"",
"outputs": [
"foóbar\n"
],
"error": null
}
{
"script": "@uri",
"input": "\"\\u03bc\"",
"outputs": [
"%CE%BC"
],
"error": null
}
{
"script": "@html \"<b>\\(.)</b>\"",
"input": "\"<script>hax</script>\"",
"outputs": [
"<b><script>hax</script></b>"
],
"error": null
}
{
"script": "[.[]|tojson|fromjson]",
"input": "[\"foo\", 1, [\"a\", 1, \"b\", 2, {\"foo\":\"bar\"}]]",
"outputs": [
[
"foo",
1,
[
"a",
1,
"b",
2,
{
"foo": "bar"
}
]
]
],
"error": null
}
{
"script": "{a: 1}",
"input": "null",
"outputs": [
{
"a": 1
}
],
"error": null
}
{
"script": "{a,b,(.d):.a,e:.b}",
"input": "{\"a\":1, \"b\":2, \"c\":3, \"d\":\"c\"}",
"outputs": [
{
"a": 1,
"b": 2,
"c": 1,
"e": 2
}
],
"error": null
}
{
"script": "{\"a\",b,\"a$\\(1+1)\"}",
"input": "{\"a\":1, \"b\":2, \"c\":3, \"a$2\":4}",
"outputs": [
{
"a": 1,
"b": 2,
"a$2": 4
}
],
"error": null
}
{
"script": "{(0):1}",
"input": null,
"outputs": null,
"error": "jq: error: Cannot use number (0) as object key at <top-level>, line 1:"
}
{
"script": "{non_const:., (0):1}",
"input": null,
"outputs": null,
"error": "jq: error: Cannot use number (0) as object key at <top-level>, line 1:"
}
{
"script": ".foo",
"input": "{\"foo\": 42, \"bar\": 43}",
"outputs": [
42
],
"error": null
}
{
"script": ".foo | .bar",
"input": "{\"foo\": {\"bar\": 42}, \"bar\": \"badvalue\"}",
"outputs": [
42
],
"error": null
}
{
"script": ".foo.bar",
"input": "{\"foo\": {\"bar\": 42}, \"bar\": \"badvalue\"}",
"outputs": [
42
],
"error": null
}
{
"script": ".foo_bar",
"input": "{\"foo_bar\": 2}",
"outputs": [
2
],
"error": null
}
{
"script": ".[\"foo\"].bar",
"input": "{\"foo\": {\"bar\": 42}, \"bar\": \"badvalue\"}",
"outputs": [
42
],
"error": null
}
{
"script": ".\"foo\".\"bar\"",
"input": "{\"foo\": {\"bar\": 20}}",
"outputs": [
20
],
"error": null
}
{
"script": ".e0, .E1, .E-1, .E+1",
"input": "{\"e0\": 1, \"E1\": 2, \"E\": 3}",
"outputs": [
1,
2,
2,
4
],
"error": null
}
{
"script": "[.[]|.foo?]",
"input": "[1,[2],{\"foo\":3,\"bar\":4},{},{\"foo\":5}]",
"outputs": [
[
3,
null,
5
]
],
"error": null
}
{
"script": "[.[]|.foo?.bar?]",
"input": "[1,[2],[],{\"foo\":3},{\"foo\":{\"bar\":4}},{}]",
"outputs": [
[
4,
null
]
],
"error": null
}
{
"script": "[..]",
"input": "[1,[[2]],{ \"a\":[1]}]",
"outputs": [
[
[
1,
[
[
2
]
],
{
"a": [
1
]
}
],
1,
[
[
2
]
],
[
2
],
2,
{
"a": [
1
]
},
[
1
],
1
]
],
"error": null
}
{
"script": "[.[]|.[]?]",
"input": "[1,null,[],[1,[2,[[3]]]],[{}],[{\"a\":[1,[2]]}]]",
"outputs": [
[
1,
[
2,
[
[
3
]
]
],
{},
{
"a": [
1,
[
2
]
]
}
]
],
"error": null
}
{
"script": "[.[]|.[1:3]?]",
"input": "[1,null,true,false,\"abcdef\",{},{\"a\":1,\"b\":2},[],[1,2,3,4,5],[1,2]]",
"outputs": [
[
null,
"bc",
[],
[
2,
3
],
[
2
]
]
],
"error": null
}
{
"script": "map(try .a[] catch ., try .a.[] catch ., .a[]?, .a.[]?)",
"input": "[{\"a\": [1,2]}, {\"a\": 123}]",
"outputs": [
[
1,
2,
1,
2,
1,
2,
1,
2,
"Cannot iterate over number (123)",
"Cannot iterate over number (123)"
]
],
"error": null
}
{
"script": "try (.foo[-1] = 0) catch .",
"input": "null",
"outputs": [
"Out of bounds negative array index"
],
"error": null
}
{
"script": "try (.foo[-2] = 0) catch .",
"input": "null",
"outputs": [
"Out of bounds negative array index"
],
"error": null
}
{
"script": ".[-1] = 5",
"input": "[0,1,2]",
"outputs": [
[
0,
1,
5
]
],
"error": null
}
{
"script": ".[-2] = 5",
"input": "[0,1,2]",
"outputs": [
[
0,
5,
2
]
],
"error": null
}
{
"script": ".[]",
"input": "[1,2,3]",
"outputs": [
1,
2,
3
],
"error": null
}
{
"script": "1,1",
"input": "[]",
"outputs": [
1,
1
],
"error": null
}
{
"script": "1,.",
"input": "[]",
"outputs": [
1,
[]
],
"error": null
}
{
"script": "[.]",
"input": "[2]",
"outputs": [
[
[
2
]
]
],
"error": null
}
{
"script": "[[2]]",
"input": "[3]",
"outputs": [
[
[
2
]
]
],
"error": null
}
{
"script": "[{}]",
"input": "[2]",
"outputs": [
[
{}
]
],
"error": null
}
{
"script": "[.[]]",
"input": "[\"a\"]",
"outputs": [
[
"a"
]
],
"error": null
}
{
"script": "[(.,1),((.,.[]),(2,3))]",
"input": "[\"a\",\"b\"]",
"outputs": [
[
[
"a",
"b"
],
1,
[
"a",
"b"
],
"a",
"b",
2,
3
]
],
"error": null
}
{
"script": "[([5,5][]),.,.[]]",
"input": "[1,2,3]",
"outputs": [
[
5,
5,
[
1,
2,
3
],
1,
2,
3
]
],
"error": null
}
{
"script": "{x: (1,2)},{x:3} | .x",
"input": "null",
"outputs": [
1,
2,
3
],
"error": null
}
{
"script": "[.[-4,-3,-2,-1,0,1,2,3]]",
"input": "[1,2,3]",
"outputs": [
[
null,
1,
2,
3,
1,
2,
3,
null
]
],
"error": null
}
{
"script": "[range(0;10)]",
"input": "null",
"outputs": [
[
0,
1,
2,
3,
4,
5,
6,
7,
8,
9
]
],
"error": null
}
{
"script": "[range(0,1;3,4)]",
"input": "null",
"outputs": [
[
0,
1,
2,
0,
1,
2,
3,
1,
2,
1,
2,
3
]
],
"error": null
}
{
"script": "[range(0;10;3)]",
"input": "null",
"outputs": [
[
0,
3,
6,
9
]
],
"error": null
}
{
"script": "[range(0;10;-1)]",
"input": "null",
"outputs": [
[]
],
"error": null
}
{
"script": "[range(0;-5;-1)]",
"input": "null",
"outputs": [
[
0,
-1,
-2,
-3,
-4
]
],
"error": null
}
{
"script": "[range(0,1;4,5;1,2)]",
"input": "null",
"outputs": [
[
0,
1,
2,
3,
0,
2,
0,
1,
2,
3,
4,
0,
2,
4,
1,
2,
3,
1,
3,
1,
2,
3,
4,
1,
3
]
],
"error": null
}
{
"script": "[while(.<100; .*2)]",
"input": "1",
"outputs": [
[
1,
2,
4,
8,
16,
32,
64
]
],
"error": null
}
{
"script": "[(label $here | .[] | if .>1 then break $here else . end), \"hi!\"]",
"input": "[0,1,2]",
"outputs": [
[
0,
1,
"hi!"
]
],
"error": null
}
{
"script": "[(label $here | .[] | if .>1 then break $here else . end), \"hi!\"]",
"input": "[0,2,1]",
"outputs": [
[
0,
"hi!"
]
],
"error": null
}
{
"script": ". as $foo | break $foo",
"input": null,
"outputs": null,
"error": "jq: error: $*label-foo is not defined at <top-level>, line 1:"
}
{
"script": "[.[]|[.,1]|until(.[0] < 1; [.[0] - 1, .[1] * .[0]])|.[1]]",
"input": "[1,2,3,4,5]",
"outputs": [
[
1,
2,
6,
24,
120
]
],
"error": null
}
{
"script": "[label $out | foreach .[] as $item ([3, null]; if .[0] < 1 then break $out else [.[0] -1, $item] end; .[1])]",
"input": "[11,22,33,44,55,66,77,88,99]",
"outputs": [
[
11,
22,
33
]
],
"error": null
}
{
"script": "[foreach range(5) as $item (0; $item)]",
"input": "null",
"outputs": [
[
0,
1,
2,
3,
4
]
],
"error": null
}
{
"script": "[foreach .[] as [$i, $j] (0; . + $i - $j)]",
"input": "[[2,1], [5,3], [6,4]]",
"outputs": [
[
1,
3,
5
]
],
"error": null
}
{
"script": "[foreach .[] as {a:$a} (0; . + $a; -.)]",
"input": "[{\"a\":1}, {\"b\":2}, {\"a\":3, \"b\":4}]",
"outputs": [
[
-1,
-1,
-4
]
],
"error": null
}
{
"script": "[limit(3; .[])]",
"input": "[11,22,33,44,55,66,77,88,99]",
"outputs": [
[
11,
22,
33
]
],
"error": null
}
{
"script": "[limit(0; error)]",
"input": "\"badness\"",
"outputs": [
[]
],
"error": null
}
{
"script": "[limit(1; 1, error)]",
"input": "\"badness\"",
"outputs": [
[
1
]
],
"error": null
}
{
"script": "[first(range(.)), last(range(.))]",
"input": "10",
"outputs": [
[
0,
9
]
],
"error": null
}
{
"script": "[nth(0,5,9,10,15; range(.)), try nth(-1; range(.)) catch .]",
"input": "10",
"outputs": [
[
0,
5,
9,
"nth doesn't support negative indices"
]
],
"error": null
}
{
"script": "first(1,error(\"foo\"))",
"input": "null",
"outputs": [
1
],
"error": null
}
{
"script": "[limit(5,7; range(9))]",
"input": "null",
"outputs": [
[
0,
1,
2,
3,
4,
0,
1,
2,
3,
4,
5,
6
]
],
"error": null
}
{
"script": "[nth(5,7; range(9;0;-1))]",
"input": "null",
"outputs": [
[
4,
2
]
],
"error": null
}
{
"script": "[range(0,1,2;4,3,2;2,3)]",
"input": "null",
"outputs": [
[
0,
2,
0,
3,
0,
2,
0,
0,
0,
1,
3,
1,
1,
1,
1,
1,
2,
2,
2,
2
]
],
"error": null
}
{
"script": "[range(3,5)]",
"input": "null",
"outputs": [
[
0,
1,
2,
0,
1,
2,
3,
4
]
],
"error": null
}
{
"script": "[(index(\",\",\"|\"), rindex(\",\",\"|\")), indices(\",\",\"|\")]",
"input": "\"a,b|c,d,e||f,g,h,|,|,i,j\"",
"outputs": [
[
1,
3,
22,
19,
[
1,
5,
7,
12,
14,
16,
18,
20,
22
],
[
3,
9,
10,
17,
19
]
]
],
"error": null
}
{
"script": "join(\",\",\"/\")",
"input": "[\"a\",\"b\",\"c\",\"d\"]",
"outputs": [
"a,b,c,d",
"a/b/c/d"
],
"error": null
}
{
"script": "[.[]|join(\"a\")]",
"input": "[[],[\"\"],[\"\",\"\"],[\"\",\"\",\"\"]]",
"outputs": [
[
"",
"",
"a",
"aa"
]
],
"error": null
}
{
"script": "flatten(3,2,1)",
"input": "[0, [1], [[2]], [[[3]]]]",
"outputs": [
[
0,
1,
2,
3
],
[
0,
1,
2,
[
3
]
],
[
0,
1,
[
2
],
[
[
3
]
]
]
],
"error": null
}
{
"script": "[.[3:2], .[-5:4], .[:-2], .[-2:], .[3:3][1:], .[10:]]",
"input": "[0,1,2,3,4,5,6]",
"outputs": [
[
[],
[
2,
3
],
[
0,
1,
2,
3,
4
],
[
5,
6
],
[],
[]
]
],
"error": null
}
{
"script": "[.[3:2], .[-5:4], .[:-2], .[-2:], .[3:3][1:], .[10:]]",
"input": "\"abcdefghi\"",
"outputs": [
[
"",
"",
"abcdefg",
"hi",
"",
""
]
],
"error": null
}
{
"script": "del(.[2:4],.[0],.[-2:])",
"input": "[0,1,2,3,4,5,6,7]",
"outputs": [
[
1,
4,
5
]
],
"error": null
}
{
"script": ".[2:4] = ([], [\"a\",\"b\"], [\"a\",\"b\",\"c\"])",
"input": "[0,1,2,3,4,5,6,7]",
"outputs": [
[
0,
1,
4,
5,
6,
7
],
[
0,
1,
"a",
"b",
4,
5,
6,
7
],
[
0,
1,
"a",
"b",
"c",
4,
5,
6,
7
]
],
"error": null
}
{
"script": "reduce range(65540;65536;-1) as $i ([]; .[$i] = $i)|.[65536:]",
"input": "null",
"outputs": [
[
null,
65537,
65538,
65539,
65540
]
],
"error": null
}
{
"script": "1 as $x | 2 as $y | [$x,$y,$x]",
"input": "null",
"outputs": [
[
1,
2,
1
]
],
"error": null
}
{
"script": "[1,2,3][] as $x | [[4,5,6,7][$x]]",
"input": "null",
"outputs": [
[
5
],
[
6
],
[
7
]
],
"error": null
}
{
"script": "42 as $x | . | . | . + 432 | $x + 1",
"input": "34324",
"outputs": [
43
],
"error": null
}
{
"script": "1 as $x | [$x,$x,$x as $x | $x]",
"input": "null",
"outputs": [
[
1,
1,
1
]
],
"error": null
}
{
"script": "[1, {c:3, d:4}] as [$a, {c:$b, b:$c}] | $a, $b, $c",
"input": "null",
"outputs": [
1,
3,
null
],
"error": null
}
{
"script": ". as {as: $kw, \"str\": $str, (\"e\"+\"x\"+\"p\"): $exp} | [$kw, $str, $exp]",
"input": "{\"as\": 1, \"str\": 2, \"exp\": 3}",
"outputs": [
[
1,
2,
3
]
],
"error": null
}
{
"script": ".[] as [$a, $b] | [$b, $a]",
"input": "[[1], [1, 2, 3]]",
"outputs": [
[
null,
1
],
[
2,
1
]
],
"error": null
}
{
"script": ". as $i | . as [$i] | $i",
"input": "[0]",
"outputs": [
0
],
"error": null
}
{
"script": ". as [$i] | . as $i | $i",
"input": "[0]",
"outputs": [
[
0
]
],
"error": null
}
{
"script": ". as [] | null",
"input": null,
"outputs": null,
"error": null
}
{
"script": ". as {} | null",
"input": null,
"outputs": null,
"error": null
}
{
"script": "1+1",
"input": "null",
"outputs": [
2
],
"error": null
}
{
"script": "1+1",
"input": "\"wtasdf\"",
"outputs": [
2.0
],
"error": null
}
{
"script": "2-1",
"input": "null",
"outputs": [
1
],
"error": null
}
{
"script": "2-(-1)",
"input": "null",
"outputs": [
3
],
"error": null
}
{
"script": "1e+0+0.001e3",
"input": "\"I wonder what this will be?\"",
"outputs": [
2.0
],
"error": null
}
{
"script": ".+4",
"input": "15",
"outputs": [
19.0
],
"error": null
}
{
"script": ".+null",
"input": "{\"a\":42}",
"outputs": [
{
"a": 42
}
],
"error": null
}
{
"script": "null+.",
"input": "null",
"outputs": [
null
],
"error": null
}
{
"script": ".a+.b",
"input": "{\"a\":42}",
"outputs": [
42
],
"error": null
}
{
"script": "[1,2,3] + [.]",
"input": "null",
"outputs": [
[
1,
2,
3,
null
]
],
"error": null
}
{
"script": "{\"a\":1} + {\"b\":2} + {\"c\":3}",
"input": "\"asdfasdf\"",
"outputs": [
{
"a": 1,
"b": 2,
"c": 3
}
],
"error": null
}
{
"script": "\"asdf\" + \"jkl;\" + . + . + .",
"input": "\"some string\"",
"outputs": [
"asdfjkl;some stringsome stringsome string"
],
"error": null
}
{
"script": "\"\\u0000\\u0020\\u0000\" + .",
"input": "\"\\u0000\\u0020\\u0000\"",
"outputs": [
"\u0000 \u0000\u0000 \u0000"
],
"error": null
}
{
"script": "42 - .",
"input": "11",
"outputs": [
31
],
"error": null
}
{
"script": "[1,2,3,4,1] - [.,3]",
"input": "1",
"outputs": [
[
2,
4
]
],
"error": null
}
{
"script": "[10 * 20, 20 / .]",
"input": "4",
"outputs": [
[
200,
5
]
],
"error": null
}
{
"script": "1 + 2 * 2 + 10 / 2",
"input": "null",
"outputs": [
10
],
"error": null
}
{
"script": "[16 / 4 / 2, 16 / 4 * 2, 16 - 4 - 2, 16 - 4 + 2]",
"input": "null",
"outputs": [
[
2,
8,
10,
14
]
],
"error": null
}
{
"script": "1e-19 + 1e-20 - 5e-21",
"input": "null",
"outputs": [
1.05E-19
],
"error": null
}
{
"script": "1 / 1e-17",
"input": "null",
"outputs": [
1E+17
],
"error": null
}
{
"script": "9E999999999, 9999999999E999999990, 1E-999999999, 0.000000001E-999999990",
"input": "null",
"outputs": [
9E+999999999,
9.999999999E+999999999,
1E-999999999,
1E-999999999
],
"error": null
}
{
"script": "5E500000000 > 5E-5000000000, 10000E500000000 > 10000E-5000000000",
"input": "null",
"outputs": [
true,
true
],
"error": null
}
{
"script": "(1e999999999, 10e999999999) > (1e-1147483646, 0.1e-1147483646)",
"input": "null",
"outputs": [
true,
true,
true,
true
],
"error": null
}
{
"script": "25 % 7",
"input": "null",
"outputs": [
4
],
"error": null
}
{
"script": "49732 % 472",
"input": "null",
"outputs": [
172
],
"error": null
}
{
"script": "[(infinite, -infinite) % (1, -1, infinite)]",
"input": "null",
"outputs": [
[
0,
0,
0,
0,
0,
-1
]
],
"error": null
}
{
"script": "[nan % 1, 1 % nan | isnan]",
"input": "null",
"outputs": [
[
true,
true
]
],
"error": null
}
{
"script": "1 + tonumber + (\"10\" | tonumber)",
"input": "4",
"outputs": [
15
],
"error": null
}
{
"script": "[{\"a\":42},.object,10,.num,false,true,null,\"b\",[1,4]] | .[] as $x | [$x == .[]]",
"input": "{\"object\": {\"a\":42}, \"num\":10.0}",
"outputs": [
[
true,
true,
false,
false,
false,
false,
false,
false,
false
],
[
true,
true,
false,
false,
false,
false,
false,
false,
false
],
[
false,
false,
true,
true,
false,
false,
false,
false,
false
],
[
false,
false,
true,
true,
false,
false,
false,
false,
false
],
[
false,
false,
false,
false,
true,
false,
false,
false,
false
],
[
false,
false,
false,
false,
false,
true,
false,
false,
false
],
[
false,
false,
false,
false,
false,
false,
true,
false,
false
],
[
false,
false,
false,
false,
false,
false,
false,
true,
false
],
[
false,
false,
false,
false,
false,
false,
false,
false,
true
]
],
"error": null
}
{
"script": "[.[] | length]",
"input": "[[], {}, [1,2], {\"a\":42}, \"asdf\", \"\\u03bc\"]",
"outputs": [
[
0,
0,
2,
1,
4,
1
]
],
"error": null
}
{
"script": "utf8bytelength",
"input": "\"asdf\\u03bc\"",
"outputs": [
6
],
"error": null
}
{
"script": "[.[] | try utf8bytelength catch .]",
"input": "[[], {}, [1,2], 55, true, false]",
"outputs": [
[
"array ([]) only strings have UTF-8 byte length",
"object ({}) only strings have UTF-8 byte length",
"array ([1,2]) only strings have UTF-8 byte length",
"number (55) only strings have UTF-8 byte length",
"boolean (true) only strings have UTF-8 byte length",
"boolean (false) only strings have UTF-8 byte length"
]
],
"error": null
}
{
"script": "map(keys)",
"input": "[{}, {\"abcd\":1,\"abc\":2,\"abcde\":3}, {\"x\":1, \"z\": 3, \"y\":2}]",
"outputs": [
[
[],
[
"abc",
"abcd",
"abcde"
],
[
"x",
"y",
"z"
]
]
],
"error": null
}
{
"script": "[1,2,empty,3,empty,4]",
"input": "null",
"outputs": [
[
1,
2,
3,
4
]
],
"error": null
}
{
"script": "map(add)",
"input": "[[], [1,2,3], [\"a\",\"b\",\"c\"], [[3],[4,5],[6]], [{\"a\":1}, {\"b\":2}, {\"a\":3}]]",
"outputs": [
[
null,
6,
"abc",
[
3,
4,
5,
6
],
{
"a": 3,
"b": 2
}
]
],
"error": null
}
{
"script": "map_values(.+1)",
"input": "[0,1,2]",
"outputs": [
[
1,
2,
3
]
],
"error": null
}
{
"script": "def f: . + 1; def g: def g: . + 100; f | g | f; (f | g), g",
"input": "3.0",
"outputs": [
106.0,
105.0
],
"error": null
}
{
"script": "def f: (1000,2000); f",
"input": "123412345",
"outputs": [
1000,
2000
],
"error": null
}
{
"script": "def f(a;b;c;d;e;f): [a+1,b,c,d,e,f]; f(.[0];.[1];.[0];.[0];.[0];.[0])",
"input": "[1,2]",
"outputs": [
[
2,
2,
1,
1,
1,
1
]
],
"error": null
}
{
"script": "def f: 1; def g: f, def f: 2; def g: 3; f, def f: g; f, g; def f: 4; [f, def f: g; def g: 5; f, g]+[f,g]",
"input": "null",
"outputs": [
[
4,
1,
2,
3,
3,
5,
4,
1,
2,
3,
3
]
],
"error": null
}
{
"script": "def a: 0; . | a",
"input": "null",
"outputs": [
0
],
"error": null
}
{
"script": "def f(a;b;c;d;e;f;g;h;i;j): [j,i,h,g,f,e,d,c,b,a]; f(.[0];.[1];.[2];.[3];.[4];.[5];.[6];.[7];.[8];.[9])",
"input": "[0,1,2,3,4,5,6,7,8,9]",
"outputs": [
[
9,
8,
7,
6,
5,
4,
3,
2,
1,
0
]
],
"error": null
}
{
"script": "([1,2] + [4,5])",
"input": "[1,2,3]",
"outputs": [
[
1,
2,
4,
5
]
],
"error": null
}
{
"script": "true",
"input": "[1]",
"outputs": [
true
],
"error": null
}
{
"script": "null,1,null",
"input": "\"hello\"",
"outputs": [
null,
1,
null
],
"error": null
}
{
"script": "[1,2,3]",
"input": "[5,6]",
"outputs": [
[
1,
2,
3
]
],
"error": null
}
{
"script": "[.[]|floor]",
"input": "[-1.1,1.1,1.9]",
"outputs": [
[
-2,
1,
1
]
],
"error": null
}
{
"script": "[.[]|sqrt]",
"input": "[4,9]",
"outputs": [
[
2,
3
]
],
"error": null
}
{
"script": "(add / length) as $m | map((. - $m) as $d | $d * $d) | add / length | sqrt",
"input": "[2,4,4,4,5,5,7,9]",
"outputs": [
2
],
"error": null
}
{
"script": "atan * 4 * 1000000|floor / 1000000",
"input": "1",
"outputs": [
3.141592
],
"error": null
}
{
"script": "[(3.141592 / 2) * (range(0;20) / 20)|cos * 1000000|floor / 1000000]",
"input": "null",
"outputs": [
[
1,
0.996917,
0.987688,
0.972369,
0.951056,
0.923879,
0.891006,
0.85264,
0.809017,
0.760406,
0.707106,
0.649448,
0.587785,
0.522498,
0.45399,
0.382683,
0.309017,
0.233445,
0.156434,
0.078459
]
],
"error": null
}
{
"script": "[(3.141592 / 2) * (range(0;20) / 20)|sin * 1000000|floor / 1000000]",
"input": "null",
"outputs": [
[
0,
0.078459,
0.156434,
0.233445,
0.309016,
0.382683,
0.45399,
0.522498,
0.587785,
0.649447,
0.707106,
0.760405,
0.809016,
0.85264,
0.891006,
0.923879,
0.951056,
0.972369,
0.987688,
0.996917
]
],
"error": null
}
{
"script": "def f(x): x | x; f([.], . + [42])",
"input": "[1,2,3]",
"outputs": [
[
[
[
1,
2,
3
]
]
],
[
[
1,
2,
3
],
42
],
[
[
1,
2,
3,
42
]
],
[
1,
2,
3,
42,
42
]
],
"error": null
}
{
"script": "def f: .+1; def g: f; def f: .+100; def f(a):a+.+11; [(g|f(20)), f]",
"input": "1",
"outputs": [
[
33,
101
]
],
"error": null
}
{
"script": "def id(x):x; 2000 as $x | def f(x):1 as $x | id([$x, x, x]); def g(x): 100 as $x | f($x,$x+x); g($x)",
"input": "\"more testing\"",
"outputs": [
[
1,
100,
2100.0,
100,
2100.0
]
],
"error": null
}
{
"script": "def x(a;b): a as $a | b as $b | $a + $b; def y($a;$b): $a + $b; def check(a;b): [x(a;b)] == [y(a;b)]; check(.[];.[]*2)",
"input": "[1,2,3]",
"outputs": [
true
],
"error": null
}
{
"script": "[[20,10][1,0] as $x | def f: (100,200) as $y | def g: [$x + $y, .]; . + $x | g; f[0] | [f][0][1] | f]",
"input": "999999999",
"outputs": [
[
[
110.0,
130.0
],
[
210.0,
130.0
],
[
110.0,
230.0
],
[
210.0,
230.0
],
[
120.0,
160.0
],
[
220.0,
160.0
],
[
120.0,
260.0
],
[
220.0,
260.0
]
]
],
"error": null
}
{
"script": "def fac: if . == 1 then 1 else . * (. - 1 | fac) end; [.[] | fac]",
"input": "[1,2,3,4]",
"outputs": [
[
1,
2,
6,
24
]
],
"error": null
}
{
"script": "reduce .[] as $x (0; . + $x)",
"input": "[1,2,4]",
"outputs": [
7
],
"error": null
}
{
"script": "reduce .[] as [$i, {j:$j}] (0; . + $i - $j)",
"input": "[[2,{\"j\":1}], [5,{\"j\":3}], [6,{\"j\":4}]]",
"outputs": [
5
],
"error": null
}
{
"script": "reduce [[1,2,10], [3,4,10]][] as [$i,$j] (0; . + $i * $j)",
"input": "null",
"outputs": [
14
],
"error": null
}
{
"script": "reduce . as $n (.; .)",
"input": "null",
"outputs": [
null
],
"error": null
}
{
"script": ". as {$a, b: [$c, {$d}]} | [$a, $c, $d]",
"input": "{\"a\":1, \"b\":[2,{\"d\":3}]}",
"outputs": [
[
1,
2,
3
]
],
"error": null
}
{
"script": ". as {$a, $b:[$c, $d]}| [$a, $b, $c, $d]",
"input": "{\"a\":1, \"b\":[2,{\"d\":3}]}",
"outputs": [
[
1,
[
2,
{
"d": 3
}
],
2,
{
"d": 3
}
]
],
"error": null
}
{
"script": ".[] | . as {$a, b: [$c, {$d}]} ?// [$a, {$b}, $e] ?// $f | [$a, $b, $c, $d, $e, $f]",
"input": "[{\"a\":1, \"b\":[2,{\"d\":3}]}, [4, {\"b\":5, \"c\":6}, 7, 8, 9], \"foo\"]",
"outputs": [
[
1,
null,
2,
3,
null,
null
],
[
4,
5,
null,
null,
7,
null
],
[
null,
null,
null,
null,
null,
"foo"
]
],
"error": null
}
{
"script": ".[] | . as {a:$a} ?// {a:$a} ?// {a:$a} | $a",
"input": "[[3],[4],[5],6]",
"outputs": [],
"error": null
}
{
"script": ".[] as {a:$a} ?// {a:$a} ?// {a:$a} | $a",
"input": "[[3],[4],[5],6]",
"outputs": [],
"error": null
}
{
"script": "[[3],[4],[5],6][] | . as {a:$a} ?// {a:$a} ?// {a:$a} | $a",
"input": "null",
"outputs": [],
"error": null
}
{
"script": "[[3],[4],[5],6] | .[] as {a:$a} ?// {a:$a} ?// {a:$a} | $a",
"input": "null",
"outputs": [],
"error": null
}
{
"script": ".[] | . as {a:$a} ?// {a:$a} ?// $a | $a",
"input": "[[3],[4],[5],6]",
"outputs": [
[
3
],
[
4
],
[
5
],
6
],
"error": null
}
{
"script": ".[] as {a:$a} ?// {a:$a} ?// $a | $a",
"input": "[[3],[4],[5],6]",
"outputs": [
[
3
],
[
4
],
[
5
],
6
],
"error": null
}
{
"script": "[[3],[4],[5],6][] | . as {a:$a} ?// {a:$a} ?// $a | $a",
"input": "null",
"outputs": [
[
3
],
[
4
],
[
5
],
6
],
"error": null
}
{
"script": "[[3],[4],[5],6] | .[] as {a:$a} ?// {a:$a} ?// $a | $a",
"input": "null",
"outputs": [
[
3
],
[
4
],
[
5
],
6
],
"error": null
}
{
"script": ".[] | . as {a:$a} ?// $a ?// {a:$a} | $a",
"input": "[[3],[4],[5],6]",
"outputs": [
[
3
],
[
4
],
[
5
],
6
],
"error": null
}
{
"script": ".[] as {a:$a} ?// $a ?// {a:$a} | $a",
"input": "[[3],[4],[5],6]",
"outputs": [
[
3
],
[
4
],
[
5
],
6
],
"error": null
}
{
"script": "[[3],[4],[5],6][] | . as {a:$a} ?// $a ?// {a:$a} | $a",
"input": "null",
"outputs": [
[
3
],
[
4
],
[
5
],
6
],
"error": null
}
{
"script": "[[3],[4],[5],6] | .[] as {a:$a} ?// $a ?// {a:$a} | $a",
"input": "null",
"outputs": [
[
3
],
[
4
],
[
5
],
6
],
"error": null
}
{
"script": ".[] | . as $a ?// {a:$a} ?// {a:$a} | $a",
"input": "[[3],[4],[5],6]",
"outputs": [
[
3
],
[
4
],
[
5
],
6
],
"error": null
}
{
"script": ".[] as $a ?// {a:$a} ?// {a:$a} | $a",
"input": "[[3],[4],[5],6]",
"outputs": [
[
3
],
[
4
],
[
5
],
6
],
"error": null
}
{
"script": "[[3],[4],[5],6][] | . as $a ?// {a:$a} ?// {a:$a} | $a",
"input": "null",
"outputs": [
[
3
],
[
4
],
[
5
],
6
],
"error": null
}
{
"script": "[[3],[4],[5],6] | .[] as $a ?// {a:$a} ?// {a:$a} | $a",
"input": "null",
"outputs": [
[
3
],
[
4
],
[
5
],
6
],
"error": null
}
{
"script": ". as $dot|any($dot[];not)",
"input": "[1,2,3,4,true,false,1,2,3,4,5]",
"outputs": [
true
],
"error": null
}
{
"script": ". as $dot|any($dot[];not)",
"input": "[1,2,3,4,true]",
"outputs": [
false
],
"error": null
}
{
"script": ". as $dot|all($dot[];.)",
"input": "[1,2,3,4,true,false,1,2,3,4,5]",
"outputs": [
false
],
"error": null
}
{
"script": ". as $dot|all($dot[];.)",
"input": "[1,2,3,4,true]",
"outputs": [
true
],
"error": null
}
{
"script": "any(true, error; .)",
"input": "\"badness\"",
"outputs": [
true
],
"error": null
}
{
"script": "all(false, error; .)",
"input": "\"badness\"",
"outputs": [
false
],
"error": null
}
{
"script": "any(not)",
"input": "[]",
"outputs": [
false
],
"error": null
}
{
"script": "all(not)",
"input": "[]",
"outputs": [
true
],
"error": null
}
{
"script": "any(not)",
"input": "[false]",
"outputs": [
true
],
"error": null
}
{
"script": "all(not)",
"input": "[false]",
"outputs": [
true
],
"error": null
}
{
"script": "[any,all]",
"input": "[]",
"outputs": [
[
false,
true
]
],
"error": null
}
{
"script": "[any,all]",
"input": "[true]",
"outputs": [
[
true,
true
]
],
"error": null
}
{
"script": "[any,all]",
"input": "[false]",
"outputs": [
[
false,
false
]
],
"error": null
}
{
"script": "[any,all]",
"input": "[true,false]",
"outputs": [
[
true,
false
]
],
"error": null
}
{
"script": "[any,all]",
"input": "[null,null,true]",
"outputs": [
[
true,
false
]
],
"error": null
}
{
"script": "path(.foo[0,1])",
"input": "null",
"outputs": [
[
"foo",
0
],
[
"foo",
1
]
],
"error": null
}
{
"script": "path(.[] | select(.>3))",
"input": "[1,5,3]",
"outputs": [
[
1
]
],
"error": null
}
{
"script": "path(.)",
"input": "42",
"outputs": [
[]
],
"error": null
}
{
"script": "try path(.a | map(select(.b == 0))) catch .",
"input": "{\"a\":[{\"b\":0}]}",
"outputs": [
"Invalid path expression with result [{\"b\":0}]"
],
"error": null
}
{
"script": "try path(.a | map(select(.b == 0)) | .[0]) catch .",
"input": "{\"a\":[{\"b\":0}]}",
"outputs": [
"Invalid path expression near attempt to access element 0 of [{\"b\":0}]"
],
"error": null
}
{
"script": "try path(.a | map(select(.b == 0)) | .c) catch .",
"input": "{\"a\":[{\"b\":0}]}",
"outputs": [
"Invalid path expression near attempt to access element \"c\" of [{\"b\":0}]"
],
"error": null
}
{
"script": "try path(.a | map(select(.b == 0)) | .[]) catch .",
"input": "{\"a\":[{\"b\":0}]}",
"outputs": [
"Invalid path expression near attempt to iterate through [{\"b\":0}]"
],
"error": null
}
{
"script": "path(.a[path(.b)[0]])",
"input": "{\"a\":{\"b\":0}}",
"outputs": [
[
"a",
"b"
]
],
"error": null
}
{
"script": "[paths]",
"input": "[1,[[],{\"a\":2}]]",
"outputs": [
[
[
0
],
[
1
],
[
1,
0
],
[
1,
1
],
[
1,
1,
"a"
]
]
],
"error": null
}
{
"script": "[\"foo\",1] as $p | getpath($p), setpath($p; 20), delpaths([$p])",
"input": "{\"bar\": 42, \"foo\": [\"a\", \"b\", \"c\", \"d\"]}",
"outputs": [
"b",
{
"bar": 42,
"foo": [
"a",
20,
"c",
"d"
]
},
{
"bar": 42,
"foo": [
"a",
"c",
"d"
]
}
],
"error": null
}
{
"script": "map(getpath([2])), map(setpath([2]; 42)), map(delpaths([[2]]))",
"input": "[[0], [0,1], [0,1,2]]",
"outputs": [
[
null,
null,
2
],
[
[
0,
null,
42
],
[
0,
1,
42
],
[
0,
1,
42
]
],
[
[
0
],
[
0,
1
],
[
0,
1
]
]
],
"error": null
}
{
"script": "map(delpaths([[0,\"foo\"]]))",
"input": "[[{\"foo\":2, \"x\":1}], [{\"bar\":2}]]",
"outputs": [
[
[
{
"x": 1
}
],
[
{
"bar": 2
}
]
]
],
"error": null
}
{
"script": "[\"foo\",1] as $p | getpath($p), setpath($p; 20), delpaths([$p])",
"input": "{\"bar\":false}",
"outputs": [
null,
{
"bar": false,
"foo": [
null,
20
]
},
{
"bar": false
}
],
"error": null
}
{
"script": "delpaths([[-200]])",
"input": "[1,2,3]",
"outputs": [
[
1,
2,
3
]
],
"error": null
}
{
"script": "try delpaths(0) catch .",
"input": "{}",
"outputs": [
"Paths must be specified as an array"
],
"error": null
}
{
"script": "del(.), del(empty), del((.foo,.bar,.baz) | .[2,3,0]), del(.foo[0], .bar[0], .foo, .baz.bar[0].x)",
"input": "{\"foo\": [0,1,2,3,4], \"bar\": [0,1]}",
"outputs": [
null,
{
"foo": [
0,
1,
2,
3,
4
],
"bar": [
0,
1
]
},
{
"foo": [
1,
4
],
"bar": [
1
]
},
{
"bar": [
1
]
}
],
"error": null
}
{
"script": "del(.[1], .[-6], .[2], .[-3:9])",
"input": "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]",
"outputs": [
[
0,
3,
5,
6,
9
]
],
"error": null
}
{
"script": "setpath([-1]; 1)",
"input": "[0]",
"outputs": [
[
1
]
],
"error": null
}
{
"script": "pick(.a.b.c)",
"input": "null",
"outputs": [
{
"a": {
"b": {
"c": null
}
}
}
],
"error": null
}
{
"script": "pick(first)",
"input": "[1,2]",
"outputs": [
[
1
]
],
"error": null
}
{
"script": "pick(first|first)",
"input": "[[10,20],30]",
"outputs": [
[
[
10
]
]
],
"error": null
}
{
"script": "try pick(last) catch .",
"input": "[1,2]",
"outputs": [
"Out of bounds negative array index"
],
"error": null
}
{
"script": ".message = \"goodbye\"",
"input": "{\"message\": \"hello\"}",
"outputs": [
{
"message": "goodbye"
}
],
"error": null
}
{
"script": ".foo = .bar",
"input": "{\"bar\":42}",
"outputs": [
{
"foo": 42,
"bar": 42
}
],
"error": null
}
{
"script": ".foo |= .+1",
"input": "{\"foo\": 42}",
"outputs": [
{
"foo": 43
}
],
"error": null
}
{
"script": ".[] += 2, .[] *= 2, .[] -= 2, .[] /= 2, .[] %=2",
"input": "[1,3,5]",
"outputs": [
[
3,
5,
7
],
[
2,
6,
10
],
[
-1,
1,
3
],
[
0.5,
1.5,
2.5
],
[
1,
1,
1
]
],
"error": null
}
{
"script": "[.[] % 7]",
"input": "[-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7]",
"outputs": [
[
0,
-6,
-5,
-4,
-3,
-2,
-1,
0,
1,
2,
3,
4,
5,
6,
0
]
],
"error": null
}
{
"script": ".foo += .foo",
"input": "{\"foo\":2}",
"outputs": [
{
"foo": 4
}
],
"error": null
}
{
"script": ".[0].a |= {\"old\":., \"new\":(.+1)}",
"input": "[{\"a\":1,\"b\":2}]",
"outputs": [
[
{
"a": {
"old": 1,
"new": 2
},
"b": 2
}
]
],
"error": null
}
{
"script": "def inc(x): x |= .+1; inc(.[].a)",
"input": "[{\"a\":1,\"b\":2},{\"a\":2,\"b\":4},{\"a\":7,\"b\":8}]",
"outputs": [
[
{
"a": 2,
"b": 2
},
{
"a": 3,
"b": 4
},
{
"a": 8,
"b": 8
}
]
],
"error": null
}
{
"script": ".[] | try (getpath([\"a\",0,\"b\"]) |= 5) catch .",
"input": "[null,{\"b\":0},{\"a\":0},{\"a\":null},{\"a\":[0,1]},{\"a\":{\"b\":1}},{\"a\":[{}]},{\"a\":[{\"c\":3}]}]",
"outputs": [
{
"a": [
{
"b": 5
}
]
},
{
"b": 0,
"a": [
{
"b": 5
}
]
},
"Cannot index number with number",
{
"a": [
{
"b": 5
}
]
},
"Cannot index number with string \"b\"",
"Cannot index object with number",
{
"a": [
{
"b": 5
}
]
},
{
"a": [
{
"c": 3,
"b": 5
}
]
}
],
"error": null
}
{
"script": "(.[] | select(. >= 2)) |= empty",
"input": "[1,5,3,0,7]",
"outputs": [
[
1,
0
]
],
"error": null
}
{
"script": ".[] |= select(. % 2 == 0)",
"input": "[0,1,2,3,4,5]",
"outputs": [
[
0,
2,
4
]
],
"error": null
}
{
"script": ".foo[1,4,2,3] |= empty",
"input": "{\"foo\":[0,1,2,3,4,5]}",
"outputs": [
{
"foo": [
0,
5
]
}
],
"error": null
}
{
"script": ".[2][3] = 1",
"input": "[4]",
"outputs": [
[
4,
null,
[
null,
null,
null,
1
]
]
],
"error": null
}
{
"script": ".foo[2].bar = 1",
"input": "{\"foo\":[11], \"bar\":42}",
"outputs": [
{
"foo": [
11,
null,
{
"bar": 1
}
],
"bar": 42
}
],
"error": null
}
{
"script": "try ((map(select(.a == 1))[].b) = 10) catch .",
"input": "[{\"a\":0},{\"a\":1}]",
"outputs": [
"Invalid path expression near attempt to iterate through [{\"a\":1}]"
],
"error": null
}
{
"script": "try ((map(select(.a == 1))[].a) |= .+1) catch .",
"input": "[{\"a\":0},{\"a\":1}]",
"outputs": [
"Invalid path expression near attempt to iterate through [{\"a\":1}]"
],
"error": null
}
{
"script": "def x: .[1,2]; x=10",
"input": "[0,1,2]",
"outputs": [
[
0,
10,
10
]
],
"error": null
}
{
"script": "try (def x: reverse; x=10) catch .",
"input": "[0,1,2]",
"outputs": [
"Invalid path expression with result [2,1,0]"
],
"error": null
}
{
"script": ".[] = 1",
"input": "[1,null,Infinity,-Infinity,NaN,-NaN]",
"outputs": [
[
1,
1,
1,
1,
1,
1
]
],
"error": null
}
{
"script": "[.[] | if .foo then \"yep\" else \"nope\" end]",
"input": "[{\"foo\":0},{\"foo\":1},{\"foo\":[]},{\"foo\":true},{\"foo\":false},{\"foo\":null},{\"foo\":\"foo\"},{}]",
"outputs": [
[
"yep",
"yep",
"yep",
"yep",
"nope",
"nope",
"yep",
"nope"
]
],
"error": null
}
{
"script": "[.[] | if .baz then \"strange\" elif .foo then \"yep\" else \"nope\" end]",
"input": "[{\"foo\":0},{\"foo\":1},{\"foo\":[]},{\"foo\":true},{\"foo\":false},{\"foo\":null},{\"foo\":\"foo\"},{}]",
"outputs": [
[
"yep",
"yep",
"yep",
"yep",
"nope",
"nope",
"yep",
"nope"
]
],
"error": null
}
{
"script": "[if 1,null,2 then 3 else 4 end]",
"input": "null",
"outputs": [
[
3,
4,
3
]
],
"error": null
}
{
"script": "[if empty then 3 else 4 end]",
"input": "null",
"outputs": [
[]
],
"error": null
}
{
"script": "[if 1 then 3,4 else 5 end]",
"input": "null",
"outputs": [
[
3,
4
]
],
"error": null
}
{
"script": "[if null then 3 else 5,6 end]",
"input": "null",
"outputs": [
[
5,
6
]
],
"error": null
}
{
"script": "[if true then 3 end]",
"input": "7",
"outputs": [
[
3
]
],
"error": null
}
{
"script": "[if false then 3 end]",
"input": "7",
"outputs": [
[
7
]
],
"error": null
}
{
"script": "[if false then 3 else . end]",
"input": "7",
"outputs": [
[
7
]
],
"error": null
}
{
"script": "[if false then 3 elif false then 4 end]",
"input": "7",
"outputs": [
[
7
]
],
"error": null
}
{
"script": "[if false then 3 elif false then 4 else . end]",
"input": "7",
"outputs": [
[
7
]
],
"error": null
}
{
"script": "[.[] | [.foo[] // .bar]]",
"input": "[{\"foo\":[1,2], \"bar\": 42}, {\"foo\":[1], \"bar\": null}, {\"foo\":[null,false,3], \"bar\": 18}, {\"foo\":[], \"bar\":42}, {\"foo\": [null,false,null], \"bar\": 41}]",
"outputs": [
[
[
1,
2
],
[
1
],
[
3
],
[
42
],
[
41
]
]
],
"error": null
}
{
"script": ".[] //= .[0]",
"input": "[\"hello\",true,false,[false],null]",
"outputs": [
[
"hello",
true,
"hello",
[
false
],
"hello"
]
],
"error": null
}
{
"script": ".[] | [.[0] and .[1], .[0] or .[1]]",
"input": "[[true,[]], [false,1], [42,null], [null,false]]",
"outputs": [
[
true,
true
],
[
false,
true
],
[
false,
true
],
[
false,
false
]
],
"error": null
}
{
"script": "[.[] | not]",
"input": "[1,0,false,null,true,\"hello\"]",
"outputs": [
[
false,
false,
true,
true,
false,
false
]
],
"error": null
}
{
"script": "[10 > 0, 10 > 10, 10 > 20, 10 < 0, 10 < 10, 10 < 20]",
"input": "{}",
"outputs": [
[
true,
false,
false,
false,
false,
true
]
],
"error": null
}
{
"script": "[10 >= 0, 10 >= 10, 10 >= 20, 10 <= 0, 10 <= 10, 10 <= 20]",
"input": "{}",
"outputs": [
[
true,
true,
false,
false,
true,
true
]
],
"error": null
}
{
"script": "[ 10 == 10, 10 != 10, 10 != 11, 10 == 11]",
"input": "{}",
"outputs": [
[
true,
false,
true,
false
]
],
"error": null
}
{
"script": "[\"hello\" == \"hello\", \"hello\" != \"hello\", \"hello\" == \"world\", \"hello\" != \"world\" ]",
"input": "{}",
"outputs": [
[
true,
false,
false,
true
]
],
"error": null
}
{
"script": "[[1,2,3] == [1,2,3], [1,2,3] != [1,2,3], [1,2,3] == [4,5,6], [1,2,3] != [4,5,6]]",
"input": "{}",
"outputs": [
[
true,
false,
false,
true
]
],
"error": null
}
{
"script": "[{\"foo\":42} == {\"foo\":42},{\"foo\":42} != {\"foo\":42}, {\"foo\":42} != {\"bar\":42}, {\"foo\":42} == {\"bar\":42}]",
"input": "{}",
"outputs": [
[
true,
false,
true,
false
]
],
"error": null
}
{
"script": "[{\"foo\":[1,2,{\"bar\":18},\"world\"]} == {\"foo\":[1,2,{\"bar\":18},\"world\"]},{\"foo\":[1,2,{\"bar\":18},\"world\"]} == {\"foo\":[1,2,{\"bar\":19},\"world\"]}]",
"input": "{}",
"outputs": [
[
true,
false
]
],
"error": null
}
{
"script": "[(\"foo\" | contains(\"foo\")), (\"foobar\" | contains(\"foo\")), (\"foo\" | contains(\"foobar\"))]",
"input": "{}",
"outputs": [
[
true,
true,
false
]
],
"error": null
}
{
"script": "[contains(\"\"), contains(\"\\u0000\")]",
"input": "\"\\u0000\"",
"outputs": [
[
true,
true
]
],
"error": null
}
{
"script": "[contains(\"\"), contains(\"a\"), contains(\"ab\"), contains(\"c\"), contains(\"d\")]",
"input": "\"ab\\u0000cd\"",
"outputs": [
[
true,
true,
true,
true,
true
]
],
"error": null
}
{
"script": "[contains(\"cd\"), contains(\"b\\u0000\"), contains(\"ab\\u0000\")]",
"input": "\"ab\\u0000cd\"",
"outputs": [
[
true,
true,
true
]
],
"error": null
}
{
"script": "[contains(\"b\\u0000c\"), contains(\"b\\u0000cd\"), contains(\"b\\u0000cd\")]",
"input": "\"ab\\u0000cd\"",
"outputs": [
[
true,
true,
true
]
],
"error": null
}
{
"script": "[contains(\"@\"), contains(\"\\u0000@\"), contains(\"\\u0000what\")]",
"input": "\"ab\\u0000cd\"",
"outputs": [
[
false,
false,
false
]
],
"error": null
}
{
"script": "[.[]|try if . == 0 then error(\"foo\") elif . == 1 then .a elif . == 2 then empty else . end catch .]",
"input": "[0,1,2,3]",
"outputs": [
[
"foo",
"Cannot index number with string \"a\"",
3
]
],
"error": null
}
{
"script": "[.[]|(.a, .a)?]",
"input": "[null,true,{\"a\":1}]",
"outputs": [
[
null,
null,
1,
1
]
],
"error": null
}
{
"script": "[[.[]|[.a,.a]]?]",
"input": "[null,true,{\"a\":1}]",
"outputs": [
[]
],
"error": null
}
{
"script": ".[] | try error catch .",
"input": "[1,null,2]",
"outputs": [
1,
null,
2
],
"error": null
}
{
"script": "try error(\"\\($__loc__)\") catch .",
"input": "null",
"outputs": [
"{\"file\":\"<top-level>\",\"line\":1}"
],
"error": null
}
{
"script": "[.[]|startswith(\"foo\")]",
"input": "[\"fo\", \"foo\", \"barfoo\", \"foobar\", \"barfoob\"]",
"outputs": [
[
false,
true,
false,
true,
false
]
],
"error": null
}
{
"script": "[.[]|endswith(\"foo\")]",
"input": "[\"fo\", \"foo\", \"barfoo\", \"foobar\", \"barfoob\"]",
"outputs": [
[
false,
true,
true,
false,
false
]
],
"error": null
}
{
"script": "[.[] | split(\", \")]",
"input": "[\"a,b, c, d, e,f\",\", a,b, c, d, e,f, \"]",
"outputs": [
[
[
"a,b",
"c",
"d",
"e,f"
],
[
"",
"a,b",
"c",
"d",
"e,f",
""
]
]
],
"error": null
}
{
"script": "split(\"\")",
"input": "\"abc\"",
"outputs": [
[
"a",
"b",
"c"
]
],
"error": null
}
{
"script": "[.[]|ltrimstr(\"foo\")]",
"input": "[\"fo\", \"foo\", \"barfoo\", \"foobar\", \"afoo\"]",
"outputs": [
[
"fo",
"",
"barfoo",
"bar",
"afoo"
]
],
"error": null
}
{
"script": "[.[]|rtrimstr(\"foo\")]",
"input": "[\"fo\", \"foo\", \"barfoo\", \"foobar\", \"foob\"]",
"outputs": [
[
"fo",
"",
"bar",
"foobar",
"foob"
]
],
"error": null
}
{
"script": "[(index(\",\"), rindex(\",\")), indices(\",\")]",
"input": "\"a,bc,def,ghij,klmno\"",
"outputs": [
[
1,
13,
[
1,
4,
8,
13
]
]
],
"error": null
}
{
"script": "[ index(\"aba\"), rindex(\"aba\"), indices(\"aba\") ]",
"input": "\"xababababax\"",
"outputs": [
[
1,
7,
[
1,
3,
5,
7
]
]
],
"error": null
}
{
"script": "indices(1)",
"input": "[0,1,1,2,3,4,1,5]",
"outputs": [
[
1,
2,
6
]
],
"error": null
}
{
"script": "indices([1,2])",
"input": "[0,1,2,3,1,4,2,5,1,2,6,7]",
"outputs": [
[
1,
8
]
],
"error": null
}
{
"script": "indices([1,2])",
"input": "[1]",
"outputs": [
[]
],
"error": null
}
{
"script": "indices(\", \")",
"input": "\"a,b, cd,e, fgh, ijkl\"",
"outputs": [
[
3,
9,
14
]
],
"error": null
}
{
"script": "[.[]|split(\",\")]",
"input": "[\"a, bc, def, ghij, jklmn, a,b, c,d, e,f\", \"a,b,c,d, e,f,g,h\"]",
"outputs": [
[
[
"a",
" bc",
" def",
" ghij",
" jklmn",
" a",
"b",
" c",
"d",
" e",
"f"
],
[
"a",
"b",
"c",
"d",
" e",
"f",
"g",
"h"
]
]
],
"error": null
}
{
"script": "[.[]|split(\", \")]",
"input": "[\"a, bc, def, ghij, jklmn, a,b, c,d, e,f\", \"a,b,c,d, e,f,g,h\"]",
"outputs": [
[
[
"a",
"bc",
"def",
"ghij",
"jklmn",
"a,b",
"c,d",
"e,f"
],
[
"a,b,c,d",
"e,f,g,h"
]
]
],
"error": null
}
{
"script": "[.[] * 3]",
"input": "[\"a\", \"ab\", \"abc\"]",
"outputs": [
[
"aaa",
"ababab",
"abcabcabc"
]
],
"error": null
}
{
"script": "[.[] * \"abc\"]",
"input": "[-1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 3.7, 10.0]",
"outputs": [
[
null,
null,
"",
"",
"abc",
"abc",
"abcabcabc",
"abcabcabcabcabcabcabcabcabcabc"
]
],
"error": null
}
{
"script": "[. * (nan,-nan)]",
"input": "\"abc\"",
"outputs": [
[
null,
null
]
],
"error": null
}
{
"script": "[.[] / \",\"]",
"input": "[\"a, bc, def, ghij, jklmn, a,b, c,d, e,f\", \"a,b,c,d, e,f,g,h\"]",
"outputs": [
[
[
"a",
" bc",
" def",
" ghij",
" jklmn",
" a",
"b",
" c",
"d",
" e",
"f"
],
[
"a",
"b",
"c",
"d",
" e",
"f",
"g",
"h"
]
]
],
"error": null
}
{
"script": "[.[] / \", \"]",
"input": "[\"a, bc, def, ghij, jklmn, a,b, c,d, e,f\", \"a,b,c,d, e,f,g,h\"]",
"outputs": [
[
[
"a",
"bc",
"def",
"ghij",
"jklmn",
"a,b",
"c,d",
"e,f"
],
[
"a,b,c,d",
"e,f,g,h"
]
]
],
"error": null
}
{
"script": "map(.[1] as $needle | .[0] | contains($needle))",
"input": "[[[],[]], [[1,2,3], [1,2]], [[1,2,3], [3,1]], [[1,2,3], [4]], [[1,2,3], [1,4]]]",
"outputs": [
[
true,
true,
true,
false,
false
]
],
"error": null
}
{
"script": "map(.[1] as $needle | .[0] | contains($needle))",
"input": "[[[\"foobar\", \"foobaz\"], [\"baz\", \"bar\"]], [[\"foobar\", \"foobaz\"], [\"foo\"]], [[\"foobar\", \"foobaz\"], [\"blap\"]]]",
"outputs": [
[
true,
true,
false
]
],
"error": null
}
{
"script": "[({foo: 12, bar:13} | contains({foo: 12})), ({foo: 12} | contains({})), ({foo: 12, bar:13} | contains({baz:14}))]",
"input": "{}",
"outputs": [
[
true,
true,
false
]
],
"error": null
}
{
"script": "{foo: {baz: 12, blap: {bar: 13}}, bar: 14} | contains({bar: 14, foo: {blap: {}}})",
"input": "{}",
"outputs": [
true
],
"error": null
}
{
"script": "{foo: {baz: 12, blap: {bar: 13}}, bar: 14} | contains({bar: 14, foo: {blap: {bar: 14}}})",
"input": "{}",
"outputs": [
false
],
"error": null
}
{
"script": "sort",
"input": "[42,[2,5,3,11],10,{\"a\":42,\"b\":2},{\"a\":42},true,2,[2,6],\"hello\",null,[2,5,6],{\"a\":[],\"b\":1},\"abc\",\"ab\",[3,10],{},false,\"abcd\",null]",
"outputs": [
[
null,
null,
false,
true,
2,
10,
42,
"ab",
"abc",
"abcd",
"hello",
[
2,
5,
3,
11
],
[
2,
5,
6
],
[
2,
6
],
[
3,
10
],
{},
{
"a": 42
},
{
"a": 42,
"b": 2
},
{
"a": [],
"b": 1
}
]
],
"error": null
}
{
"script": "(sort_by(.b) | sort_by(.a)), sort_by(.a, .b), sort_by(.b, .c), group_by(.b), group_by(.a + .b - .c == 2)",
"input": "[{\"a\": 1, \"b\": 4, \"c\": 14}, {\"a\": 4, \"b\": 1, \"c\": 3}, {\"a\": 1, \"b\": 4, \"c\": 3}, {\"a\": 0, \"b\": 2, \"c\": 43}]",
"outputs": [
[
{
"a": 0,
"b": 2,
"c": 43
},
{
"a": 1,
"b": 4,
"c": 14
},
{
"a": 1,
"b": 4,
"c": 3
},
{
"a": 4,
"b": 1,
"c": 3
}
],
[
{
"a": 0,
"b": 2,
"c": 43
},
{
"a": 1,
"b": 4,
"c": 14
},
{
"a": 1,
"b": 4,
"c": 3
},
{
"a": 4,
"b": 1,
"c": 3
}
],
[
{
"a": 4,
"b": 1,
"c": 3
},
{
"a": 0,
"b": 2,
"c": 43
},
{
"a": 1,
"b": 4,
"c": 3
},
{
"a": 1,
"b": 4,
"c": 14
}
],
[
[
{
"a": 4,
"b": 1,
"c": 3
}
],
[
{
"a": 0,
"b": 2,
"c": 43
}
],
[
{
"a": 1,
"b": 4,
"c": 14
},
{
"a": 1,
"b": 4,
"c": 3
}
]
],
[
[
{
"a": 1,
"b": 4,
"c": 14
},
{
"a": 0,
"b": 2,
"c": 43
}
],
[
{
"a": 4,
"b": 1,
"c": 3
},
{
"a": 1,
"b": 4,
"c": 3
}
]
]
],
"error": null
}
{
"script": "unique",
"input": "[1,2,5,3,5,3,1,3]",
"outputs": [
[
1,
2,
3,
5
]
],
"error": null
}
{
"script": "unique",
"input": "[]",
"outputs": [
[]
],
"error": null
}
{
"script": "[min, max, min_by(.[1]), max_by(.[1]), min_by(.[2]), max_by(.[2])]",
"input": "[[4,2,\"a\"],[3,1,\"a\"],[2,4,\"a\"],[1,3,\"a\"]]",
"outputs": [
[
[
1,
3,
"a"
],
[
4,
2,
"a"
],
[
3,
1,
"a"
],
[
2,
4,
"a"
],
[
4,
2,
"a"
],
[
1,
3,
"a"
]
]
],
"error": null
}
{
"script": "[min,max,min_by(.),max_by(.)]",
"input": "[]",
"outputs": [
[
null,
null,
null,
null
]
],
"error": null
}
{
"script": ".foo[.baz]",
"input": "{\"foo\":{\"bar\":4},\"baz\":\"bar\"}",
"outputs": [
4
],
"error": null
}
{
"script": ".[] | .error = \"no, it's OK\"",
"input": "[{\"error\":true}]",
"outputs": [
{
"error": "no, it's OK"
}
],
"error": null
}
{
"script": "[{a:1}] | .[] | .a=999",
"input": "null",
"outputs": [
{
"a": 999
}
],
"error": null
}
{
"script": "to_entries",
"input": "{\"a\": 1, \"b\": 2}",
"outputs": [
[
{
"key": "a",
"value": 1
},
{
"key": "b",
"value": 2
}
]
],
"error": null
}
{
"script": "from_entries",
"input": "[{\"key\":\"a\", \"value\":1}, {\"Key\":\"b\", \"Value\":2}, {\"name\":\"c\", \"value\":3}, {\"Name\":\"d\", \"Value\":4}]",
"outputs": [
{
"a": 1,
"b": 2,
"c": 3,
"d": 4
}
],
"error": null
}
{
"script": "with_entries(.key |= \"KEY_\" + .)",
"input": "{\"a\": 1, \"b\": 2}",
"outputs": [
{
"KEY_a": 1,
"KEY_b": 2
}
],
"error": null
}
{
"script": "map(has(\"foo\"))",
"input": "[{\"foo\": 42}, {}]",
"outputs": [
[
true,
false
]
],
"error": null
}
{
"script": "map(has(2))",
"input": "[[0,1], [\"a\",\"b\",\"c\"]]",
"outputs": [
[
false,
true
]
],
"error": null
}
{
"script": "has(nan)",
"input": "[0,1,2]",
"outputs": [
false
],
"error": null
}
{
"script": "keys",
"input": "[42,3,35]",
"outputs": [
[
0,
1,
2
]
],
"error": null
}
{
"script": "[][.]",
"input": "1000000000000000000",
"outputs": [
null
],
"error": null
}
{
"script": "map([1,2][0:.])",
"input": "[-1, 1, 2, 3, 1000000000000000000]",
"outputs": [
[
[
1
],
[
1
],
[
1,
2
],
[
1,
2
],
[
1,
2
]
]
],
"error": null
}
{
"script": "{\"k\": {\"a\": 1, \"b\": 2}} * .",
"input": "{\"k\": {\"a\": 0,\"c\": 3}}",
"outputs": [
{
"k": {
"a": 0,
"b": 2,
"c": 3
}
}
],
"error": null
}
{
"script": "{\"k\": {\"a\": 1, \"b\": 2}, \"hello\": {\"x\": 1}} * .",
"input": "{\"k\": {\"a\": 0,\"c\": 3}, \"hello\": 1}",
"outputs": [
{
"k": {
"a": 0,
"b": 2,
"c": 3
},
"hello": 1
}
],
"error": null
}
{
"script": "{\"k\": {\"a\": 1, \"b\": 2}, \"hello\": 1} * .",
"input": "{\"k\": {\"a\": 0,\"c\": 3}, \"hello\": {\"x\": 1}}",
"outputs": [
{
"k": {
"a": 0,
"b": 2,
"c": 3
},
"hello": {
"x": 1
}
}
],
"error": null
}
{
"script": "{\"a\": {\"b\": 1}, \"c\": {\"d\": 2}, \"e\": 5} * .",
"input": "{\"a\": {\"b\": 2}, \"c\": {\"d\": 3, \"f\": 9}}",
"outputs": [
{
"a": {
"b": 2
},
"c": {
"d": 3,
"f": 9
},
"e": 5
}
],
"error": null
}
{
"script": "[.[]|arrays]",
"input": "[1,2,\"foo\",[],[3,[]],{},true,false,null]",
"outputs": [
[
[],
[
3,
[]
]
]
],
"error": null
}
{
"script": "[.[]|objects]",
"input": "[1,2,\"foo\",[],[3,[]],{},true,false,null]",
"outputs": [
[
{}
]
],
"error": null
}
{
"script": "[.[]|iterables]",
"input": "[1,2,\"foo\",[],[3,[]],{},true,false,null]",
"outputs": [
[
[],
[
3,
[]
],
{}
]
],
"error": null
}
{
"script": "[.[]|scalars]",
"input": "[1,2,\"foo\",[],[3,[]],{},true,false,null]",
"outputs": [
[
1,
2,
"foo",
true,
false,
null
]
],
"error": null
}
{
"script": "[.[]|values]",
"input": "[1,2,\"foo\",[],[3,[]],{},true,false,null]",
"outputs": [
[
1,
2,
"foo",
[],
[
3,
[]
],
{},
true,
false
]
],
"error": null
}
{
"script": "[.[]|booleans]",
"input": "[1,2,\"foo\",[],[3,[]],{},true,false,null]",
"outputs": [
[
true,
false
]
],
"error": null
}
{
"script": "[.[]|nulls]",
"input": "[1,2,\"foo\",[],[3,[]],{},true,false,null]",
"outputs": [
[
null
]
],
"error": null
}
{
"script": "flatten",
"input": "[0, [1], [[2]], [[[3]]]]",
"outputs": [
[
0,
1,
2,
3
]
],
"error": null
}
{
"script": "flatten(0)",
"input": "[0, [1], [[2]], [[[3]]]]",
"outputs": [
[
0,
[
1
],
[
[
2
]
],
[
[
[
3
]
]
]
]
],
"error": null
}
{
"script": "flatten(2)",
"input": "[0, [1], [[2]], [[[3]]]]",
"outputs": [
[
0,
1,
2,
[
3
]
]
],
"error": null
}
{
"script": "flatten(2)",
"input": "[0, [1, [2]], [1, [[3], 2]]]",
"outputs": [
[
0,
1,
2,
1,
[
3
],
2
]
],
"error": null
}
{
"script": "try flatten(-1) catch .",
"input": "[0, [1], [[2]], [[[3]]]]",
"outputs": [
"flatten depth must not be negative"
],
"error": null
}
{
"script": "transpose",
"input": "[[1], [2,3]]",
"outputs": [
[
[
1,
2
],
[
null,
3
]
]
],
"error": null
}
{
"script": "transpose",
"input": "[]",
"outputs": [
[]
],
"error": null
}
{
"script": "ascii_upcase",
"input": "\"useful but not for é\"",
"outputs": [
"USEFUL BUT NOT FOR é"
],
"error": null
}
{
"script": "bsearch(0,2,4)",
"input": "[1,2,3]",
"outputs": [
-1,
1,
-4
],
"error": null
}
{
"script": "strftime(\"%Y-%m-%dT%H:%M:%SZ\")",
"input": "[2015,2,5,23,51,47,4,63]",
"outputs": [
"2015-03-05T23:51:47Z"
],
"error": null
}
{
"script": "strftime(\"%A, %B %d, %Y\")",
"input": "1435677542.822351",
"outputs": [
"Tuesday, June 30, 2015"
],
"error": null
}
{
"script": "gmtime",
"input": "1425599507",
"outputs": [
[
2015,
2,
5,
23,
51,
47,
4,
63
]
],
"error": null
}
{
"script": "try strftime(\"%Y-%m-%dT%H:%M:%SZ\") catch .",
"input": "[\"a\",1,2,3,4,5,6,7]",
"outputs": [
"strftime/1 requires parsed datetime inputs"
],
"error": null
}
{
"script": "try strflocaltime(\"%Y-%m-%dT%H:%M:%SZ\") catch .",
"input": "[\"a\",1,2,3,4,5,6,7]",
"outputs": [
"strflocaltime/1 requires parsed datetime inputs"
],
"error": null
}
{
"script": "try mktime catch .",
"input": "[\"a\",1,2,3,4,5,6,7]",
"outputs": [
"mktime requires parsed datetime inputs"
],
"error": null
}
{
"script": "import \"a\" as foo; import \"b\" as bar; def fooa: foo::a; [fooa, bar::a, bar::b, foo::a]",
"input": "null",
"outputs": [
[
"a",
"b",
"c",
"a"
]
],
"error": null
}
{
"script": "import \"c\" as foo; [foo::a, foo::c]",
"input": "null",
"outputs": [
[
0,
"acmehbah"
]
],
"error": null
}
{
"script": "include \"c\"; [a, c]",
"input": "null",
"outputs": [
[
0,
"acmehbah"
]
],
"error": null
}
{
"script": "import \"data\" as $e; import \"data\" as $d; [$d[].this,$e[].that,$d::d[].this,$e::e[].that]|join(\";\")",
"input": "null",
"outputs": [
"is a test;is too;is a test;is too"
],
"error": null
}
{
"script": "import \"data\" as $a; import \"data\" as $b; def f: {$a, $b}; f",
"input": "null",
"outputs": [
{
"a": [
{
"this": "is a test",
"that": "is too"
}
],
"b": [
{
"this": "is a test",
"that": "is too"
}
]
}
],
"error": null
}
{
"script": "include \"shadow1\"; e",
"input": "null",
"outputs": [
2
],
"error": null
}
{
"script": "include \"shadow1\"; include \"shadow2\"; e",
"input": "null",
"outputs": [
3
],
"error": null
}
{
"script": "import \"shadow1\" as f; import \"shadow2\" as f; import \"shadow1\" as e; [e::e, f::e]",
"input": "null",
"outputs": [
[
2,
3
]
],
"error": null
}
{
"script": "module (.+1); 0",
"input": null,
"outputs": null,
"error": "jq: error: Module metadata must be constant at <top-level>, line 1:"
}
{
"script": "module []; 0",
"input": null,
"outputs": null,
"error": "jq: error: Module metadata must be an object at <top-level>, line 1:"
}
{
"script": "include \"a\" (.+1); 0",
"input": null,
"outputs": null,
"error": "jq: error: Module metadata must be constant at <top-level>, line 1:"
}
{
"script": "include \"a\" []; 0",
"input": null,
"outputs": null,
"error": "jq: error: Module metadata must be an object at <top-level>, line 1:"
}
{
"script": "include \"\\ \"; 0",
"input": null,
"outputs": null,
"error": "jq: error: Invalid escape at line 1, column 4 (while parsing '\"\\ \"') at <top-level>, line 1:"
}
{
"script": "include \"\\(a)\"; 0",
"input": null,
"outputs": null,
"error": "jq: error: Import path must be constant at <top-level>, line 1:"
}
{
"script": "modulemeta",
"input": "\"c\"",
"outputs": [
{
"whatever": null,
"deps": [
{
"as": "foo",
"is_data": false,
"relpath": "a"
},
{
"search": "./",
"as": "d",
"is_data": false,
"relpath": "d"
},
{
"search": "./",
"as": "d2",
"is_data": false,
"relpath": "d"
},
{
"search": "./../lib/jq",
"as": "e",
"is_data": false,
"relpath": "e"
},
{
"search": "./../lib/jq",
"as": "f",
"is_data": false,
"relpath": "f"
},
{
"as": "d",
"is_data": true,
"relpath": "data"
}
],
"defs": [
"a/0",
"c/0"
]
}
],
"error": null
}
{
"script": "modulemeta | .deps | length",
"input": "\"c\"",
"outputs": [
6
],
"error": null
}
{
"script": "modulemeta | .defs | length",
"input": "\"c\"",
"outputs": [
2
],
"error": null
}
{
"script": "import \"syntaxerror\" as e; .",
"input": null,
"outputs": null,
"error": null
}
{
"script": "%::wat",
"input": null,
"outputs": null,
"error": null
}
{
"script": "import \"test_bind_order\" as check; check::check",
"input": "null",
"outputs": [
true
],
"error": null
}
{
"script": "try -. catch .",
"input": "\"very-long-string\"",
"outputs": [
"string (\"very-long-...) cannot be negated"
],
"error": null
}
{
"script": "join(\",\")",
"input": "[\"1\",2,true,false,3.4]",
"outputs": [
"1,2,true,false,3.4"
],
"error": null
}
{
"script": ".[] | join(\",\")",
"input": "[[], [null], [null,null], [null,null,null]]",
"outputs": [
"",
"",
",",
",,"
],
"error": null
}
{
"script": ".[] | join(\",\")",
"input": "[[\"a\",null], [null,\"a\"]]",
"outputs": [
"a,",
",a"
],
"error": null
}
{
"script": "try join(\",\") catch .",
"input": "[\"1\",\"2\",{\"a\":{\"b\":{\"c\":33}}}]",
"outputs": [
"string (\"1,2,\") and object ({\"a\":{\"b\":{...) cannot be added"
],
"error": null
}
{
"script": "try join(\",\") catch .",
"input": "[\"1\",\"2\",[3,4,5]]",
"outputs": [
"string (\"1,2,\") and array ([3,4,5]) cannot be added"
],
"error": null
}
{
"script": "{if:0,and:1,or:2,then:3,else:4,elif:5,end:6,as:7,def:8,reduce:9,foreach:10,try:11,catch:12,label:13,import:14,include:15,module:16}",
"input": "null",
"outputs": [
{
"if": 0,
"and": 1,
"or": 2,
"then": 3,
"else": 4,
"elif": 5,
"end": 6,
"as": 7,
"def": 8,
"reduce": 9,
"foreach": 10,
"try": 11,
"catch": 12,
"label": 13,
"import": 14,
"include": 15,
"module": 16
}
],
"error": null
}
{
"script": "try (1/.) catch .",
"input": "0",
"outputs": [
"number (1) and number (0) cannot be divided because the divisor is zero"
],
"error": null
}
{
"script": "try (1/0) catch .",
"input": "0",
"outputs": [
"number (1) and number (0) cannot be divided because the divisor is zero"
],
"error": null
}
{
"script": "try (0/0) catch .",
"input": "0",
"outputs": [
"number (0) and number (0) cannot be divided because the divisor is zero"
],
"error": null
}
{
"script": "try (1%.) catch .",
"input": "0",
"outputs": [
"number (1) and number (0) cannot be divided (remainder) because the divisor is zero"
],
"error": null
}
{
"script": "try (1%0) catch .",
"input": "0",
"outputs": [
"number (1) and number (0) cannot be divided (remainder) because the divisor is zero"
],
"error": null
}
{
"script": "[range(-52;52;1)] as $powers | [$powers[]|pow(2;.)|log2|round] == $powers",
"input": "null",
"outputs": [
true
],
"error": null
}
{
"script": "[range(-99/2;99/2;1)] as $orig | [$orig[]|pow(2;.)|log2] as $back | ($orig|keys)[]|. as $k | (($orig|.[$k])-($back|.[$k]))|if . < 0 then . * -1 else . end|select(.>.00005)",
"input": "null",
"outputs": [],
"error": null
}
{
"script": "}",
"input": null,
"outputs": null,
"error": null
}
{
"script": "(.[{}] = 0)?",
"input": "null",
"outputs": [],
"error": null
}
{
"script": "INDEX(range(5)|[., \"foo\\(.)\"]; .[0])",
"input": "null",
"outputs": [
{
"0": [
0,
"foo0"
],
"1": [
1,
"foo1"
],
"2": [
2,
"foo2"
],
"3": [
3,
"foo3"
],
"4": [
4,
"foo4"
]
}
],
"error": null
}
{
"script": "JOIN({\"0\":[0,\"abc\"],\"1\":[1,\"bcd\"],\"2\":[2,\"def\"],\"3\":[3,\"efg\"],\"4\":[4,\"fgh\"]}; .[0]|tostring)",
"input": "[[5,\"foo\"],[3,\"bar\"],[1,\"foobar\"]]",
"outputs": [
[
[
[
5,
"foo"
],
null
],
[
[
3,
"bar"
],
[
3,
"efg"
]
],
[
[
1,
"foobar"
],
[
1,
"bcd"
]
]
]
],
"error": null
}
{
"script": "range(5;10)|IN(range(10))",
"input": "null",
"outputs": [
true,
true,
true,
true,
true
],
"error": null
}
{
"script": "range(5;13)|IN(range(0;10;3))",
"input": "null",
"outputs": [
false,
true,
false,
false,
true,
false,
false,
false
],
"error": null
}
{
"script": "range(10;12)|IN(range(10))",
"input": "null",
"outputs": [
false,
false
],
"error": null
}
{
"script": "IN(range(10;20); range(10))",
"input": "null",
"outputs": [
false
],
"error": null
}
{
"script": "IN(range(5;20); range(10))",
"input": "null",
"outputs": [
true
],
"error": null
}
{
"script": "(.a as $x | .b) = \"b\"",
"input": "{\"a\":null,\"b\":null}",
"outputs": [
{
"a": null,
"b": "b"
}
],
"error": null
}
{
"script": "(.. | select(type == \"object\" and has(\"b\") and (.b | type) == \"array\")|.b) |= .[0]",
"input": "{\"a\": {\"b\": [1, {\"b\": 3}]}}",
"outputs": [
{
"a": {
"b": 1
}
}
],
"error": null
}
{
"script": "isempty(empty)",
"input": "null",
"outputs": [
true
],
"error": null
}
{
"script": "isempty(range(3))",
"input": "null",
"outputs": [
false
],
"error": null
}
{
"script": "isempty(1,error(\"foo\"))",
"input": "null",
"outputs": [
false
],
"error": null
}
{
"script": "index(\"\")",
"input": "\"\"",
"outputs": [
null
],
"error": null
}
{
"script": "builtins|length > 10",
"input": "null",
"outputs": [
true
],
"error": null
}
{
"script": "\"-1\"|IN(builtins[] / \"/\"|.[1])",
"input": "null",
"outputs": [
false
],
"error": null
}
{
"script": "all(builtins[] / \"/\"; .[1]|tonumber >= 0)",
"input": "null",
"outputs": [
true
],
"error": null
}
{
"script": "builtins|any(.[:1] == \"_\")",
"input": "null",
"outputs": [
false
],
"error": null
}
{
"script": "map(. == 1)",
"input": "[1, 1.0, 1.000, 100e-2, 1e+0, 0.0001e4]",
"outputs": [
[
true,
true,
true,
true,
true,
true
]
],
"error": null
}
{
"script": ".[0] | tostring",
"input": "[13911860366432393]",
"outputs": [
"13911860366432393"
],
"error": null
}
{
"script": ".x | tojson",
"input": "{\"x\":13911860366432393}",
"outputs": [
"13911860366432393"
],
"error": null
}
{
"script": "13911860366432393 == 13911860366432392",
"input": "null",
"outputs": [
false
],
"error": null
}
{
"script": ". - 10",
"input": "13911860366432393",
"outputs": [
13911860366432382
],
"error": null
}
{
"script": ".[0] - 10",
"input": "[13911860366432393]",
"outputs": [
13911860366432382
],
"error": null
}
{
"script": ".x - 10",
"input": "{\"x\":13911860366432393}",
"outputs": [
13911860366432382
],
"error": null
}
{
"script": ". |= try . catch .",
"input": "1",
"outputs": [
1
],
"error": null
}
{
"script": "abs",
"input": "\"abc\"",
"outputs": [
"abc"
],
"error": null
}
{
"script": "map(abs)",
"input": "[-0, 0, -10, -1.1]",
"outputs": [
[
0,
0,
10,
1.1
]
],
"error": null
}
{
"script": "map(fabs == length) | unique",
"input": "[-10, -1.1, -1e-1, 1000000000000000002]",
"outputs": [
[
true
]
],
"error": null
}
{
"script": "map(abs)",
"input": "[0.1,1000000000000000002]",
"outputs": [
[
0.1,
1000000000000000002
]
],
"error": null
}
{
"script": "123 as $label | $label",
"input": "null",
"outputs": [
123
],
"error": null
}
{
"script": "[ label $if | range(10) | ., (select(. == 5) | break $if) ]",
"input": "null",
"outputs": [
[
0,
1,
2,
3,
4,
5
]
],
"error": null
}
{
"script": "reduce .[] as $then (4 as $else | $else; . as $elif | . + $then * $elif)",
"input": "[1,2,3]",
"outputs": [
96
],
"error": null
}
{
"script": "1 as $foreach | 2 as $and | 3 as $or | { $foreach, $and, $or, a }",
"input": "{\"a\":4,\"b\":5}",
"outputs": [
{
"foreach": 1,
"and": 2,
"or": 3,
"a": 4
}
],
"error": null
}
{
"script": "[ foreach .[] as $try (1 as $catch | $catch - 1; . + $try; .) ]",
"input": "[10,9,8,7]",
"outputs": [
[
10,
19,
27,
34
]
],
"error": null
}
{
"script": "{ a, $__loc__, c }",
"input": "{\"a\":[1,2,3],\"b\":\"foo\",\"c\":{\"hi\":\"hey\"}}",
"outputs": [
{
"a": [
1,
2,
3
],
"__loc__": {
"file": "<top-level>",
"line": 1
},
"c": {
"hi": "hey"
}
}
],
"error": null
}
{
"script": "1 as $x | \"2\" as $y | \"3\" as $z | { $x, as, $y: 4, ($z): 5, if: 6, foo: 7 }",
"input": "{\"as\":8}",
"outputs": [
{
"x": 1,
"as": 8,
"2": 4,
"3": 5,
"if": 6,
"foo": 7
}
],
"error": null
}
{
"script": "fromjson | isnan",
"input": "\"nan\"",
"outputs": [
true
],
"error": null
}
{
"script": "tojson | fromjson",
"input": "{\"a\":nan}",
"outputs": [
{
"a": null
}
],
"error": null
}
{
"script": "try input catch .",
"input": "null",
"outputs": [
"break"
],
"error": null
}
{
"script": "debug",
"input": "1",
"outputs": [
1
],
"error": null
}
{
"script": "\"foo\" | try ((try . catch \"caught too much\") | error) catch \"caught just right\"",
"input": "null",
"outputs": [
"caught just right"
],
"error": null
}
{
"script": ".[]|(try (if .==\"hi\" then . else error end) catch empty) | \"\\(.) there!\"",
"input": "[\"hi\",\"ho\"]",
"outputs": [
"hi there!"
],
"error": null
}
{
"script": "try ([\"hi\",\"ho\"]|.[]|(try . catch (if .==\"ho\" then \"BROKEN\"|error else empty end)) | if .==\"ho\" then error else \"\\(.) there!\" end) catch \"caught outside \\(.)\"",
"input": "null",
"outputs": [
"hi there!",
"caught outside ho"
],
"error": null
}
{
"script": ".[]|(try . catch (if .==\"ho\" then \"BROKEN\"|error else empty end)) | if .==\"ho\" then error else \"\\(.) there!\" end",
"input": "[\"hi\",\"ho\"]",
"outputs": [
"hi there!"
],
"error": null
}
{
"script": "try (try error catch \"inner catch \\(.)\") catch \"outer catch \\(.)\"",
"input": "\"foo\"",
"outputs": [
"inner catch foo"
],
"error": null
}
{
"script": "try ((try error catch \"inner catch \\(.)\")|error) catch \"outer catch \\(.)\"",
"input": "\"foo\"",
"outputs": [
"outer catch inner catch foo"
],
"error": null
}
{
"script": "first(.?,.?)",
"input": "null",
"outputs": [
null
],
"error": null
}
{
"script": "{foo: \"bar\"} | .foo |= .?",
"input": "null",
"outputs": [
{
"foo": "bar"
}
],
"error": null
}
{
"script": ". |= try 2",
"input": "1",
"outputs": [
2
],
"error": null
}
{
"script": ". |= try 2 catch 3",
"input": "1",
"outputs": [
2
],
"error": null
}
{
"script": ".[] |= try tonumber",
"input": "[\"1\", \"2a\", \"3\", 4]",
"outputs": [
[
1,
3,
4
]
],
"error": null
}
{
"script": "any(keys[]|tostring?;true)",
"input": "{\"a\":\"1\",\"b\":\"2\",\"c\":\"3\"}",
"outputs": [
true
],
"error": null
}
{
"script": "implode|explode",
"input": "[-1,0,1,2,3,1114111,1114112,55295,55296,57343,57344,1.1,1.9]",
"outputs": [
[
65533,
0,
1,
2,
3,
1114111,
65533,
55295,
65533,
65533,
57344,
1,
1
]
],
"error": null
}
{
"script": "map(try implode catch .)",
"input": "[123,[\"a\"],[nan]]",
"outputs": [
[
"implode input must be an array",
"string (\"a\") can't be imploded, unicode codepoint needs to be numeric",
"number (null) can't be imploded, unicode codepoint needs to be numeric"
]
],
"error": null
}
{
"script": "walk(.)",
"input": "{\"x\":0}",
"outputs": [
{
"x": 0
}
],
"error": null
}
{
"script": "walk(1)",
"input": "{\"x\":0}",
"outputs": [
1
],
"error": null
}
{
"script": "[walk(.,1)]",
"input": "{\"x\":0}",
"outputs": [
[
{
"x": 0
},
1
]
],
"error": null
}
{
"script": "walk(select(IN({}, []) | not))",
"input": "{\"a\":1,\"b\":[]}",
"outputs": [
{
"a": 1
}
],
"error": null
}
{
"script": "[range(10)] | .[1.2:3.5]",
"input": "null",
"outputs": [
[
1,
2,
3
]
],
"error": null
}
{
"script": "[range(10)] | .[1.5:3.5]",
"input": "null",
"outputs": [
[
1,
2,
3
]
],
"error": null
}
{
"script": "[range(10)] | .[1.7:3.5]",
"input": "null",
"outputs": [
[
1,
2,
3
]
],
"error": null
}
{
"script": "[range(10)] | .[1.7:4294967295]",
"input": "null",
"outputs": [
[
1,
2,
3,
4,
5,
6,
7,
8,
9
]
],
"error": null
}
{
"script": "[range(10)] | .[1.7:-4294967296]",
"input": "null",
"outputs": [
[]
],
"error": null
}
{
"script": "[[range(10)] | .[1.1,1.5,1.7]]",
"input": "null",
"outputs": [
[
1,
1,
1
]
],
"error": null
}
{
"script": "[range(5)] | .[1.1] = 5",
"input": "null",
"outputs": [
[
0,
5,
2,
3,
4
]
],
"error": null
}
{
"script": "[range(3)] | .[nan:1]",
"input": "null",
"outputs": [
[
0
]
],
"error": null
}
{
"script": "[range(3)] | .[1:nan]",
"input": "null",
"outputs": [
[
1,
2
]
],
"error": null
}
{
"script": "[range(3)] | .[nan]",
"input": "null",
"outputs": [
null
],
"error": null
}
{
"script": "try ([range(3)] | .[nan] = 9) catch .",
"input": "null",
"outputs": [
"Cannot set array element at NaN index"
],
"error": null
}
{
"script": "try (\"foobar\" | .[1.5:3.5] = \"xyz\") catch .",
"input": "null",
"outputs": [
"Cannot update string slices"
],
"error": null
}
{
"script": "try ([range(10)] | .[1.5:3.5] = [\"xyz\"]) catch .",
"input": "null",
"outputs": [
[
0,
"xyz",
4,
5,
6,
7,
8,
9
]
],
"error": null
}
{
"script": "try (\"foobar\" | .[1.5]) catch .",
"input": "null",
"outputs": [
"Cannot index string with number"
],
"error": null
} |
|
Yes, we have extensions. I was referring to what we output, but indeed we accept more than what we output. |
Thanks, I got more appropriate understanding of syntax. One more question. How to distinguish runtime errors and empty output cases? |
|
So stderr and exit code are fully ignored until |
|
Hi! Can you please point out what is wrong with my jq-1.7-dirty tests in windows cmd?
$ echo 13911860366432393 | jq ".-10"
13911860366432380 Corresponding test is:
which correctly passes as
which fails as I can get |
This is probably because a 64 bit double can only store integers exactly for -2^53 to 2^53.
As some some arithmetics is done i think this boils down to that the numbers are compared as doubles. |
Thanks. Maybe I do not understand something but 64 bits of double can store 18446744073709551616 and 53 bits of mantissa fraction can store 9007199254740992 while 13911860366432393 is actually 2^53.6. Moreover the closest double (according to random online calculator) is 1.3911860366432394E16=13911860366432394. So if math uses 53 fraction bits It should be 13911860366432393-10→9007199254740992 -10=9007199254740982 but jq binary prints 13911860366432380. Alternatively if math converts int to double it should be 13911860366432393-10→13911860366432394-10=13911860366432384. Can you please explain jq math? |
It is like javascript maths: $ node -p '13911860366432393 - 10'
13911860366432382 |
Ok, thanks, i will read more about it. But what about this? $ echo 13911860366432393 | jq ".-10"
13911860366432380 |
If you don't do any arithmetic then jq will preserve and "passthru" big integers but once you do any operations on them they will behave as 64bit floats. Sorry i'm far from a floating point math expert so can't really help explain why the minus operation behave the way it does but i'm quite sure both 18446744073709551616 and 13911860366432393 are beyond the range for storing integers exactly so might get truncated and things might behave unexpectedly. You can use node to observe the same behaviour: $ node -e 'console.log(18446744073709551616)'
18446744073709552000
$ node -e 'console.log(13911860366432393)'
13911860366432392 Why node and jq differ in this case below can't explain. Maybe we have our own float parser or printer that behave differently when beyond the integer range? $ node -e 'console.log(13911860366432393-10)'
13911860366432382
$ jq -n '13911860366432393-10'
13911860366432380 |
jq built with $ echo 13911860366432393 | ./jq '.-10'
13911860366432382 |
@wader, yes, this is really out of my mind. Moreover Ive tested downloadable binaries and they give me 13911860366432380 in both windows and linux while I can not see failed tests in github ci. Maybe it is worth to create separate issue for this? |
Yeap i think so. I dugg a bit more and it seems like this is a change/regression since 680baef before that jq behaved the same as node (and gojq): # node
$ node -p '13911860366432393'
13911860366432392
# gojq
$ gojq -n '13911860366432393 + 0.0'
13911860366432392
# jq 1.7
$ echo 13911860366432393 | jq '.+0'
13911860366432390
# jq 680baeffeb7983e7570b5e68db07fe47f94db8c7~1
$ echo 13911860366432393 | ./jq '.+0'
13911860366432392 The breaking change seem to be the change of I'm not familiar with the decnum code at all so don't know if there is something else needed or if there is a better way? maybe this just fixes these partiuclar cases? |
diff --git a/src/decNumber/decContext.c b/src/decNumber/decContext.c
index 9f99759..9806cbd 100644
--- a/src/decNumber/decContext.c
+++ b/src/decNumber/decContext.c
@@ -97,7 +97,7 @@ decContext * decContextDefault(decContext *context, Int kind) {
#endif
break;
case DEC_INIT_DECIMAL64:
- context->digits=16; // digits
+ context->digits=17; // digits
context->emax=384; // Emax
context->emin=-383; // Emin
context->round=DEC_ROUND_HALF_EVEN; // 0.5 to nearest even
diff --git a/src/jv.c b/src/jv.c
index ada15fe..811c569 100644
--- a/src/jv.c
+++ b/src/jv.c
@@ -213,7 +213,7 @@ enum {
#define JVP_FLAGS_NUMBER_LITERAL JVP_MAKE_FLAGS(JV_KIND_NUMBER, JVP_MAKE_PFLAGS(JVP_NUMBER_DECIMAL, 1))
// the decimal precision of binary double
-#define DEC_NUBMER_DOUBLE_PRECISION (16)
+#define DEC_NUBMER_DOUBLE_PRECISION (17)
#define DEC_NUMBER_STRING_GUARD (14)
#define DEC_NUBMER_DOUBLE_EXTRA_UNITS ((DEC_NUBMER_DOUBLE_PRECISION - DECNUMDIGITS + DECDPUN - 1)/DECDPUN) I think the reason why the jq test pass with and without the patch is becuase it ends up comparing a double and decnum so the decnum will be converted and truncated to a double also. # 1.7
$ jq -n '13911860366432393-10 | ., . == 13911860366432382'
13911860366432380
true
# master with patch
$ ./jq -n '13911860366432393-10 | ., . == 13911860366432382'
13911860366432382
true |
Great job!
I think so too. Hence the test actually checks truncation instead of arithmetic. Guess it should be rewritten into multiple "single responsibility" tests. |
@leonid-s-usov any ideas? |
@wader I've spent some time refreshing my memory about this. There were several changes and fixes that got us to this point. It's true that the Wikipedia states that the decimal representation of a double precision that carries 17 digits should be sufficient to convert from the floating point to decimal and back arriving at the same floating point number. The original implementation of the decimal number support has used 17 as the conversion setting. Later @itchyny discovered and fixed an issue with the conversion, and along with that change we've also updated the double decimal representation of the number to 16 digits. The formal document analyzing the decimal64 format claims that 16 is the correct number of decimal digits, see https://speleotrove.com/decimal/dbspec.html Here we may be confusing the double precision floating point and decimal64. So, given that we want to be consistent with the double floating point math, we may want to bump up the decimal representation digit count to 17 again, though losing formal consistency with the decimal64 format (not an issue, but important to mention). I think you can proceed with your patch above, given of course that we don't see any regression, specifically with #2804 |
@wader just one thing I missed: please don't change the This means that we should not use the |
Sorry, I keep going :) So, we could argue that the observed behavior was "as designed" if we also mentioned that by using --enable-decnum one accepts that internally the numbers will be represented by an IEEE decimal64 instead of a binary64 (aka double) Please note that apart from the number of decimal digits, there's also a different exponent range between decimal and binary formats: [−383 to +384] vs [−1022 to +1023]. When fixing #2804 we haven't thought of this side effect of moving to the standard decimal64 representation. But given this thread of discussion, and also generally taking the original jq as the desired behavior, we should probably revise our |
Thanks, very appreciated!
Ok that makes sense. I was also confused and also didn't noticed this was about decimal64, not that I know much how they are different... but now based on the their names it makes much more sense :)
Yeap that was mostly to test :) now I copied out the DEC_INIT_DECIMAL64 values and changed digits to DEC_NUBMER_DOUBLE_PRECISION (17).
No worries, much approved
Ok! how come it seems to work so well with the decimal64 values?
Yes I think for least amount of confusion we should stick with binary64 behaviour. Also the JSON spec does not require it but do seem to suggest doing so. From https://datatracker.ietf.org/doc/html/rfc8259
Also added some more tests but it feels like we should probably have even more? Two related decnum things i thought about while looking into this: Currently we convert to decimal64 but won't we end up storing it in a C double that on most hardware and C implemenations will be in binary64 representation? if so, did we loose even more precision because of that? ... also makes you wonder the opposite: how would the new version behave on some hardware that uses decimal64? :) Would it be possible to implement Line 611 in 88f01a7
|
This is what the JSON spec suggests and will also be less confusing compared to other jq implementations and langauges. Related to jqlang#2939
This is what the JSON spec suggests and will also be less confusing compared to other jq implementations and langauges. Related to jqlang#2939
@wader thanks so much for your attention to the problem. As I have commented on #2949, I have caused some confusion with my last comment. The exponent range of a binary64, [-1022,1023], is in terms of base-2 binary mantissa, so we should not use those numbers to initialize a dec context. Sorry for that 🙏🏻
I had this concern as well, but eventually, I realized that it was the only way. Creating a binary floating point number involves calculating the log base 2 of the decimal number, and really, that's exactly what |
No worries! greatful that your spending time on this. I didn't know much about floating point representations and after learning more about them i understand that i know even less than i thought :) Doh that makes total sense that decnum is base-10. Maybe I should have noticed that there was no base config in the context struct.
I see 👍 |
This is what the JSON spec suggests and will also be less confusing compared to other jq implementations and langauges. Related to jqlang#2939
This is what the JSON spec suggests and will also be less confusing compared to other jq implementations and langauges. Related to jqlang#2939
This is what the JSON spec suggests and will also be less confusing compared to other jq implementations and langauges. Related to #2939
Hi! Feel free to use or extend it if any needs. |
Describe the bug
There are several different test case syntaxes which do not follow single logick.
Current behavior
As for now you can look into jq.test and find syntaxes:
[]
but somehow just no line generates successful pass for test.{x: -1}
→null
→{"x": -1}
- just wrong output. Can you see one extra space? This is false positive test.Expected behavior
Each test case must be normalized to well-documented format. To my mind it should be JSON format with schema. Example:
should be converted to
Notice that this is JSON but raw cli string.
The text was updated successfully, but these errors were encountered: