# Tests are groups of three lines: program, input, expected output
# Blank lines and lines starting with # are ignored

#
# Simple value tests to check parser. Input is irrelevant
#

true
null
true

false
null
false

null
42
null

1
null
1


-1
null
-1

# FIXME: much more number testing needed

{}
null
{}

[]
null
[]

{x: -1}
null
{"x": -1}

# The input line starts with a 0xFEFF (byte order mark) codepoint
# No, there is no reason to have a byte order mark in UTF8 text.
# But apparently people do, so jq shouldn't break on it.
.
"byte order mark"
"byte order mark"

# We test escapes by matching them against Unicode codepoints
# FIXME: more tests needed for weird unicode stuff (e.g. utf16 pairs)
"Aa\r\n\t\b\f\u03bc"
null
"Aa\u000d\u000a\u0009\u0008\u000c\u03bc"

.
"Aa\r\n\t\b\f\u03bc"
"Aa\u000d\u000a\u0009\u0008\u000c\u03bc"

"inter\("pol" + "ation")"
null
"interpolation"

@text,@json,([1,.] | (@csv, @tsv)),@html,@uri,@sh,@base64
"<>&'\"\t"
"<>&'\"\t"
"\"<>&'\\\"\\t\""
"1,\"<>&'\"\"\t\""
"1\t<>&'\"\\t"
"&lt;&gt;&amp;&apos;&quot;\t"
"%3C%3E%26'%22%09"
"'<>&'\\''\"\t'"
"PD4mJyIJ"

# regression test for #436
@base64
"foóbar\n"
"Zm/Ds2Jhcgo="

@uri
"\u03bc"
"%CE%BC"

@html "<b>\(.)</b>"
"<script>hax</script>"
"<b>&lt;script&gt;hax&lt;/script&gt;</b>"

[.[]|tojson|fromjson]
["foo", 1, ["a", 1, "b", 2, {"foo":"bar"}]]
["foo",1,["a",1,"b",2,{"foo":"bar"}]]

#
# Dictionary construction syntax
#

{a: 1}
null
{"a":1}

{a,b,(.d):.a,e:.b}
{"a":1, "b":2, "c":3, "d":"c"}
{"a":1, "b":2, "c":1, "e":2}

{"a",b,"a$\(1+1)"}
{"a":1, "b":2, "c":3, "a$2":4}
{"a":1, "b":2, "a$2":4}

#
# Field access, piping
#

.foo
{"foo": 42, "bar": 43}
42

.foo | .bar
{"foo": {"bar": 42}, "bar": "badvalue"}
42

.foo.bar
{"foo": {"bar": 42}, "bar": "badvalue"}
42

.foo_bar
{"foo_bar": 2}
2

.["foo"].bar
{"foo": {"bar": 42}, "bar": "badvalue"}
42

."foo"."bar"
{"foo": {"bar": 20}}
20

[.[]|.foo?]
[1,[2],{"foo":3,"bar":4},{},{"foo":5}]
[3,null,5]

[.[]|.foo?.bar?]
[1,[2],[],{"foo":3},{"foo":{"bar":4}},{}]
[4,null]

[..]
[1,[[2]],{ "a":[1]}]
[[1,[[2]],{"a":[1]}],1,[[2]],[2],2,{"a":[1]},[1],1]

[.[]|.[]?]
[1,null,[],[1,[2,[[3]]]],[{}],[{"a":[1,[2]]}]]
[1,[2,[[3]]],{},{"a":[1,[2]]}]

[.[]|.[1:3]?]
[1,null,true,false,"abcdef",{},{"a":1,"b":2},[],[1,2,3,4,5],[1,2]]
[null,"bc",[],[2,3],[2]]

#
# Negative array indices
#

try (.foo[-1] = 0) catch .
null
"Out of bounds negative array index"

try (.foo[-2] = 0) catch .
null
"Out of bounds negative array index"

.[-1] = 5
[0,1,2]
[0,1,5]

.[-2] = 5
[0,1,2]
[0,5,2]

#
# Multiple outputs, iteration
#

.[]
[1,2,3]
1
2
3

1,1
[]
1
1

1,.
[]
1
[]

[.]
[2]
[[2]]

[[2]]
[3]
[[2]]

[{}]
[2]
[{}]

