jamespath 0.5.0

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.
@@ -0,0 +1,214 @@
1
+ [{
2
+ "given": {
3
+ "foo": {
4
+ "bar": "bar",
5
+ "baz": "baz",
6
+ "qux": "qux",
7
+ "nested": {
8
+ "one": {
9
+ "a": "first",
10
+ "b": "second",
11
+ "c": "third"
12
+ },
13
+ "two": {
14
+ "a": "first",
15
+ "b": "second",
16
+ "c": "third"
17
+ },
18
+ "three": {
19
+ "a": "first",
20
+ "b": "second",
21
+ "c": {"inner": "third"}
22
+ }
23
+ }
24
+ },
25
+ "bar": 1,
26
+ "baz": 2,
27
+ "qux\"": 3
28
+ },
29
+ "cases": [
30
+ {
31
+ "expression": "foo.{bar: bar}",
32
+ "result": {"bar": "bar"}
33
+ },
34
+ {
35
+ "expression": "foo.{\"bar\": bar}",
36
+ "result": {"bar": "bar"}
37
+ },
38
+ {
39
+ "expression": "foo.{\"foo.bar\": bar}",
40
+ "result": {"foo.bar": "bar"}
41
+ },
42
+ {
43
+ "expression": "foo.{bar: bar, baz: baz}",
44
+ "result": {"bar": "bar", "baz": "baz"}
45
+ },
46
+ {
47
+ "expression": "foo.{\"bar\": bar, \"baz\": baz}",
48
+ "result": {"bar": "bar", "baz": "baz"}
49
+ },
50
+ {
51
+ "expression": "{\"baz\": baz, \"qux\\\"\": \"qux\\\"\"}",
52
+ "result": {"baz": 2, "qux\"": 3}
53
+ },
54
+ {
55
+ "expression": "foo.{bar:bar,baz:baz}",
56
+ "result": {"bar": "bar", "baz": "baz"}
57
+ },
58
+ {
59
+ "expression": "foo.{bar: bar,qux: qux}",
60
+ "result": {"bar": "bar", "qux": "qux"}
61
+ },
62
+ {
63
+ "expression": "foo.{bar: bar, noexist: noexist}",
64
+ "result": {"bar": "bar", "noexist": null}
65
+ },
66
+ {
67
+ "expression": "foo.{noexist: noexist, alsonoexist: alsonoexist}",
68
+ "result": {"noexist": null, "alsonoexist": null}
69
+ },
70
+ {
71
+ "expression": "foo.badkey.{nokey: nokey, alsonokey: alsonokey}",
72
+ "result": null
73
+ },
74
+ {
75
+ "expression": "foo.nested.*.{a: a,b: b}",
76
+ "result": [{"a": "first", "b": "second"},
77
+ {"a": "first", "b": "second"},
78
+ {"a": "first", "b": "second"}]
79
+ },
80
+ {
81
+ "expression": "foo.nested.three.{a: a, cinner: c.inner}",
82
+ "result": {"a": "first", "cinner": "third"}
83
+ },
84
+ {
85
+ "expression": "foo.nested.three.{a: a, c: c.inner.bad.key}",
86
+ "result": {"a": "first", "c": null}
87
+ },
88
+ {
89
+ "expression": "foo.{a: nested.one.a, b: nested.two.b}",
90
+ "result": {"a": "first", "b": "second"}
91
+ },
92
+ {
93
+ "expression": "{bar: bar, baz: baz}",
94
+ "result": {"bar": 1, "baz": 2}
95
+ },
96
+ {
97
+ "expression": "{bar: bar}",
98
+ "result": {"bar": 1}
99
+ },
100
+ {
101
+ "expression": "{otherkey: bar}",
102
+ "result": {"otherkey": 1}
103
+ },
104
+ {
105
+ "expression": "{no: no, exist: exist}",
106
+ "result": {"no": null, "exist": null}
107
+ },
108
+ {
109
+ "expression": "foo.[bar]",
110
+ "result": ["bar"]
111
+ },
112
+ {
113
+ "expression": "foo.[bar,baz]",
114
+ "result": ["bar", "baz"]
115
+ },
116
+ {
117
+ "expression": "foo.[bar,qux]",
118
+ "result": ["bar", "qux"]
119
+ },
120
+ {
121
+ "expression": "foo.[bar,noexist]",
122
+ "result": ["bar", null]
123
+ },
124
+ {
125
+ "expression": "foo.[noexist,alsonoexist]",
126
+ "result": [null, null]
127
+ }
128
+ ]
129
+ }, {
130
+ "given": {
131
+ "foo": {"bar": 1, "baz": [2, 3, 4]}
132
+ },
133
+ "cases": [
134
+ {
135
+ "expression": "foo.{bar:bar,baz:baz}",
136
+ "result": {"bar": 1, "baz": [2, 3, 4]}
137
+ },
138
+ {
139
+ "expression": "foo.[bar,baz[0]]",
140
+ "result": [1, 2]
141
+ },
142
+ {
143
+ "expression": "foo.[bar,baz[1]]",
144
+ "result": [1, 3]
145
+ },
146
+ {
147
+ "expression": "foo.[bar,baz[2]]",
148
+ "result": [1, 4]
149
+ },
150
+ {
151
+ "expression": "foo.[bar,baz[3]]",
152
+ "result": [1, null]
153
+ },
154
+ {
155
+ "expression": "foo.[bar[0],baz[3]]",
156
+ "result": [null, null]
157
+ }
158
+ ]
159
+ }, {
160
+ "given": {
161
+ "foo": {"bar": 1, "baz": 2}
162
+ },
163
+ "cases": [
164
+ {
165
+ "expression": "foo.{bar: bar, baz: baz}",
166
+ "result": {"bar": 1, "baz": 2}
167
+ },
168
+ {
169
+ "expression": "foo.[bar,baz]",
170
+ "result": [1, 2]
171
+ }
172
+ ]
173
+ }, {
174
+ "given": {
175
+ "foo": {
176
+ "bar": {"baz": [{"one": 1}, {"two": 2}]},
177
+ "ignoreme": 1,
178
+ "includeme": true
179
+ }
180
+ },
181
+ "cases": [
182
+ {
183
+ "expression": "foo.{bar: bar.baz[1],includeme: includeme}",
184
+ "result": {"bar": {"two": 2}, "includeme": true}
185
+ },
186
+ {
187
+ "expression": "foo.{\"bar.baz.two\": bar.baz[1].two, includeme: includeme}",
188
+ "result": {"bar.baz.two": 2, "includeme": true}
189
+ }
190
+ ]
191
+ }, {
192
+ "given": {
193
+ "reservations": [{
194
+ "instances": [
195
+ {"id": "id1",
196
+ "name": "first"},
197
+ {"id": "id2",
198
+ "name": "second"}
199
+ ]}, {
200
+ "instances": [
201
+ {"id": "id3",
202
+ "name": "third"},
203
+ {"id": "id4",
204
+ "name": "fourth"}
205
+ ]}
206
+ ]},
207
+ "cases": [
208
+ {
209
+ "expression": "reservations[*].instances[*].{id: id, name: name}",
210
+ "result": [[{"id": "id1", "name": "first"}, {"id": "id2", "name": "second"}],
211
+ [{"id": "id3", "name": "third"}, {"id": "id4", "name": "fourth"}]]
212
+ }
213
+ ]
214
+ }]
@@ -0,0 +1,46 @@
1
+ [{
2
+ "given":
3
+ {"outer": {"foo": "foo", "bar": "bar", "baz": "baz"}},
4
+ "cases": [
5
+ {
6
+ "expression": "outer.foo || outer.bar",
7
+ "result": "foo"
8
+ },
9
+ {
10
+ "expression": "outer.foo||outer.bar",
11
+ "result": "foo"
12
+ },
13
+ {
14
+ "expression": "outer.bar || outer.baz",
15
+ "result": "bar"
16
+ },
17
+ {
18
+ "expression": "outer.bar||outer.baz",
19
+ "result": "bar"
20
+ },
21
+ {
22
+ "expression": "outer.bad || outer.foo",
23
+ "result": "foo"
24
+ },
25
+ {
26
+ "expression": "outer.bad||outer.foo",
27
+ "result": "foo"
28
+ },
29
+ {
30
+ "expression": "outer.foo || outer.bad",
31
+ "result": "foo"
32
+ },
33
+ {
34
+ "expression": "outer.foo||outer.bad",
35
+ "result": "foo"
36
+ },
37
+ {
38
+ "expression": "outer.bad || outer.alsobad",
39
+ "result": null
40
+ },
41
+ {
42
+ "expression": "outer.bad||outer.alsobad",
43
+ "result": null
44
+ }
45
+ ]
46
+ }]
@@ -0,0 +1,100 @@
1
+ [{
2
+ "given": {
3
+ "foo": {
4
+ "bar": {
5
+ "baz": "one"
6
+ },
7
+ "other": {
8
+ "baz": "two"
9
+ },
10
+ "other2": {
11
+ "baz": "three"
12
+ },
13
+ "other3": {
14
+ "notbaz": ["a", "b", "c"]
15
+ },
16
+ "other4": {
17
+ "notbaz": ["d", "e", "f"]
18
+ }
19
+ }
20
+ },
21
+ "cases": [
22
+ {
23
+ "expression": "foo.*.baz",
24
+ "result": ["one", "two", "three"]
25
+ },
26
+ {
27
+ "expression": "foo.bar.*",
28
+ "result": ["one"]
29
+ },
30
+ {
31
+ "expression": "foo.*.notbaz",
32
+ "result": [["a", "b", "c"], ["d", "e", "f"]]
33
+ },
34
+ {
35
+ "expression": "foo.*.notbaz[0]",
36
+ "result": ["a", "d"]
37
+ },
38
+ {
39
+ "expression": "foo.*.notbaz[-1]",
40
+ "result": ["c", "f"]
41
+ },
42
+ {
43
+ "expression": "foo.*",
44
+ "result": [{"baz": "one"}, {"baz": "two"}, {"baz": "three"}, {"notbaz": ["a", "b", "c"]}, {"notbaz": ["d", "e", "f"]}]
45
+ },
46
+ {
47
+ "expression": "foo.*.*",
48
+ "result": null
49
+ },
50
+ {
51
+ "expression": "foo.*.*.*",
52
+ "result": null
53
+ },
54
+ {
55
+ "expression": "foo.*.*.*.*",
56
+ "result": null
57
+ }
58
+ ]
59
+ }, {
60
+ "given": {
61
+ "foo": {
62
+ "bar": "one"
63
+ },
64
+ "other": {
65
+ "bar": "two"
66
+ },
67
+ "nomatch": {
68
+ "notbar": "three"
69
+ }
70
+ },
71
+ "cases": [
72
+ {
73
+ "expression": "*.bar",
74
+ "result": ["one", "two"]
75
+ }
76
+ ]
77
+ }, {
78
+ "given": {
79
+ "top1": {
80
+ "sub1": {"foo": "one"}
81
+ },
82
+ "top2": {
83
+ "sub1": {"foo": "two"}
84
+ },
85
+ "top3": {
86
+ "sub3": {"notfoo": "notfoo"}
87
+ }
88
+ },
89
+ "cases": [
90
+ {
91
+ "expression": "*.*.foo",
92
+ "result": null
93
+ },
94
+ {
95
+ "expression": "*.sub1.foo",
96
+ "result": ["one", "two"]
97
+ }
98
+ ]
99
+ }
100
+ ]
@@ -0,0 +1,29 @@
1
+ require 'minitest/autorun'
2
+ require 'json'
3
+ require_relative '../lib/jamespath'
4
+
5
+ def compliance_test(file)
6
+ json = File.read(File.dirname(__FILE__) + '/compliance/' + file + '.json')
7
+ test_datas = JSON.parse(json)
8
+ describe "Compliance for #{file}.json" do
9
+ test_datas.each.with_index do |test_data, i|
10
+ describe "Given case #{i+1}" do
11
+ object = test_data['given']
12
+ test_data['cases'].each do |test_case|
13
+ expr, result = test_case['expression'], test_case['result']
14
+ it "handles '#{expr}'" do
15
+ Jamespath.search(expr, object).must_equal(result)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ describe "Compliance testing" do
24
+ compliance_test 'basic'
25
+ compliance_test 'escape'
26
+ compliance_test 'ormatch'
27
+ compliance_test 'wildcard'
28
+ compliance_test 'indices'
29
+ end
@@ -0,0 +1,23 @@
1
+ require 'minitest/autorun'
2
+ require_relative '../lib/jamespath'
3
+
4
+ describe "Struct" do
5
+
6
+ it "treats struct objects like hashes" do
7
+ struct_class = Struct.new(:foo, :bar)
8
+ data = struct_class.new(struct_class.new(nil, 'yuck'), nil)
9
+ Jamespath.search('foo.bar', data).must_equal('yuck')
10
+ end
11
+
12
+ it "selects all values from a struct" do
13
+ struct_class = Struct.new(:foo, :bar)
14
+ data = struct_class.new(nil, struct_class.new('f', 'b'))
15
+ Jamespath.search('bar.*', data).must_equal(['f', 'b'])
16
+ end
17
+
18
+ it "supports wildcard indexing on structs" do
19
+ struct_class = Struct.new(:foo, :bar)
20
+ data = struct_class.new('foo_value', 'bar_value')
21
+ Jamespath.search('[*]', data).must_equal(['foo', 'bar'])
22
+ end
23
+ end
@@ -0,0 +1,15 @@
1
+ require 'minitest/autorun'
2
+ require_relative '../lib/jamespath'
3
+
4
+ describe Jamespath::Tokenizer do
5
+
6
+ it "handles tokenization errors" do
7
+ err = nil
8
+ begin
9
+ Jamespath::Tokenizer.new.tokenize('foo.$%^&')
10
+ rescue SyntaxError => e
11
+ err = e
12
+ end
13
+ err.message.must_equal 'unexpected token at pos=4: $'
14
+ end
15
+ end
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jamespath
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0
5
+ platform: ruby
6
+ authors:
7
+ - Loren Segal
8
+ - Trevor Rowe
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-11-27 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: yard
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ~>
19
+ - !ruby/object:Gem::Version
20
+ version: '0.0'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ version: '0.0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rdiscount
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - '>='
33
+ - !ruby/object:Gem::Version
34
+ version: 2.1.7
35
+ - - <
36
+ - !ruby/object:Gem::Version
37
+ version: '3.0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - '>='
43
+ - !ruby/object:Gem::Version
44
+ version: 2.1.7
45
+ - - <
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ description: Like XPath, but for JSON and other structured objects.
49
+ email:
50
+ executables: []
51
+ extensions: []
52
+ extra_rdoc_files: []
53
+ files:
54
+ - .gitignore
55
+ - Gemfile
56
+ - LICENSE
57
+ - README.md
58
+ - Rakefile
59
+ - jamespath.gemspec
60
+ - lib/jamespath.rb
61
+ - lib/jamespath/parser.rb
62
+ - lib/jamespath/tokenizer.rb
63
+ - lib/jamespath/version.rb
64
+ - lib/jamespath/vm.rb
65
+ - test/compliance/basic.json
66
+ - test/compliance/escape.json
67
+ - test/compliance/indices.json
68
+ - test/compliance/multiselect.json
69
+ - test/compliance/ormatch.json
70
+ - test/compliance/wildcard.json
71
+ - test/compliance_test.rb
72
+ - test/struct_test.rb
73
+ - test/tokenizer_test.rb
74
+ homepage: http://github.com/lsegal/jamespath
75
+ licenses:
76
+ - MIT
77
+ metadata: {}
78
+ post_install_message:
79
+ rdoc_options: []
80
+ require_paths:
81
+ - lib
82
+ required_ruby_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - '>='
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ required_rubygems_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - '>='
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ requirements: []
93
+ rubyforge_project:
94
+ rubygems_version: 2.0.3
95
+ signing_key:
96
+ specification_version: 4
97
+ summary: Implements JMESpath declarative object searching.
98
+ test_files:
99
+ - test/compliance/basic.json
100
+ - test/compliance/escape.json
101
+ - test/compliance/indices.json
102
+ - test/compliance/multiselect.json
103
+ - test/compliance/ormatch.json
104
+ - test/compliance/wildcard.json
105
+ - test/compliance_test.rb
106
+ - test/struct_test.rb
107
+ - test/tokenizer_test.rb
108
+ has_rdoc: