joshbuddy / jsonpath

Ruby implementation of http://goessner.net/articles/JsonPath/
MIT License
447 stars 72 forks source link

Negating the filter expression using ! is not working #151

Open Parth-Rewind opened 1 year ago

Parth-Rewind commented 1 year ago

Sample JSON: Response from Github when getting a list of all issues The response contains two objects, one with a pull_request property and the other doesn't have a pull_request property.

[
  {
    "id": 1,
    "pull_request": {
      "url": "https://api.github.com/repos/octocat/Hello-World/pulls/1347",
      "html_url": "https://github.com/octocat/Hello-World/pull/1347",
      "diff_url": "https://github.com/octocat/Hello-World/pull/1347.diff",
      "patch_url": "https://github.com/octocat/Hello-World/pull/1347.patch"
    },
    "updated_at": "2011-04-22T13:33:48Z"
  },
  {
    "id": 2,
    "updated_at": "2011-04-22T13:33:48Z"
  }
]

Bug

The request is to support this scenario

πŸ”΄ Failing scenario. Cannot negate a filter expression using !

Intent: Get all objects from sample json data that don't have a pull_request property

Query

JsonPath.new('$[?(!@.pull_request)]').on(json)

🐞 Actual Result:

[]

Expected Result

[
  {
    "id": 2,
    "updated_at": "2011-04-22T13:33:48Z"
  }
]

Result From Jsonpath.com

Screenshot 2023-02-22 at 8 16 21 AM

🟒 Passing scenario. This scenario is working fine and as intended.

Intent: Get all objects from sample data with the pull_request property in the response

Query

JsonPath.new('$[?(@.pull_request)]').on(json)

Result from JsonPath

[
  {
    'id' => 1,
    'pull_request' => {
      'url' => 'https://api.github.com/repos/octocat/Hello-World/pulls/1347',
      'html_url' => 'https://github.com/octocat/Hello-World/pull/1347',
      'diff_url' => 'https://github.com/octocat/Hello-World/pull/1347.diff',
      'patch_url' => 'https://github.com/octocat/Hello-World/pull/1347.patch'
    },
    'updated_at' => '2011-04-22T13:33:48Z'
  }
]
evansalter commented 1 year ago

Also note that when using bracket indexing for the object we're checking, we get an error:

Query

JsonPath.new("$[?(!@['pull_request'])]").on(json)

🐞 Actual Result:

Traceback (most recent call last):
       16: from /Users/evansalter/.rvm/gems/ruby-2.6.6/gems/jsonpath-1.1.2/lib/jsonpath/enumerable.rb:24:in `each'
       15: from /Users/evansalter/.rvm/gems/ruby-2.6.6/gems/jsonpath-1.1.2/lib/jsonpath/enumerable.rb:26:in `each'
       14: from /Users/evansalter/.rvm/gems/ruby-2.6.6/gems/jsonpath-1.1.2/lib/jsonpath/enumerable.rb:55:in `handle_wildecard'
       13: from /Users/evansalter/.rvm/gems/ruby-2.6.6/gems/jsonpath-1.1.2/lib/jsonpath/enumerable.rb:55:in `each'
       12: from /Users/evansalter/.rvm/gems/ruby-2.6.6/gems/jsonpath-1.1.2/lib/jsonpath/enumerable.rb:63:in `block in handle_wildecard'
       11: from /Users/evansalter/.rvm/gems/ruby-2.6.6/gems/jsonpath-1.1.2/lib/jsonpath/enumerable.rb:108:in `handle_question_mark'
       10: from /Users/evansalter/.rvm/gems/ruby-2.6.6/gems/jsonpath-1.1.2/lib/jsonpath/enumerable.rb:108:in `times'
        9: from /Users/evansalter/.rvm/gems/ruby-2.6.6/gems/jsonpath-1.1.2/lib/jsonpath/enumerable.rb:110:in `block in handle_question_mark'
        8: from /Users/evansalter/.rvm/gems/ruby-2.6.6/gems/jsonpath-1.1.2/lib/jsonpath/enumerable.rb:160:in `process_function_or_literal'
        7: from /Users/evansalter/.rvm/gems/ruby-2.6.6/gems/jsonpath-1.1.2/lib/jsonpath/parser.rb:31:in `parse'
        6: from /Users/evansalter/.rvm/gems/ruby-2.6.6/gems/jsonpath-1.1.2/lib/jsonpath/parser.rb:45:in `construct_expression_map'
        5: from /Users/evansalter/.rvm/gems/ruby-2.6.6/gems/jsonpath-1.1.2/lib/jsonpath/parser.rb:45:in `each_with_index'
        4: from /Users/evansalter/.rvm/gems/ruby-2.6.6/gems/jsonpath-1.1.2/lib/jsonpath/parser.rb:45:in `each'
        3: from /Users/evansalter/.rvm/gems/ruby-2.6.6/gems/jsonpath-1.1.2/lib/jsonpath/parser.rb:49:in `block in construct_expression_map'
        2: from /Users/evansalter/.rvm/gems/ruby-2.6.6/gems/jsonpath-1.1.2/lib/jsonpath/parser.rb:107:in `parse_exp'
        1: from /Users/evansalter/.rvm/gems/ruby-2.6.6/gems/jsonpath-1.1.2/lib/jsonpath/parser.rb:107:in `!'
ArgumentError (wrong number of arguments (given 1, expected 0))

Expected Result

[
  {
    "id": 2,
    "updated_at": "2011-04-22T13:33:48Z"
  }
]

I've got a PR to fix this incoming.