[.[]]
["a"]
["a"]

[(.,1),((.,.[]),(2,3))]
["a","b"]
[["a","b"],1,["a","b"],"a","b",2,3]

[([5,5][]),.,.[]]
[1,2,3]
[5,5,[1,2,3],1,2,3]

{x: (1,2)},{x:3} | .x
null
1
2
3

.[-2]
[1,2,3]
2

[range(0;10)]
null
[0,1,2,3,4,5,6,7,8,9]

[range(0,1;3,4)]
null
[0,1,2, 0,1,2,3, 1,2, 1,2,3]

[range(0;10;3)]
null
[0,3,6,9]

[range(0;10;-1)]
null
[]

[range(0;-5;-1)]
null
[0,-1,-2,-3,-4]

[range(0,1;4,5;1,2)]
null
[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]

[while(.<100; .*2)]
1
[1,2,4,8,16,32,64]

[(label $here | .[] | if .>1 then break $here else . end), "hi!"]
[0,1,2]
[0,1,"hi!"]

[(label $here | .[] | if .>1 then break $here else . end), "hi!"]
[0,2,1]
[0,"hi!"]

%%FAIL
. as $foo | break $foo
jq: error: *label-foo/0 is not defined at <top-level>, line 1:

[.[]|[.,1]|until(.[0] < 1; [.[0] - 1, .[1] * .[0]])|.[1]]
[1,2,3,4,5]
[1,2,6,24,120]

[label $out | foreach .[] as $item ([3, null]; if .[0] < 1 then break $out else [.[0] -1, $item] end; .[1])]
[11,22,33,44,55,66,77,88,99]
[11,22,33]

[foreach range(5) as $item (0; $item)]
null
[0,1,2,3,4]

[foreach .[] as [$i, $j] (0; . + $i - $j)]
[[2,1], [5,3], [6,4]]
[1,3,5]

[foreach .[] as {a:$a} (0; . + $a; -.)]
[{"a":1}, {"b":2}, {"a":3, "b":4}]
[-1, -1, -4]

[limit(3; .[])]
[11,22,33,44,55,66,77,88,99]
[11,22,33]

[first(range(.)), last(range(.)), nth(0; range(.)), nth(5; range(.)), try nth(-1; range(.)) catch .]
10
[0,9,0,5,"nth doesn't support negative indices"]

#
# Check that various builtins evalute all arguments where appropriate,
# doing cartesian products where appropriate.
#

# Check that limit does work for each value produced by n!
[limit(5,7; range(9))]
null
[0,1,2,3,4,0,1,2,3,4,5,6]

# Same check for nth
[nth(5,7; range(9;0;-1))]
null
[4,2]

# Same check for range/3
[range(0,1,2;4,3,2;2,3)]
null
[0,2,0,3,0,2,0,0,0,1,3,1,1,1,1,1,2,2,2,2]

# Same check for range/1
[range(3,5)]
null
[0,1,2,0,1,2,3,4]

# Same check for index/1, rindex/1, indices/1
[(index(",","|"), rindex(",","|")), indices(",","|")]
"a,b|c,d,e||f,g,h,|,|,i,j"
[1,3,22,19,[1,5,7,12,14,16,18,20,22],[3,9,10,17,19]]

# Same check for join/1
join(",","/")
["a","b","c","d"]
"a,b,c,d"
"a/b/c/d"

[.[]|join("a")]
[[],[""],["",""],["","",""]]
["","","a","aa"]

# Same check for flatten/1
flatten(3,2,1)
[0, [1], [[2]], [[[3]]]]
[0,1,2,3]
[0,1,2,[3]]
[0,1,[2],[[3]]]


#
# Slices
#

[.[3:2], .[-5:4], .[:-2], .[-2:], .[3:3][1:], .[10:]]
[0,1,2,3,4,5,6]
[[], [2,3], [0,1,2,3,4], [5,6], [], []]

[.[3:2], .[-5:4], .[:-2], .[-2:], .[3:3][1:], .[10:]]
"abcdefghi"
["","","abcdefg","hi","",""]

del(.[2:4],.[0],.[-2:])
[0,1,2,3,4,5,6,7]
[1,4,5]

