jsonpath 1.0.1 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []