[
  {
     "given": {
         "store": {
             "book": [
                 {
                     "category": "reference",
                     "author": "Nigel Rees",
                     "title": "Sayings of the Century",
                     "price": 8.95
                 },
                 {
                     "category": "fiction",
                     "author": "Evelyn Waugh",
                     "title": "Sword of Honour",
                     "price": 12.99
                 },
                 {
                     "category": "fiction",
                     "author": "Herman Melville",
                     "title": "Moby Dick",
                     "isbn": "0-553-21311-3",
                     "price": 8.99
                 },
                 {
                     "category": "fiction",
                     "author": "J. R. R. Tolkien",
                     "title": "The Lord of the Rings",
                     "isbn": "0-395-19395-8",
                     "price": 22.99
                 }
             ],
             "bicycle": {
                 "color": "red",
                 "price": 19.95
             }
         }
     },
     "cases": [
       {
         "comment" : "length",
         "expression": "length($.store.book[*])",
         "result": [4]
       },
       {
         "comment" : "keys",
         "expression": "keys($.store.book[0])[*]",
         "result": ["author","category","price","title"]
       },
       {
         "comment" : "sum",
         "expression": "sum($.store.book[*].price)",
         "result": [53.92]
       },
       {
         "comment" : "sum in filter",
         "expression": "$.store.book[?(@.price > sum($.store.book[*].price) / length($.store.book[*]))].title",
         "result": ["The Lord of the Rings"]
       },
       {
         "comment" : "avg",
         "expression": "avg($.store.book[*].price)",
         "result": [13.48]
       },
       {
         "comment" : "avg in filter",
         "expression": "$.store.book[?(@.price > avg($.store.book[*].price))].title",
         "result": ["The Lord of the Rings"]
       },
       {
         "comment" : "prod",
         "expression": "prod($.store.book[*].price)",
         "result": [24028.731766049998]
       },
       {
         "comment" : "min",
         "expression": "min($.store.book[*].price)",
         "result": [8.95]
       },
       {
         "comment" : "max",
         "expression": "max($.store.book[*].price)",
         "result": [22.99]
       },
       {
         "comment" : "max in filter",
         "expression": "$.store.book[?(@.price < max($.store.book[*].price))].title",
         "result": ["Sayings of the Century","Sword of Honour","Moby Dick"]
       }
     ]
  },
  {
     "given": {
             "books":
             [
                 {
                     "title" : "A Wild Sheep Chase",
                     "author" : "Haruki Murakami",
                     "price" : 22.72
                 },
                 {
                     "title" : "The Comedians",
                     "author" : "Graham Greene",
                     "price" : 21.99
                 },
                 {
                     "title" : "The Night Watch",
                     "author" : "Phillips, David Atlee"
                 }
             ]
           },
     "cases": [
       {
         "comment" : "All titles that don't have a price",
         "expression": "$.books[?(!contains(keys(@),'price'))].title",
         "result": ["The Night Watch"]
       }
     ]
  },
   {
     "source": "JMESPath test suite",
     "given":
     {
       "foo": -1,
       "zero": 0,
       "numbers": [-1, 3, 4, 5],
       "array": [-1, 3, 4, 5, "a", "100"],
       "strings": ["a", "b", "c"],
       "decimals": [1.01, 1.2, -1.5],
       "str": "Str",
       "false": false,
       "empty_list": [],
       "empty_hash": {},
       "objects": {"foo": "bar", "bar": "baz"},
       "null_key": null
     },
     "cases": [
       {
         "expression": "ceil(1.2)",
         "result": [2]
       },
       {
         "expression": "ceil(1.2*2)",
         "result": [3]
       },
       {
         "expression": "ceil($.decimals[0])",
         "result": [2]
       },
       {
         "expression": "ceil($.decimals[1])",
         "result": [2]
       },
       {
         "expression": "to_number('1.0')",
         "result": [1.0]
       },
       {
         "expression": "ceil($.decimals[2])",
         "result": [-1]
       },
       {
         "expression": "ceil('string')",
         "result": []
       },
       {
         "expression": "abs($.foo)",
         "result": [1]
       },
       {
         "expression": "abs($.str)",
         "result": []
       },
       {
         "expression": "abs($.array[1])",
         "result": [3]
       },
       {
         "expression": "abs(false)",
         "result": []
       },
       {
         "expression": "abs(-24)",
         "result": [24]
       },
       {
         "expression": "abs(1, 2)",
         "error": "invalid arity"
       },
       {
         "expression": "abs()",
         "error": "invalid arity"
       },
       {
         "expression": "unknown_function(1, 2)",
         "error": "unknown-function"
       },
       {
         "expression": "avg($.numbers)",
         "result": [2.75]
       },
       {
         "expression": "avg($.array)",
         "result": []
       },
       {
         "expression": "avg('abc')",
         "result": []
       },
       {
         "expression": "avg($.foo)",
         "result": []
         //"error": "invalid-type"
       },
       {
         "expression": "avg(@)",
         "result": []
         //"error": "invalid-type"
       },
       {
         "expression": "avg($.strings)",
         "result": []
         //"error": "invalid-type"
       },
       {
         "expression": "avg($.empty_list)",
         "result": [null]
       },
       {
         "expression": "ceil(1.2)",
         "result": [2]
       },
       {
         "expression": "ceil($.decimals[0])",
         "result": [2]
       },
       {
         "expression": "ceil($.decimals[1])",
         "result": [2]
       },
       {
         "expression": "ceil($.decimals[2])",
         "result": [-1]
       },
       {
         "expression": "ceil('string')",
         "result": []
         //"error": "invalid-type"
       },
       {
         "expression": "contains('abc', 'a')",
         "result": [true]
       },
       {
         "expression": "contains('abc', 'd')",
         "result": [false]
       },
       {
         "expression": "contains(false, 'd')",
         "result" : [] 
         //"error": "invalid-type"
       },
       {
         "expression": "contains($.strings, 'a')",
         "result": [true]
       },
       {
         "expression": "contains($.decimals, 1.2)",
         "result": [true]
       },
       {
         "expression": "contains($.decimals, false)",
         "result": [false]
       },
       {
         "expression": "ends_with($.str, 'r')",
         "result": [true]
       },
       {
         "expression": "ends_with($.str, 'tr')",
         "result": [true]
       },
       {
         "expression": "ends_with($.str, 'Str')",
         "result": [true]
       },
       {
         "expression": "ends_with($.str, 'SStr')",
         "result": [false]
       },
       {
         "expression": "ends_with($.str, 'foo')",
         "result": [false]
       },
       {
         "expression": "ends_with($.str, 0)",
         "result": []
         //"error": "invalid-type"
       },
       {
         "expression": "floor(1.2)",
         "result" : [1]
       },
       {
         "expression": "floor('string')",
         "result" : []
         //"error": "invalid-type"
       },
       {
         "expression": "floor($.decimals[0])",
         "result": [1]
       },
       {
         "expression": "floor($.foo)",
         "result": [-1]
       },
       {
         "expression": "floor($.str)",
         "result": []
         //"error": "invalid-type"
       },
       {
         "expression": "length('abc')",
         "result": [3]
       },
       {
         "expression": "length('✓foo')",
         "result": [4]
       },
       {
         "expression": "length('')",
         "result": [0]
       },
       {
         "expression": "length(@)",
         "result": [12]
       },
       {
         "expression": "length($.strings[0])",
         "result": [1]
       },
       {
         "expression": "length($.str)",
         "result": [3]
       },
       {
         "expression": "length($.array)",
         "result": [6]
       },
       {
         "expression": "length($.objects)",
         "result": [2]
       },
       {
         "expression": "length(false)",
         "result": []
         //"error": "invalid-type"
       },
       {
         "expression": "length($.foo)",
         "result": []
         //"error": "invalid-type"
       },
       {
         "expression": "length($.strings[0])",
         "result": [1]
       },
       {
         "expression": "max($.numbers)",
         "result": [5]
       },
       {
         "expression": "max($.decimals)",
         "result": [1.2]
       },
       {
         "expression": "max($.strings)",
         "result": ["c"]
       },
       {
         "expression": "max($.abc)",
         "result": []
         //"error": "invalid-type"
       },
       {
         "expression": "max($.array)",
         "result": []
         //"error": "invalid-type"
       },
       {
         "expression": "max($.decimals)",
         "result": [1.2]
       },
       {
         "expression": "max($.empty_list)",
         "result": [null]
       }/*,
       {
         "expression": "merge(`{}`)",
         "result": {}
       },
       {
         "expression": "merge(`{}`, `{}`)",
         "result": {}
       },
       {
         "expression": "merge(`{\"a\": 1}`, `{\"b\": 2}`)",
         "result": {"a": 1, "b": 2}
       },
       {
         "expression": "merge(`{\"a\": 1}`, `{\"a\": 2}`)",
         "result": {"a": 2}
       },
       {
         "expression": "merge(`{\"a\": 1, \"b\": 2}`, `{\"a\": 2, \"c\": 3}`, `{\"d\": 4}`)",
         "result": {"a": 2, "b": 2, ["c"]: 3, "d": 4}
       }*/,
       {
         "expression": "min($.numbers)",
         "result": [-1]
       },
       {
         "expression": "min($.decimals)",
         "result": [-1.5]
       },
       {
         "expression": "min($.abc)",
         "result": []
         //"error": "invalid-type"
       },
       {
         "expression": "starts_with($.str, 'S')",
         "result": [true]
       },
       {
         "expression": "starts_with($.str, 'St')",
         "result": [true]
       },
       {
         "expression": "starts_with($.str, 'Str')",
         "result": [true]
       },
       {
         "expression": "starts_with($.str, 'String')",
         "result": [false]
       },
       {
         "expression": "starts_with($.str, 0)",
         "result" : []
         //"error": "invalid-type"
       },
       {
         "expression": "min($.array)",
         "result" : []
         //"error": "invalid-type"
       },
       {
         "expression": "min($.empty_list)",
         "result": [null]
       },
       {
         "expression": "min($.decimals)",
         "result": [-1.5]
       },
       {
         "expression": "min($.strings)",
         "result": ["a"]
       }/*,
       {
         "expression": "type('abc')",
         "result": ["string"]
       },
       {
         "expression": "type(`1.0`)",
         "result": ["number"]
       },
       {
         "expression": "type(`2`)",
         "result": ["number"]
       },
       {
         "expression": "type(`true`)",
         "result": ["boolean"]
       },
       {
         "expression": "type(false)",
         "result": ["boolean"]
       },
       {
         "expression": "type(null)",
         "result": ["null"]
       },
       {
         "expression": "type([0])",
         "result": ["array"]
       },
       {
         "expression": "type(`{\"a\": \"b\"}`)",
         "result": ["object"]
       },
       {
         "expression": "type(@)",
         "result": ["object"]
       },
       {
         "expression": "sort(keys($.objects))",
         "result": ["bar", "foo"]
       }*/,
       {
         "expression": "keys($.foo)",
         "result" : []
         //"error": "invalid-type"
       },
       {
         "expression": "keys($.strings)",
         "result" : []
         //"error": "invalid-type"
       },
       {
         "expression": "keys(false)",
         "result" : []
         //"error": "invalid-type"
       }/*,
       {
         "expression": "sort(values($.objects))",
         "result": ["bar", "baz"]
       }*/,
       {
         "expression": "keys($.empty_hash)",
         "result": [[]]
       }/*,
       {
         "expression": "values($.foo)",
         "error": "invalid-type"
       },
       {
         "expression": "join(', ', strings)",
         "result": "a, b, c"
       },
       {
         "expression": "join(', ', strings)",
         "result": "a, b, c"
       },
       {
         "expression": "join(',', `[\"a\", \"b\"]`)",
         "result": "a,b"
       },
       {
         "expression": "join(',', `[\"a\", 0]`)",
         "error": "invalid-type"
       },
       {
         "expression": "join(', ', str)",
         "error": "invalid-type"
       },
       {
         "expression": "join('|', strings)",
         "result": "a|b|c"
       },
       {
         "expression": "join(`2`, strings)",
         "error": "invalid-type"
       },
       {
         "expression": "join('|', decimals)",
         "error": "invalid-type"
       },
       {
         "expression": "join('|', decimals[].to_string(@))",
         "result": "1.01|1.2|-1.5"
       },
       {
         "expression": "join('|', empty_list)",
         "result": ""
       },
       {
         "expression": "reverse($.numbers)",
         "result": [5, 4, 3, -1]
       },
       {
         "expression": "reverse($.array)",
         "result": ["100", "a", 5, 4, 3, -1]
       },
       {
         "expression": "reverse(`[]`)",
         "result": []
       },
       {
         "expression": "reverse('')",
         "result": ""
       },
       {
         "expression": "reverse('hello world')",
         "result": "dlrow olleh"
       }*/,
       {
         "expression": "sum($.numbers)",
         "result": [11]
       },
       {
         "expression": "sum($.decimals)",
         "result": [0.71]
       },
       {
         "expression": "sum($.array)",
         "result" : []
         //"error": "invalid-type"
       }/*,
       {
         "expression": "sum($.array[].to_number(@))",
         "result": 111
       }*/,
       {
         "expression": "sum([])",
         "result": [0]
       }/*,
       {
         "expression": "to_array('foo')",
         "result": ["foo"]
       },
       {
         "expression": "to_array(`0`)",
         "result": [0]
       },
       {
         "expression": "to_array($.objects)",
         "result": [{"foo": "bar", "bar": "baz"}]
       },
       {
         "expression": "to_array(`[1, 2, 3]`)",
         "result": [1, 2, 3]
       },
       {
         "expression": "to_array(false)",
         "result": [false]
       },
       {
         "expression": "to_string('foo')",
         "result": "foo"
       },
       {
         "expression": "to_string(1.2)",
         "result": "1.2"
       },
       {
         "expression": "to_string(`[0, 1]`)",
         "result": "[0,1]"
       },
       {
         "expression": "to_number('1.0')",
         "result": 1.0
       },
       {
         "expression": "to_number('1.1')",
         "result": 1.1
       },
       {
         "expression": "to_number('4')",
         "result": [4]
       },
       {
         "expression": "to_number('notanumber')",
         "result": []
       },
       {
         "expression": "to_number(false)",
         "result": []
       },
       {
         "expression": "to_number(`null`)",
         "result": []
       },
       {
         "expression": "to_number(`[0]`)",
         "result": []
       },
       {
         "expression": "to_number(`{\"foo\": 0}`)",
         "result": []
       },
       {
         "expression": "\"to_string\"(`1.0`)",
         "error": "syntax"
       },
       {
         "expression": "sort($.numbers)",
         "result": [-1, 3, 4, 5]
       },
       {
         "expression": "sort($.strings)",
         "result": ["a", "b", ["c"]]
       },
       {
         "expression": "sort($.decimals)",
         "result": [-1.5, 1.01, 1.2]
       },
       {
         "expression": "sort($.array)",
         "error": "invalid-type"
       },
       {
         "expression": "sort($.abc)",
         "error": "invalid-type"
       },
       {
         "expression": "sort($.empty_list)",
         "result": []
       },
       {
         "expression": "sort(@)",
         "error": "invalid-type"
       },
       {
         "expression": "not_null($.unknown_key, str)",
         "result": "Str"
       },
       {
         "expression": "not_null($.unknown_key, foo.bar, empty_list, str)",
         "result": []
       },
       {
         "expression": "not_null($.unknown_key, null_key, empty_list, str)",
         "result": []
       },
       {
         "expression": "not_null(all, expressions, are_null)",
         "result": []
       },
       {
         "expression": "not_null()",
         "error": "invalid-arity"
       }
       */
     ]
   }
]