.[2:4] = ([], ["a","b"], ["a","b","c"])
[0,1,2,3,4,5,6,7]
[0,1,4,5,6,7]
[0,1,"a","b",4,5,6,7]
[0,1,"a","b","c",4,5,6,7]


#
# Variables
#

1 as $x | 2 as $y | [$x,$y,$x]
null
[1,2,1]

[1,2,3][] as $x | [[4,5,6,7][$x]]
null
[5]
[6]
[7]

42 as $x | . | . | . + 432 | $x + 1
34324
43

1 as $x | [$x,$x,$x as $x | $x]
null
[1,1,1]

[1, {c:3, d:4}] as [$a, {c:$b, b:$c}] | $a, $b, $c
null
1
3
null

. as {as: $kw, "str": $str, ("e"+"x"+"p"): $exp} | [$kw, $str, $exp]
{"as": 1, "str": 2, "exp": 3}
[1, 2, 3]

.[] as [$a, $b] | [$b, $a]
[[1], [1, 2, 3]]
[null, 1]
[2, 1]

. as $i | . as [$i] | $i
[0]
0

. as [$i] | . as $i | $i
[0]
[0]

%%FAIL
. as [] | null
jq: error: syntax error, unexpected ']', expecting '$' or '[' or '{' (Unix shell quoting issues?) at <top-level>, line 1:

%%FAIL
. as {} | null
jq: error: syntax error, unexpected '}' (Unix shell quoting issues?) at <top-level>, line 1:

# [.,(.[] | {x:.},.),.,.[]]

#
# Builtin functions
#

1+1
null
2

1+1
"wtasdf"
2.0

2-1
null
1

2-(-1)
null
3

1e+0+0.001e3
"I wonder what this will be?"
20e-1

.+4
15
19.0

.+null
{"a":42}
{"a":42}

null+.
null
null

.a+.b
{"a":42}
42

[1,2,3] + [.]
null
[1,2,3,null]

{"a":1} + {"b":2} + {"c":3}
"asdfasdf"
{"a":1, "b":2, "c":3}

"asdf" + "jkl;" + . + . + .
"some string"
"asdfjkl;some stringsome stringsome string"

"\u0000\u0020\u0000" + .
"\u0000\u0020\u0000"
"\u0000 \u0000\u0000 \u0000"

42 - .
11
31

[1,2,3,4,1] - [.,3]
1
[2,4]

[10 * 20, 20 / .]
4
[200, 5]

1 + 2 * 2 + 10 / 2
null
10

[16 / 4 / 2, 16 / 4 * 2, 16 - 4 - 2, 16 - 4 + 2]
null
[2, 8, 10, 14]

25 % 7
null
4

49732 % 472
null
172

1 + tonumber + ("10" | tonumber)
4
15

[{"a":42},.object,10,.num,false,true,null,"b",[1,4]] | .[] as $x | [$x == .[]]
{"object": {"a":42}, "num":10.0}
[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 ]

[.[] | length]
[[], {}, [1,2], {"a":42}, "asdf", "\u03bc"]
[0, 0, 2, 1, 4, 1]

map(keys)
[{}, {"abcd":1,"abc":2,"abcde":3}, {"x":1, "z": 3, "y":2}]
[[], ["abc","abcd","abcde"], ["x","y","z"]]

[1,2,empty,3,empty,4]
null
[1,2,3,4]

map(add)
[[], [1,2,3], ["a","b","c"], [[3],[4,5],[6]], [{"a":1}, {"b":2}, {"a":3}]]
[null, 6, "abc", [3,4,5,6], {"a":3, "b": 2}]

map_values(.+1)
[0,1,2]
[1,2,3]

#
# User-defined functions
# Oh god.
#

def f: . + 1; def g: def g: . + 100; f | g | f; (f | g), g
3.0
106.0
105.0

def f: (1000,2000); f
123412345
1000
2000

def f(a;b;c;d;e;f): [a+1,b,c,d,e,f]; f(.[0];.[1];.[0];.[0];.[0];.[0])
[1,2]
[2,2,1,1,1,1]

# Test precedence of 'def' vs '|'
def a: 0; . | a
null
0

# Many arguments
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])
[0,1,2,3,4,5,6,7,8,9]
[9,8,7,6,5,4,3,2,1,0]

([1,2] + [4,5])
[1,2,3]
[1,2,4,5]

true
[1]
true

