jsonpath 1.0.1 → 1.0.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d45aa52a5d4a9500f243abaa6ff69131a7e5a8653ffacd1ff0787946774d12f3
4
- data.tar.gz: bd0903ab08210ac2e5a44a56f548104c1924f2d9a9db9d5006a51db86aafc648
3
+ metadata.gz: 7c156dcfda0e97156b872e63c64fc1b4a4f2379f217103165f22de78e3415800
4
+ data.tar.gz: ab9647efecba7fa057dc77b4f447c9ea09aba719d117e95edefeace45915c2cb
5
5
  SHA512:
6
- metadata.gz: 96a161911383f2c7870bd5450020aaaaceb1ea4305672f5a08493016e4fdcc5fb346001b3e8a377c16588c7bcd5adf9b0be1ef51d18b483404619324600501bb
7
- data.tar.gz: 2c824f8916a742f0e5a9201c858c683bf2df7e9c7d5e38f7b7206fc8f511f69741afb3378993f3ed7e8f396148a14596ce7b9e78f0a739d2aeafc15591a0b585
6
+ metadata.gz: 74ca2152d154f76497df525616aba1792c192be58025c47e6e76a9ebb6c6ebd3a3cbbcf66c2a7b49d4ec1d211ce46ce0b2ba3c334b6c755e0acde4042be9f27f
7
+ data.tar.gz: 47d2c181d409d1091b23080e8f62f8b708e5bd171040599b2ed3f1ce3c0a379e5a11eb72b441c61395682ec40f1f6d16bdfb51fa967a4a16046ba63caefb99ca
data/.gitignore CHANGED
@@ -3,3 +3,5 @@ Gemfile.lock
3
3
  coverage/*
4
4
  doc/*
5
5
  .yardoc
6
+ .DS_Store
7
+ .idea
@@ -1,9 +1,7 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.1.6
4
- - 2.3.1
3
+ - 2.5
4
+ - 2.6
5
+ - 2.7
5
6
  - ruby-head
6
7
  - jruby-head
7
-
8
- before_install:
9
- - gem install bundler -v '< 2'
data/README.md CHANGED
@@ -123,6 +123,51 @@ For more usage examples and variations on paths, please visit the tests. There a
123
123
  end
124
124
  ```
125
125
 
126
+ ### Selecting Values
127
+
128
+ It's possible to select results once a query has been defined after the query. For example given this JSON data:
129
+
130
+ ```bash
131
+ {
132
+ "store": {
133
+ "book": [
134
+ {
135
+ "category": "reference",
136
+ "author": "Nigel Rees",
137
+ "title": "Sayings of the Century",
138
+ "price": 8.95
139
+ },
140
+ {
141
+ "category": "fiction",
142
+ "author": "Evelyn Waugh",
143
+ "title": "Sword of Honour",
144
+ "price": 12.99
145
+ }
146
+ ]
147
+ }
148
+ ```
149
+
150
+ ... and this query:
151
+
152
+ ```ruby
153
+ "$.store.book[*](category,author)"
154
+ ```
155
+
156
+ ... the result can be filtered as such:
157
+
158
+ ```bash
159
+ [
160
+ {
161
+ "category" : "reference",
162
+ "author" : "Nigel Rees"
163
+ },
164
+ {
165
+ "category" : "fiction",
166
+ "author" : "Evelyn Waugh"
167
+ }
168
+ ]
169
+ ```
170
+
126
171
  ### Running an individual test
127
172
 
128
173
  ```ruby
@@ -5,10 +5,7 @@ require File.join(File.dirname(__FILE__), 'lib', 'jsonpath', 'version')
5
5
  Gem::Specification.new do |s|
6
6
  s.name = 'jsonpath'
7
7
  s.version = JsonPath::VERSION
8
- if s.respond_to? :required_rubygems_version=
9
- s.required_rubygems_version =
10
- Gem::Requirement.new('>= 0')
11
- end
8
+ s.required_ruby_version = '>= 2.5'
12
9
  s.authors = ['Joshua Hull', 'Gergely Brautigam']
13
10
  s.summary = 'Ruby implementation of http://goessner.net/articles/JsonPath/'
14
11
  s.description = 'Ruby implementation of http://goessner.net/articles/JsonPath/.'
@@ -16,17 +13,12 @@ Gem::Specification.new do |s|
16
13
  s.extra_rdoc_files = ['README.md']
17
14
  s.files = `git ls-files`.split("\n")
18
15
  s.homepage = 'https://github.com/joshbuddy/jsonpath'
19
- s.rdoc_options = ['--charset=UTF-8']
20
- s.require_paths = ['lib']
21
- s.rubygems_version = '1.3.7'
22
16
  s.test_files = `git ls-files`.split("\n").select { |f| f =~ /^spec/ }
23
- s.rubyforge_project = 'jsonpath'
24
17
  s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
25
18
  s.licenses = ['MIT']
26
19
 
27
20
  # dependencies
28
21
  s.add_runtime_dependency 'multi_json'
29
- s.add_runtime_dependency 'to_regexp', '~> 0.2.1'
30
22
  s.add_development_dependency 'bundler'
31
23
  s.add_development_dependency 'code_stats'
32
24
  s.add_development_dependency 'minitest', '~> 2.2.0'
@@ -10,7 +10,7 @@ require 'jsonpath/parser'
10
10
  # JsonPath: initializes the class with a given JsonPath and parses that path
11
11
  # into a token array.
12
12
  class JsonPath
13
- PATH_ALL = '$..*'.freeze
13
+ PATH_ALL = '$..*'
14
14
 
15
15
  attr_accessor :path
16
16
 
@@ -19,21 +19,23 @@ class JsonPath
19
19
  scanner = StringScanner.new(path.strip)
20
20
  @path = []
21
21
  until scanner.eos?
22
- if token = scanner.scan(/\$\B|@\B|\*|\.\./)
22
+ if (token = scanner.scan(/\$\B|@\B|\*|\.\./))
23
23
  @path << token
24
- elsif token = scanner.scan(/[\$@a-zA-Z0-9:{}_-]+/)
24
+ elsif (token = scanner.scan(/[$@a-zA-Z0-9:{}_-]+/))
25
25
  @path << "['#{token}']"
26
- elsif token = scanner.scan(/'(.*?)'/)
26
+ elsif (token = scanner.scan(/'(.*?)'/))
27
27
  @path << "[#{token}]"
28
- elsif token = scanner.scan(/\[/)
28
+ elsif (token = scanner.scan(/\[/))
29
29
  @path << find_matching_brackets(token, scanner)
30
- elsif token = scanner.scan(/\]/)
30
+ elsif (token = scanner.scan(/\]/))
31
31
  raise ArgumentError, 'unmatched closing bracket'
32
+ elsif (token = scanner.scan(/\(.*\)/))
33
+ @path << token
32
34
  elsif scanner.scan(/\./)
33
35
  nil
34
- elsif token = scanner.scan(/[><=] \d+/)
36
+ elsif (token = scanner.scan(/[><=] \d+/))
35
37
  @path.last << token
36
- elsif token = scanner.scan(/./)
38
+ elsif (token = scanner.scan(/./))
37
39
  begin
38
40
  @path.last << token
39
41
  rescue RuntimeError
@@ -46,13 +48,13 @@ class JsonPath
46
48
  def find_matching_brackets(token, scanner)
47
49
  count = 1
48
50
  until count.zero?
49
- if t = scanner.scan(/\[/)
51
+ if (t = scanner.scan(/\[/))
50
52
  token << t
51
53
  count += 1
52
- elsif t = scanner.scan(/\]/)
54
+ elsif (t = scanner.scan(/\]/))
53
55
  token << t
54
56
  count -= 1
55
- elsif t = scanner.scan(/[^\[\]]+/)
57
+ elsif (t = scanner.scan(/[^\[\]]+/))
56
58
  token << t
57
59
  elsif scanner.eos?
58
60
  raise ArgumentError, 'unclosed bracket'
@@ -12,7 +12,12 @@ class JsonPath
12
12
  end
13
13
 
14
14
  def each(context = @object, key = nil, pos = 0, &blk)
15
- node = key ? context[key] : context
15
+ node =
16
+ if key
17
+ context.is_a?(Hash) || context.is_a?(Array) ? context[key] : context.__send__(key)
18
+ else
19
+ context
20
+ end
16
21
  @_current_node = node
17
22
  return yield_value(blk, context, key) if pos == @path.size
18
23
 
@@ -23,6 +28,10 @@ class JsonPath
23
28
  each(context, key, pos + 1, &blk) if node == @object
24
29
  when /^\[(.*)\]$/
25
30
  handle_wildecard(node, expr, context, key, pos, &blk)
31
+ when /\(.*\)/
32
+ keys = expr.gsub(/[()]/, '').split(',').map(&:strip)
33
+ new_context = filter_context(context, keys)
34
+ yield_value(blk, new_context, key)
26
35
  end
27
36
 
28
37
  if pos > 0 && @path[pos - 1] == '..' || (@path[pos - 1] == '*' && @path[pos] != '..')
@@ -35,14 +44,28 @@ class JsonPath
35
44
 
36
45
  private
37
46
 
47
+ def filter_context(context, keys)
48
+ case context
49
+ when Hash
50
+ # TODO: Change this to `slice(*keys)` when ruby version support is > 2.4
51
+ context.select { |k| keys.include?(k) }
52
+ when Array
53
+ context.each_with_object([]) do |c, memo|
54
+ memo << c.select { |k| keys.include?(k) }
55
+ end
56
+ end
57
+ end
58
+
38
59
  def handle_wildecard(node, expr, _context, _key, pos, &blk)
39
60
  expr[1, expr.size - 2].split(',').each do |sub_path|
40
61
  case sub_path[0]
41
62
  when '\'', '"'
63
+ k = sub_path[1, sub_path.size - 2]
42
64
  if node.is_a?(Hash)
43
- k = sub_path[1, sub_path.size - 2]
44
65
  node[k] ||= nil if @options[:default_path_leaf_to_null]
45
66
  each(node, k, pos + 1, &blk) if node.key?(k)
67
+ elsif node.respond_to?(k.to_s) && !Object.respond_to?(k.to_s)
68
+ each(node, k, pos + 1, &blk)
46
69
  end
47
70
  when '?'
48
71
  handle_question_mark(sub_path, node, pos, &blk)
@@ -1,11 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'strscan'
4
- require 'to_regexp'
5
4
 
6
5
  class JsonPath
7
6
  # Parser parses and evaluates an expression passed to @_current_node.
8
7
  class Parser
8
+ REGEX = /\A\/(.+)\/([imxnesu]*)\z|\A%r{(.+)}([imxnesu]*)\z/
9
+
9
10
  def initialize(node)
10
11
  @_current_node = node
11
12
  @_expr_map = {}
@@ -46,46 +47,56 @@ class JsonPath
46
47
  end
47
48
  end
48
49
 
49
- #  using a scanner break down the individual expressions and determine if
50
+ # Using a scanner break down the individual expressions and determine if
50
51
  # there is a match in the JSON for it or not.
51
52
  def parse_exp(exp)
52
53
  exp = exp.sub(/@/, '').gsub(/^\(/, '').gsub(/\)$/, '').tr('"', '\'').strip
54
+ exp.scan(/^\[(\d+)\]/) do |i|
55
+ next if i.empty?
56
+
57
+ index = Integer(i[0])
58
+ raise ArgumentError, 'Node does not appear to be an array.' unless @_current_node.is_a?(Array)
59
+ raise ArgumentError, "Index out of bounds for nested array. Index: #{index}" if @_current_node.size < index
60
+
61
+ @_current_node = @_current_node[index]
62
+ # Remove the extra '' and the index.
63
+ exp = exp.gsub(/^\[\d+\]|\[''\]/, '')
64
+ end
53
65
  scanner = StringScanner.new(exp)
54
66
  elements = []
55
67
  until scanner.eos?
56
- if scanner.scan(/\./)
57
- sym = scanner.scan(/\w+/)
58
- op = scanner.scan(/./)
59
- num = scanner.scan(/\d+/)
60
- return @_current_node.send(sym.to_sym).send(op.to_sym, num.to_i)
61
- end
62
- if t = scanner.scan(/\['[a-zA-Z@&\*\/\$%\^\?_]+'\]+/)
63
- elements << t.gsub(/\[|\]|'|\s+/, '')
64
- elsif t = scanner.scan(/(\s+)?[<>=][=~]?(\s+)?/)
68
+ if (t = scanner.scan(/\['[a-zA-Z@&*\/$%^?_]+'\]|\.[a-zA-Z0-9_]+[?!]?/))
69
+ elements << t.gsub(/[\[\]'.]|\s+/, '')
70
+ elsif (t = scanner.scan(/(\s+)?[<>=!\-+][=~]?(\s+)?/))
65
71
  operator = t
66
- elsif t = scanner.scan(/(\s+)?'?.*'?(\s+)?/)
72
+ elsif (t = scanner.scan(/(\s+)?'?.*'?(\s+)?/))
67
73
  # If we encounter a node which does not contain `'` it means
68
74
  #  that we are dealing with a boolean type.
69
- operand = if t == 'true'
70
- true
71
- elsif t == 'false'
72
- false
73
- else
74
- operator.to_s.strip == '=~' ? t.to_regexp : t.gsub(%r{^'|'$}, '').strip
75
- end
76
- elsif t = scanner.scan(/\/\w+\//)
77
- elsif t = scanner.scan(/.*/)
75
+ operand =
76
+ if t == 'true'
77
+ true
78
+ elsif t == 'false'
79
+ false
80
+ elsif operator.to_s.strip == '=~'
81
+ parse_regex(t)
82
+ else
83
+ t.gsub(%r{^'|'$}, '').strip
84
+ end
85
+ elsif (t = scanner.scan(/\/\w+\//))
86
+ elsif (t = scanner.scan(/.*/))
78
87
  raise "Could not process symbol: #{t}"
79
88
  end
80
89
  end
81
90
 
82
91
  el = if elements.empty?
83
92
  @_current_node
93
+ elsif @_current_node.is_a?(Hash)
94
+ @_current_node.dig(*elements)
84
95
  else
85
- dig(elements, @_current_node)
96
+ elements.inject(@_current_node, &:__send__)
86
97
  end
87
- return false if el.nil?
88
- return true if operator.nil? && el
98
+
99
+ return (el ? true : false) if el.nil? || operator.nil?
89
100
 
90
101
  el = Float(el) rescue el
91
102
  operand = Float(operand) rescue operand
@@ -95,14 +106,29 @@ class JsonPath
95
106
 
96
107
  private
97
108
 
98
- # @TODO: Remove this once JsonPath no longer supports ruby versions below 2.3
99
- def dig(keys, hash)
100
- return nil unless hash.is_a? Hash
101
- return nil unless hash.key?(keys.first)
102
- return hash.fetch(keys.first) if keys.size == 1
109
+ # /foo/i -> Regex.new("foo", Regexp::IGNORECASE) without using eval
110
+ # also supports %r{foo}i
111
+ # following https://github.com/seamusabshere/to_regexp/blob/master/lib/to_regexp.rb
112
+ def parse_regex(t)
113
+ t =~ REGEX
114
+ content = $1 || $3
115
+ options = $2 || $4
116
+
117
+ raise "unsupported regex #{t} use /foo/ style" if !content || !options
118
+
119
+ content = content.gsub '\\/', '/'
120
+
121
+ flags = 0
122
+ flags |= Regexp::IGNORECASE if options.include?('i')
123
+ flags |= Regexp::MULTILINE if options.include?('m')
124
+ flags |= Regexp::EXTENDED if options.include?('x')
125
+
126
+ # 'n' = none, 'e' = EUC, 's' = SJIS, 'u' = UTF-8
127
+ lang = options.scan(/[nes]/).join.downcase # ignores u since that is default and causes a warning
103
128
 
104
- prev = keys.shift
105
- dig(keys, hash.fetch(prev))
129
+ args = [content, flags]
130
+ args << lang unless lang.empty? # avoid warning
131
+ Regexp.new(*args)
106
132
  end
107
133
 
108
134
  #  This will break down a parenthesis from the left to the right
@@ -129,10 +155,9 @@ class JsonPath
129
155
  top = top.map(&:strip)
130
156
  res = bool_or_exp(top.shift)
131
157
  top.each_with_index do |item, index|
132
- case item
133
- when '&&'
158
+ if item == '&&'
134
159
  res &&= top[index + 1]
135
- when '||'
160
+ elsif item == '||'
136
161
  res ||= top[index + 1]
137
162
  end
138
163
  end
@@ -141,9 +166,9 @@ class JsonPath
141
166
  # and the closing index will be the last index. To avoid
142
167
  # off-by-one errors we simply return the result at that point.
143
168
  if closing_index + 1 >= str.length && opening_index == 0
144
- return res.to_s
169
+ res.to_s
145
170
  else
146
- return "#{str[0..opening_index - 1]}#{res}#{str[closing_index + 1..str.length]}"
171
+ "#{str[0..opening_index - 1]}#{res}#{str[closing_index + 1..str.length]}"
147
172
  end
148
173
  end
149
174
 
@@ -10,11 +10,11 @@ class JsonPath
10
10
  end
11
11
 
12
12
  def gsub(path, replacement = nil, &replacement_block)
13
- _gsub(_deep_copy, path, replacement ? proc { replacement } : replacement_block)
13
+ _gsub(_deep_copy, path, replacement ? proc(&method(:replacement)) : replacement_block)
14
14
  end
15
15
 
16
16
  def gsub!(path, replacement = nil, &replacement_block)
17
- _gsub(@obj, path, replacement ? proc { replacement } : replacement_block)
17
+ _gsub(@obj, path, replacement ? proc(&method(:replacement)) : replacement_block)
18
18
  end
19
19
 
20
20
  def delete(path = JsonPath::PATH_ALL)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class JsonPath
4
- VERSION = '1.0.1'.freeze
4
+ VERSION = '1.0.6'
5
5
  end
@@ -70,6 +70,12 @@ class TestJsonpath < MiniTest::Unit::TestCase
70
70
  assert_equal [@object['store']['book'][0], @object['store']['book'][2]], JsonPath.new("$..book[?(@['price'] < 10)]").on(@object)
71
71
  assert_equal [@object['store']['book'][0], @object['store']['book'][2]], JsonPath.new("$..book[?(@['price'] == 9)]").on(@object)
72
72
  assert_equal [@object['store']['book'][3]], JsonPath.new("$..book[?(@['price'] > 20)]").on(@object)
73
+ assert_equal [
74
+ @object['store']['book'][0],
75
+ @object['store']['book'][4],
76
+ @object['store']['book'][5],
77
+ @object['store']['book'][6]
78
+ ], JsonPath.new("$..book[?(@['category'] != 'fiction')]").on(@object)
73
79
  end
74
80
 
75
81
  def test_or_operator
@@ -113,6 +119,25 @@ class TestJsonpath < MiniTest::Unit::TestCase
113
119
  assert_equal [@object['store']['bicycle']['2seater']], JsonPath.new('$.store.bicycle.2seater').on(@object)
114
120
  end
115
121
 
122
+ def test_recognized_dot_notation_in_filters
123
+ assert_equal [@object['store']['book'][2], @object['store']['book'][3]], JsonPath.new('$..book[?(@.isbn)]').on(@object)
124
+ end
125
+
126
+ def test_works_on_non_hash
127
+ klass = Struct.new(:a, :b)
128
+ object = klass.new('some', 'value')
129
+
130
+ assert_equal ['value'], JsonPath.new('$.b').on(object)
131
+ end
132
+
133
+ def test_works_on_non_hash_with_filters
134
+ klass = Struct.new(:a, :b)
135
+ first_object = klass.new('some', 'value')
136
+ second_object = klass.new('next', 'other value')
137
+
138
+ assert_equal ['other value'], JsonPath.new('$[?(@.a == "next")].b').on([first_object, second_object])
139
+ end
140
+
116
141
  def test_recognize_array_with_evald_index
117
142
  assert_equal [@object['store']['book'][2]], JsonPath.new('$..book[(@.length-5)]').on(@object)
118
143
  end
@@ -723,7 +748,7 @@ class TestJsonpath < MiniTest::Unit::TestCase
723
748
  end
724
749
 
725
750
  def test_runtime_error_frozen_string
726
- skip('in ruby version below 2.2.0 this error is not raised') if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.2.0')
751
+ skip('in ruby version below 2.2.0 this error is not raised') if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.2.0') || Gem::Version.new(RUBY_VERSION) > Gem::Version::new('2.6')
727
752
  json = '
728
753
  {
729
754
  "test": "something"
@@ -779,6 +804,124 @@ class TestJsonpath < MiniTest::Unit::TestCase
779
804
  assert_equal expected, JsonPath.for(a.to_json).delete('$.itemList[1:6:2]').to_hash
780
805
  end
781
806
 
807
+ def test_nested_values
808
+ json = '
809
+ {
810
+ "phoneNumbers": [
811
+ [{
812
+ "type" : "iPhone",
813
+ "number": "0123-4567-8888"
814
+ }],
815
+ [{
816
+ "type" : "home",
817
+ "number": "0123-4567-8910"
818
+ }]
819
+ ]
820
+ }
821
+ '.to_json
822
+ assert_equal [[{ 'type' => 'home', 'number' => '0123-4567-8910' }]], JsonPath.on(json, "$.phoneNumbers[?(@[0].type == 'home')]")
823
+ assert_equal [], JsonPath.on(json, "$.phoneNumbers[?(@[2].type == 'home')]")
824
+ json = '
825
+ {
826
+ "phoneNumbers":
827
+ {
828
+ "type" : "iPhone",
829
+ "number": "0123-4567-8888"
830
+ }
831
+ }
832
+ '.to_json
833
+ assert_equal [], JsonPath.on(json, "$.phoneNumbers[?(@[0].type == 'home')]")
834
+ end
835
+
836
+ def test_selecting_multiple_keys
837
+ json = '
838
+ {
839
+ "store": {
840
+ "book": [
841
+ {
842
+ "category": "reference",
843
+ "author": "Nigel Rees",
844
+ "title": "Sayings of the Century",
845
+ "price": 8.95
846
+ },
847
+ {
848
+ "category": "fiction",
849
+ "author": "Evelyn Waugh",
850
+ "title": "Sword of Honour",
851
+ "price": 12.99
852
+ }
853
+ ]
854
+ }
855
+ }
856
+ '.to_json
857
+
858
+ assert_equal [{ 'category' => 'reference', 'author' => 'Nigel Rees' }, { 'category' => 'fiction', 'author' => 'Evelyn Waugh' }], JsonPath.on(json, '$.store.book[*](category,author)')
859
+ end
860
+
861
+ def test_selecting_multiple_keys_with_filter
862
+ json = '
863
+ {
864
+ "store": {
865
+ "book": [
866
+ {
867
+ "category": "reference",
868
+ "author": "Nigel Rees",
869
+ "title": "Sayings of the Century",
870
+ "price": 8.95
871
+ },
872
+ {
873
+ "category": "fiction",
874
+ "author": "Evelyn Waugh",
875
+ "title": "Sword of Honour",
876
+ "price": 12.99
877
+ }
878
+ ]
879
+ }
880
+ }
881
+ '.to_json
882
+
883
+ assert_equal [{ 'category' => 'reference', 'author' => 'Nigel Rees' }], JsonPath.on(json, "$.store.book[?(@['price'] == 8.95)](category,author)")
884
+ assert_equal [{ 'category' => 'reference', 'author' => 'Nigel Rees' }], JsonPath.on(json, "$.store.book[?(@['price'] == 8.95)]( category, author )")
885
+ end
886
+
887
+ def test_selecting_multiple_keys_with_filter_with_space_in_catergory
888
+ json = '
889
+ {
890
+ "store": {
891
+ "book": [
892
+ {
893
+ "cate gory": "reference",
894
+ "author": "Nigel Rees",
895
+ "title": "Sayings of the Century",
896
+ "price": 8.95
897
+ },
898
+ {
899
+ "cate gory": "fiction",
900
+ "author": "Evelyn Waugh",
901
+ "title": "Sword of Honour",
902
+ "price": 12.99
903
+ }
904
+ ]
905
+ }
906
+ }
907
+ '.to_json
908
+
909
+ assert_equal [{ 'cate gory' => 'reference', 'author' => 'Nigel Rees' }], JsonPath.on(json, "$.store.book[?(@['price'] == 8.95)]( cate gory, author )")
910
+ end
911
+
912
+ def test_object_method_send
913
+ j = {height: 5, hash: "some_hash"}.to_json
914
+ hs = JsonPath.new "$..send"
915
+ assert_equal([], hs.on(j))
916
+ hs = JsonPath.new "$..hash"
917
+ assert_equal(["some_hash"], hs.on(j))
918
+ hs = JsonPath.new "$..send"
919
+ assert_equal([], hs.on(j))
920
+ j = {height: 5, send: "should_still_work"}.to_json
921
+ hs = JsonPath.new "$..send"
922
+ assert_equal(['should_still_work'], hs.on(j))
923
+ end
924
+
782
925
  def example_object
783
926
  { 'store' => {
784
927
  'book' => [
metadata CHANGED
@@ -1,23 +1,23 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsonpath
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joshua Hull
8
8
  - Gergely Brautigam
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2019-01-25 00:00:00.000000000 Z
12
+ date: 2020-11-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: multi_json
16
15
  requirement: !ruby/object:Gem::Requirement
17
16
  requirements:
18
17
  - - ">="
19
18
  - !ruby/object:Gem::Version
20
19
  version: '0'
20
+ name: multi_json
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
@@ -26,26 +26,12 @@ dependencies:
26
26
  - !ruby/object:Gem::Version
27
27
  version: '0'
28
28
  - !ruby/object:Gem::Dependency
29
- name: to_regexp
30
- requirement: !ruby/object:Gem::Requirement
31
- requirements:
32
- - - "~>"
33
- - !ruby/object:Gem::Version
34
- version: 0.2.1
35
- type: :runtime
36
- prerelease: false
37
- version_requirements: !ruby/object:Gem::Requirement
38
- requirements:
39
- - - "~>"
40
- - !ruby/object:Gem::Version
41
- version: 0.2.1
42
- - !ruby/object:Gem::Dependency
43
- name: bundler
44
29
  requirement: !ruby/object:Gem::Requirement
45
30
  requirements:
46
31
  - - ">="
47
32
  - !ruby/object:Gem::Version
48
33
  version: '0'
34
+ name: bundler
49
35
  type: :development
50
36
  prerelease: false
51
37
  version_requirements: !ruby/object:Gem::Requirement
@@ -54,12 +40,12 @@ dependencies:
54
40
  - !ruby/object:Gem::Version
55
41
  version: '0'
56
42
  - !ruby/object:Gem::Dependency
57
- name: code_stats
58
43
  requirement: !ruby/object:Gem::Requirement
59
44
  requirements:
60
45
  - - ">="
61
46
  - !ruby/object:Gem::Version
62
47
  version: '0'
48
+ name: code_stats
63
49
  type: :development
64
50
  prerelease: false
65
51
  version_requirements: !ruby/object:Gem::Requirement
@@ -68,12 +54,12 @@ dependencies:
68
54
  - !ruby/object:Gem::Version
69
55
  version: '0'
70
56
  - !ruby/object:Gem::Dependency
71
- name: minitest
72
57
  requirement: !ruby/object:Gem::Requirement
73
58
  requirements:
74
59
  - - "~>"
75
60
  - !ruby/object:Gem::Version
76
61
  version: 2.2.0
62
+ name: minitest
77
63
  type: :development
78
64
  prerelease: false
79
65
  version_requirements: !ruby/object:Gem::Requirement
@@ -82,12 +68,12 @@ dependencies:
82
68
  - !ruby/object:Gem::Version
83
69
  version: 2.2.0
84
70
  - !ruby/object:Gem::Dependency
85
- name: phocus
86
71
  requirement: !ruby/object:Gem::Requirement
87
72
  requirements:
88
73
  - - ">="
89
74
  - !ruby/object:Gem::Version
90
75
  version: '0'
76
+ name: phocus
91
77
  type: :development
92
78
  prerelease: false
93
79
  version_requirements: !ruby/object:Gem::Requirement
@@ -96,12 +82,12 @@ dependencies:
96
82
  - !ruby/object:Gem::Version
97
83
  version: '0'
98
84
  - !ruby/object:Gem::Dependency
99
- name: rake
100
85
  requirement: !ruby/object:Gem::Requirement
101
86
  requirements:
102
87
  - - ">="
103
88
  - !ruby/object:Gem::Version
104
89
  version: '0'
90
+ name: rake
105
91
  type: :development
106
92
  prerelease: false
107
93
  version_requirements: !ruby/object:Gem::Requirement
@@ -142,25 +128,23 @@ homepage: https://github.com/joshbuddy/jsonpath
142
128
  licenses:
143
129
  - MIT
144
130
  metadata: {}
145
- post_install_message:
146
- rdoc_options:
147
- - "--charset=UTF-8"
131
+ post_install_message:
132
+ rdoc_options: []
148
133
  require_paths:
149
134
  - lib
150
135
  required_ruby_version: !ruby/object:Gem::Requirement
151
136
  requirements:
152
137
  - - ">="
153
138
  - !ruby/object:Gem::Version
154
- version: '0'
139
+ version: '2.5'
155
140
  required_rubygems_version: !ruby/object:Gem::Requirement
156
141
  requirements:
157
142
  - - ">="
158
143
  - !ruby/object:Gem::Version
159
144
  version: '0'
160
145
  requirements: []
161
- rubyforge_project: jsonpath
162
- rubygems_version: 2.7.8
163
- signing_key:
146
+ rubygems_version: 3.0.8
147
+ signing_key:
164
148
  specification_version: 4
165
149
  summary: Ruby implementation of http://goessner.net/articles/JsonPath/
166
150
  test_files: []