null,1,null
"hello"
null
1
null

[1,2,3]
[5,6]
[1,2,3]

[.[]|floor]
[-1.1,1.1,1.9]
[-2, 1, 1]

[.[]|sqrt]
[4,9]
[2,3]

(add / length) as $m | map((. - $m) as $d | $d * $d) | add / length | sqrt
[2,4,4,4,5,5,7,9]
2

# Should write a test that calls the -lm function from C (or bc(1)) to
# check that they match the corresponding jq functions.  However,
# there's so little template code standing between that it suffices to
# test a handful of these.  The results were checked by eye against
# bc(1).
atan * 4 * 1000000|floor / 1000000
1
3.141592

[(3.141592 / 2) * (range(0;20) / 20)|cos * 1000000|floor / 1000000]
null
[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]

[(3.141592 / 2) * (range(0;20) / 20)|sin * 1000000|floor / 1000000]
null
[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]


def f(x): x | x; f([.], . + [42])
[1,2,3]
[[[1,2,3]]]
[[1,2,3],42]
[[1,2,3,42]]
[1,2,3,42,42]

# test multiple function arities and redefinition
def f: .+1; def g: f; def f: .+100; def f(a):a+.+11; [(g|f(20)), f]
1
[33,101]

# test closures and lexical scoping
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)
"more testing"
[1,100,2100.0,100,2100.0]

# test def f($a) syntax
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)
[1,2,3]
true

# test backtracking through function calls and returns
# this test is *evil*
[[20,10][1,0] as $x | def f: (100,200) as $y | def g: [$x + $y, .]; . + $x | g; f[0] | [f][0][1] | f]
999999999
[[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]]

# test recursion
def fac: if . == 1 then 1 else . * (. - 1 | fac) end; [.[] | fac]
[1,2,3,4]
[1,2,6,24]

# test stack overflow and reallocation
# this test is disabled for now, it takes a realllllly long time.
# def f: if length > 1000 then . else .+[1]|f end; f | length
# []
# 1001

reduce .[] as $x (0; . + $x)
[1,2,4]
7

reduce .[] as [$i, {j:$j}] (0; . + $i - $j)
[[2,{"j":1}], [5,{"j":3}], [6,{"j":4}]]
5

reduce [[1,2,10], [3,4,10]][] as [$i,$j] (0; . + $i * $j)
null
14

. as $dot|any($dot[];not)
[1,2,3,4,true,false,1,2,3,4,5]
true

. as $dot|any($dot[];not)
[1,2,3,4,true]
false

. as $dot|all($dot[];.)
[1,2,3,4,true,false,1,2,3,4,5]
false

. as $dot|all($dot[];.)
[1,2,3,4,true]
true

#
# Paths
#

path(.foo[0,1])
null
["foo", 0]
["foo", 1]

path(.[] | select(.>3))
[1,5,3]
[1]

path(.)
42
[]

try path(.a | map(select(.b == 0))) catch .
{"a":[{"b":0}]}
"Invalid path expression with result [{\"b\":0}]"

try path(.a | map(select(.b == 0)) | .[0]) catch .
{"a":[{"b":0}]}
"Invalid path expression near attempt to access element 0 of [{\"b\":0}]"

try path(.a | map(select(.b == 0)) | .c) catch .
{"a":[{"b":0}]}
"Invalid path expression near attempt to access element \"c\" of [{\"b\":0}]"

try path(.a | map(select(.b == 0)) | .[]) catch .
{"a":[{"b":0}]}
"Invalid path expression near attempt to iterate through [{\"b\":0}]"

path(.a[path(.b)[0]])
{"a":{"b":0}}
["a","b"]

[paths]
[1,[[],{"a":2}]]
[[0],[1],[1,0],[1,1],[1,1,"a"]]

[leaf_paths]
[1,[[],{"a":2}]]
[[0],[1,1,"a"]]

["foo",1] as $p | getpath($p), setpath($p; 20), delpaths([$p])
{"bar": 42, "foo": ["a", "b", "c", "d"]}
"b"
{"bar": 42, "foo": ["a", 20, "c", "d"]}
{"bar": 42, "foo": ["a", "c", "d"]}

map(getpath([2])), map(setpath([2]; 42)), map(delpaths([[2]]))
[[0], [0,1], [0,1,2]]
[null, null, 2]
[[0,null,42], [0,1,42], [0,1,42]]
[[0], [0,1], [0,1]]

map(delpaths([[0,"foo"]]))
[[{"foo":2, "x":1}], [{"bar":2}]]
[[{"x":1}], [{"bar":2}]]

["foo",1] as $p | getpath($p), setpath($p; 20), delpaths([$p])
{"bar":false}
null
{"bar":false, "foo": [null, 20]}
{"bar":false}

delpaths([[-200]])
[1,2,3]
[1,2,3]

try delpaths(0) catch .
{}
"Paths must be specified as an array"

del(.), del(empty), del((.foo,.bar,.baz) | .[2,3,0]), del(.foo[0], .bar[0], .foo, .baz.bar[0].x)
{"foo": [0,1,2,3,4], "bar": [0,1]}
null
{"foo": [0,1,2,3,4], "bar": [0,1]}
{"foo": [1,4], "bar": [1]}
{"bar": [1]}

#
# Assignment
#
.message = "goodbye"
{"message": "hello"}
{"message": "goodbye"}

.foo = .bar
{"bar":42}
{"foo":42, "bar":42}

.foo |= .+1
{"foo": 42}
{"foo": 43}

.[] += 2, .[] *= 2, .[] -= 2, .[] /= 2, .[] %=2
[1,3,5]
[3,5,7]
[2,6,10]
[-1,1,3]
[0.5, 1.5, 2.5]
[1,1,1]

[.[] % 7]
[-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7]
[0,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,0]

.foo += .foo
{"foo":2}
{"foo":4}

.[0].a |= {"old":., "new":(.+1)}
[{"a":1,"b":2}]
[{"a":{"old":1, "new":2},"b":2}]

def inc(x): x |= .+1; inc(.[].a)
[{"a":1,"b":2},{"a":2,"b":4},{"a":7,"b":8}]
[{"a":2,"b":2},{"a":3,"b":4},{"a":8,"b":8}]

.[2][3] = 1
[4]
[4, null, [null, null, null, 1]]

.foo[2].bar = 1
{"foo":[11], "bar":42}
{"foo":[11,null,{"bar":1}], "bar":42}

try ((map(select(.a == 1))[].b) = 10) catch .
[{"a":0},{"a":1}]
"Invalid path expression near attempt to iterate through [{\"a\":1}]"

try ((map(select(.a == 1))[].a) |= .+1) catch .
[{"a":0},{"a":1}]
"Invalid path expression near attempt to iterate through [{\"a\":1}]"

def x: .[1,2]; x=10
[0,1,2]
[0,10,10]

try (def x: reverse; x=10) catch .
[0,1,2]
"Invalid path expression with result [2,1,0]"

#
# Conditionals
#

[.[] | if .foo then "yep" else "nope" end]
[{"foo":0},{"foo":1},{"foo":[]},{"foo":true},{"foo":false},{"foo":null},{"foo":"foo"},{}]
["yep","yep","yep","yep","nope","nope","yep","nope"]

[.[] | if .baz then "strange" elif .foo then "yep" else "nope" end]
[{"foo":0},{"foo":1},{"foo":[]},{"foo":true},{"foo":false},{"foo":null},{"foo":"foo"},{}]
["yep","yep","yep","yep","nope","nope","yep","nope"]


# FIXME: define/test behaviour of 'if (.foo,.bar) then A else B end'

[.[] | [.foo[] // .bar]]
[{"foo":[1,2], "bar": 42}, {"foo":[1], "bar": null}, {"foo":[null,false,3], "bar": 18}, {"foo":[], "bar":42}, {"foo": [null,false,null], "bar": 41}]
[[1,2], [1], [3], [42], [41]]

.[] //= .[0]
["hello",true,false,[false],null]
["hello",true,"hello",[false],"hello"]

.[] | [.[0] and .[1], .[0] or .[1]]
[[true,[]], [false,1], [42,null], [null,false]]
[true,true]
[false,true]
[false,true]
[false,false]

[.[] | not]
[1,0,false,null,true,"hello"]
[false,false,true,true,false,false]

# Check numeric comparison binops
[10 > 0, 10 > 10, 10 > 20, 10 < 0, 10 < 10, 10 < 20]
{}
[true,false,false,false,false,true]

[10 >= 0, 10 >= 10, 10 >= 20, 10 <= 0, 10 <= 10, 10 <= 20]
{}
[true,true,false,false,true,true]

# And some in/equality tests
[ 10 == 10, 10 != 10, 10 != 11, 10 == 11]
{}
[true,false,true,false]

["hello" == "hello", "hello" != "hello", "hello" == "world", "hello" != "world" ]
{}
[true,false,false,true]

[[1,2,3] == [1,2,3], [1,2,3] != [1,2,3], [1,2,3] == [4,5,6], [1,2,3] != [4,5,6]]
{}
[true,false,false,true]

[{"foo":42} == {"foo":42},{"foo":42} != {"foo":42}, {"foo":42} != {"bar":42}, {"foo":42} == {"bar":42}]
{}
[true,false,true,false]

# ugly complicated thing
[{"foo":[1,2,{"bar":18},"world"]} == {"foo":[1,2,{"bar":18},"world"]},{"foo":[1,2,{"bar":18},"world"]} == {"foo":[1,2,{"bar":19},"world"]}]
{}
[true,false]

# containment operator
[("foo" | contains("foo")), ("foobar" | contains("foo")), ("foo" | contains("foobar"))]
{}
[true, true, false]

# Try/catch and general `?` operator
[.[]|try if . == 0 then error("foo") elif . == 1 then .a elif . == 2 then empty else . end catch .]
[0,1,2,3]
["foo","Cannot index number with string \"a\"",3]

[.[]|(.a, .a)?]
[null,true,{"a":1}]
[null,null,1,1]

[[.[]|[.a,.a]]?]
[null,true,{"a":1}]
[]

try error("\($__loc__)") catch .
null
"{\"file\":\"<top-level>\",\"line\":1}"

# string operations
[.[]|startswith("foo")]
["fo", "foo", "barfoo", "foobar", "barfoob"]
[false, true, false, true, false]

[.[]|endswith("foo")]
["fo", "foo", "barfoo", "foobar", "barfoob"]
[false, true, true, false, false]

[.[] | split(", ")]
["a,b, c, d, e,f",", a,b, c, d, e,f, "]
[["a,b","c","d","e,f"],["","a,b","c","d","e,f",""]]

split("")
"abc"
["a","b","c"]

[.[]|ltrimstr("foo")]
["fo", "foo", "barfoo", "foobar", "afoo"]
["fo","","barfoo","bar","afoo"]

[.[]|rtrimstr("foo")]
["fo", "foo", "barfoo", "foobar", "foob"]
["fo","","bar","foobar","foob"]

[(index(","), rindex(",")), indices(",")]
"a,bc,def,ghij,klmno"
[1,13,[1,4,8,13]]

indices(1)
[0,1,1,2,3,4,1,5]
[1,2,6]

indices([1,2])
[0,1,2,3,1,4,2,5,1,2,6,7]
[1,8]

indices([1,2])
[1]
[]

indices(", ")
"a,b, cd,e, fgh, ijkl"
[3,9,14]

[.[]|split(",")]
["a, bc, def, ghij, jklmn, a,b, c,d, e,f", "a,b,c,d, e,f,g,h"]
[["a"," bc"," def"," ghij"," jklmn"," a","b"," c","d"," e","f"],["a","b","c","d"," e","f","g","h"]]

[.[]|split(", ")]
["a, bc, def, ghij, jklmn, a,b, c,d, e,f", "a,b,c,d, e,f,g,h"]
[["a","bc","def","ghij","jklmn","a,b","c,d","e,f"],["a,b,c,d","e,f,g,h"]]

[.[] * 3]
["a", "ab", "abc"]
["aaa", "ababab", "abcabcabc"]

[.[] / ","]
["a, bc, def, ghij, jklmn, a,b, c,d, e,f", "a,b,c,d, e,f,g,h"]
[["a"," bc"," def"," ghij"," jklmn"," a","b"," c","d"," e","f"],["a","b","c","d"," e","f","g","h"]]

[.[] / ", "]
["a, bc, def, ghij, jklmn, a,b, c,d, e,f", "a,b,c,d, e,f,g,h"]
[["a","bc","def","ghij","jklmn","a,b","c,d","e,f"],["a,b,c,d","e,f,g,h"]]

map(.[1] as $needle | .[0] | contains($needle))
[[[],[]], [[1,2,3], [1,2]], [[1,2,3], [3,1]], [[1,2,3], [4]], [[1,2,3], [1,4]]]
[true, true, true, false, false]

map(.[1] as $needle | .[0] | contains($needle))
[[["foobar", "foobaz"], ["baz", "bar"]], [["foobar", "foobaz"], ["foo"]], [["foobar", "foobaz"], ["blap"]]]
[true, true, false]

[({foo: 12, bar:13} | contains({foo: 12})), ({foo: 12} | contains({})), ({foo: 12, bar:13} | contains({baz:14}))]
{}
[true, true, false]

{foo: {baz: 12, blap: {bar: 13}}, bar: 14} | contains({bar: 14, foo: {blap: {}}})
{}
true

{foo: {baz: 12, blap: {bar: 13}}, bar: 14} | contains({bar: 14, foo: {blap: {bar: 14}}})
{}
false

sort
[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]
[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}]

(sort_by(.b) | sort_by(.a)), sort_by(.a, .b), sort_by(.b, .c), group_by(.b), group_by(.a + .b - .c == 2)
[{"a": 1, "b": 4, "c": 14}, {"a": 4, "b": 1, "c": 3}, {"a": 1, "b": 4, "c": 3}, {"a": 0, "b": 2, "c": 43}]
[{"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}]]

unique
[1,2,5,3,5,3,1,3]
[1,2,3,5]

unique
[]
[]

[min, max, min_by(.[1]), max_by(.[1]), min_by(.[2]), max_by(.[2])]
[[4,2,"a"],[3,1,"a"],[2,4,"a"],[1,3,"a"]]
[[1,3,"a"],[4,2,"a"],[3,1,"a"],[2,4,"a"],[4,2,"a"],[1,3,"a"]]

[min,max,min_by(.),max_by(.)]
[]
[null,null,null,null]

.foo[.baz]
{"foo":{"bar":4},"baz":"bar"}
4

.[] | .error = "no, it's OK"
[{"error":true}]
{"error": "no, it's OK"}

[{a:1}] | .[] | .a=999
null
{"a": 999}

to_entries
{"a": 1, "b": 2}
[{"key":"a", "value":1}, {"key":"b", "value":2}]

from_entries
[{"key":"a", "value":1}, {"Key":"b", "value":2}]
{"a": 1, "b": 2}

from_entries
[{"key":"a", "Value":1}, {"Name":"b", "value":2}]
{"a": 1, "b": 2}

with_entries(.key |= "KEY_" + .)
{"a": 1, "b": 2}
{"KEY_a": 1, "KEY_b": 2}

map(has("foo"))
[{"foo": 42}, {}]
[true, false]

map(has(2))
[[0,1], ["a","b","c"]]
[false, true]

keys
[42,3,35]
[0,1,2]

[][.]
1000000000000000000
null

map([1,2][0:.])
[-1, 1, 2, 3, 1000000000000000000]
[[1], [1], [1,2], [1,2], [1,2]]

# Test recursive object merge

{"k": {"a": 1, "b": 2}} * .
{"k": {"a": 0,"c": 3}}
{"k": {"a": 0, "b": 2, "c": 3}}

{"k": {"a": 1, "b": 2}, "hello": {"x": 1}} * .
{"k": {"a": 0,"c": 3}, "hello": 1}
{"k": {"a": 0, "b": 2, "c": 3}, "hello": 1}

{"k": {"a": 1, "b": 2}, "hello": 1} * .
{"k": {"a": 0,"c": 3}, "hello": {"x": 1}}
{"k": {"a": 0, "b": 2, "c": 3}, "hello": {"x": 1}}

{"a": {"b": 1}, "c": {"d": 2}, "e": 5} * .
{"a": {"b": 2}, "c": {"d": 3, "f": 9}}
{"a": {"b": 2}, "c": {"d": 3, "f": 9}, "e": 5}

[.[]|arrays]
[1,2,"foo",[],[3,[]],{},true,false,null]
[[],[3,[]]]

[.[]|objects]
[1,2,"foo",[],[3,[]],{},true,false,null]
[{}]

[.[]|iterables]
[1,2,"foo",[],[3,[]],{},true,false,null]
[[],[3,[]],{}]

[.[]|scalars]
[1,2,"foo",[],[3,[]],{},true,false,null]
[1,2,"foo",true,false,null]

[.[]|values]
[1,2,"foo",[],[3,[]],{},true,false,null]
[1,2,"foo",[],[3,[]],{},true,false]

[.[]|booleans]
[1,2,"foo",[],[3,[]],{},true,false,null]
[true,false]

[.[]|nulls]
[1,2,"foo",[],[3,[]],{},true,false,null]
[null]

flatten
[0, [1], [[2]], [[[3]]]]
[0, 1, 2, 3]

flatten(0)
[0, [1], [[2]], [[[3]]]]
[0, [1], [[2]], [[[3]]]]

flatten(2)
[0, [1], [[2]], [[[3]]]]
[0, 1, 2, [3]]

flatten(2)
[0, [1, [2]], [1, [[3], 2]]]
[0, 1, 2, 1, [3], 2]

try flatten(-1) catch .
[0, [1], [[2]], [[[3]]]]
"flatten depth must not be negative"

transpose
[[1], [2,3]]
[[1,2],[null,3]]

ascii_upcase
"useful but not for é"
"USEFUL BUT NOT FOR é"

bsearch(4)
[1,2,3]
-4

[strptime("%Y-%m-%dT%H:%M:%SZ")|(.,mktime)]
"2015-03-05T23:51:47Z"
[[2015,2,5,23,51,47,4,63],1425599507]

strftime("%Y-%m-%dT%H:%M:%SZ")
[2015,2,5,23,51,47,4,63]
"2015-03-05T23:51:47Z"

strftime("%A, %B %e, %Y")
1435677542.822351
"Tuesday, June 30, 2015"

gmtime
1425599507
[2015,2,5,23,51,47,4,63]

# module system
import "a" as foo; import "b" as bar; def fooa: foo::a; [fooa, bar::a, bar::b, foo::a]
null
["a","b","c","a"]

import "c" as foo; [foo::a, foo::c]
null
[0,"acmehbah"]

include "c"; [a, c]
null
[0,"acmehbah"]

%%FAIL
module (.+1); 0
jq: error: Module metadata must be constant at <top-level>, line 1:

%%FAIL
include "a" (.+1); 0
jq: error: Module metadata must be constant at <top-level>, line 1:

%%FAIL
include "a" []; 0
jq: error: Module metadata must be an object at <top-level>, line 1:

%%FAIL
include "\ "; 0
jq: error: Invalid escape at line 1, column 4 (while parsing '"\ "') at <top-level>, line 1:

%%FAIL
include "\(a)"; 0
jq: error: Import path must be constant at <top-level>, line 1:

modulemeta
"c"
{"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"}]}

%%FAIL IGNORE MSG
import "syntaxerror" as e; .
jq: error: syntax error, unexpected ';', expecting $end (Unix shell quoting issues?) at /home/nico/ws/jq/tests/modules/syntaxerror/syntaxerror.jq, line 1:

%%FAIL
%::wat
jq: error: syntax error, unexpected '%', expecting $end (Unix shell quoting issues?) at <top-level>, line 1:

import "test_bind_order" as check; check::check
null
true

try -. catch .
"very-long-string"
"string (\"very-long-...) cannot be negated"

try join(",") catch .
["1",2]
"string (\",\") and number (2) cannot be added"

try join(",") catch .
["1","2",{"a":{"b":{"c":33}}}]
"string (\",\") and object ({\"a\":{\"b\":{...) cannot be added"

{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}
null
{"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}

try (1/.) catch .
0
"number (1) and number (0) cannot be divided because the divisor is zero"

try (1%.) catch .
0
"number (1) and number (0) cannot be divided (remainder) because the divisor is zero"

%%FAIL
1/0
jq: error: Division by zero? at <top-level>, line 1:

# Basic numbers tests: integers, powers of two
[range(-52;52;1)] as $powers | [$powers[]|pow(2;.)|log2] == $powers
null
true

[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)
null

%%FAIL
}
jq: error: syntax error, unexpected INVALID_CHARACTER, expecting $end (Unix shell quoting issues?) at <top-level>, line 1:

(.[{}] = 0)?
null