jsonpath 0.0.3 → 0.1.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.
- data/README.rdoc +4 -4
- data/Rakefile +9 -1
- data/VERSION +1 -1
- data/jsonpath.gemspec +51 -0
- data/lib/jsonpath.rb +28 -19
- data/lib/jsonpath/{expression.rb → enumerable.rb} +10 -47
- data/spec/jsonpath_spec.rb +54 -52
- data/test/reference_test.rb +134 -0
- data/test/test_helper.rb +22 -0
- metadata +16 -7
- data/lib/jsonpath/wrapper.rb +0 -14
data/README.rdoc
CHANGED
@@ -4,7 +4,7 @@ This is an implementation of http://goessner.net/articles/JsonPath/.
|
|
4
4
|
|
5
5
|
== Usage
|
6
6
|
|
7
|
-
|
7
|
+
object = JSON.parse(<<-HERE_DOC))
|
8
8
|
{"store":
|
9
9
|
{"bicycle":
|
10
10
|
{"price":19.95, "color":"red"},
|
@@ -18,11 +18,11 @@ This is an implementation of http://goessner.net/articles/JsonPath/.
|
|
18
18
|
}
|
19
19
|
HERE_DOC
|
20
20
|
|
21
|
-
|
21
|
+
JsonPath.new('$..price').on(object).to_a
|
22
22
|
=> [19.95, 8.95, 12.99, 8.99, 22.99]
|
23
23
|
|
24
|
-
|
24
|
+
JsonPath.new('$..author').on(object).to_a
|
25
25
|
=> ["Nigel Rees", "Evelyn Waugh", "Herman Melville", "J. R. R. Tolkien"]
|
26
26
|
|
27
|
-
|
27
|
+
JsonPath.new('$..book[::2]').on(object).to_a
|
28
28
|
=> [{"price"=>8.95, "category"=>"reference", "author"=>"Nigel Rees", "title"=>"Sayings of the Century"}, {"price"=>8.99, "category"=>"fiction", "author"=>"Herman Melville", "title"=>"Moby Dick", "isbn"=>"0-553-21311-3"}]
|
data/Rakefile
CHANGED
@@ -8,7 +8,7 @@ begin
|
|
8
8
|
s.email = "joshbuddy@gmail.com"
|
9
9
|
s.homepage = "http://github.com/joshbuddy/jsonpath"
|
10
10
|
s.authors = ['Joshua Hull']
|
11
|
-
s.files =
|
11
|
+
s.files = `git ls-files`.split(/\n/)
|
12
12
|
end
|
13
13
|
Jeweler::GemcutterTasks.new
|
14
14
|
rescue LoadError
|
@@ -28,7 +28,15 @@ require 'spec'
|
|
28
28
|
require 'spec/rake/spectask'
|
29
29
|
|
30
30
|
Spec::Rake::SpecTask.new do |t|
|
31
|
+
t.ruby_opts = ['-rubygems']
|
31
32
|
t.spec_opts ||= []
|
32
33
|
t.spec_opts << "--options" << "spec/spec.opts"
|
33
34
|
t.spec_files = FileList['spec/*.rb']
|
34
35
|
end
|
36
|
+
|
37
|
+
#require 'rake/testtask'
|
38
|
+
#Rake::TestTask.new(:test) do |test|
|
39
|
+
# test.libs << 'lib' << 'test'
|
40
|
+
# test.pattern = 'test/**/*_test.rb'
|
41
|
+
# test.verbose = true
|
42
|
+
#end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0
|
1
|
+
0.1.0
|
data/jsonpath.gemspec
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{jsonpath}
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Joshua Hull"]
|
12
|
+
s.date = %q{2010-03-27}
|
13
|
+
s.description = %q{Ruby implementation of http://goessner.net/articles/JsonPath/}
|
14
|
+
s.email = %q{joshbuddy@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"README.rdoc"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
"README.rdoc",
|
20
|
+
"Rakefile",
|
21
|
+
"VERSION",
|
22
|
+
"jsonpath.gemspec",
|
23
|
+
"lib/jsonpath.rb",
|
24
|
+
"lib/jsonpath/enumerable.rb",
|
25
|
+
"spec/jsonpath_spec.rb",
|
26
|
+
"spec/spec.opts",
|
27
|
+
"spec/spec_helper.rb"
|
28
|
+
]
|
29
|
+
s.homepage = %q{http://github.com/joshbuddy/jsonpath}
|
30
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
31
|
+
s.require_paths = ["lib"]
|
32
|
+
s.rubygems_version = %q{1.3.6}
|
33
|
+
s.summary = %q{Ruby implementation of http://goessner.net/articles/JsonPath/}
|
34
|
+
s.test_files = [
|
35
|
+
"spec/jsonpath_spec.rb",
|
36
|
+
"spec/spec_helper.rb",
|
37
|
+
"test/reference_test.rb",
|
38
|
+
"test/test_helper.rb"
|
39
|
+
]
|
40
|
+
|
41
|
+
if s.respond_to? :specification_version then
|
42
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
43
|
+
s.specification_version = 3
|
44
|
+
|
45
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
46
|
+
else
|
47
|
+
end
|
48
|
+
else
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
data/lib/jsonpath.rb
CHANGED
@@ -1,25 +1,34 @@
|
|
1
|
-
|
2
|
-
require
|
3
|
-
|
1
|
+
require 'strscan'
|
2
|
+
require 'load_path_find'
|
3
|
+
|
4
|
+
$LOAD_PATH.add_current
|
5
|
+
|
6
|
+
require File.join('jsonpath', 'enumerable')
|
4
7
|
|
5
8
|
class JsonPath
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
|
10
|
+
attr_reader :path
|
11
|
+
|
12
|
+
def initialize(path)
|
13
|
+
scanner = StringScanner.new(path)
|
14
|
+
@path = []
|
15
|
+
bracket_count = 0
|
16
|
+
while not scanner.eos?
|
17
|
+
token = scanner.scan_until(/($|\$|@|[a-zA-Z]+|\[.*?\]|\.\.|\.(?!\.))/)
|
18
|
+
case token
|
19
|
+
when '.'
|
20
|
+
# do nothing
|
21
|
+
when /^[a-zA-Z]+$/
|
22
|
+
@path << "['#{token}']"
|
23
|
+
else
|
24
|
+
bracket_count == 0 && @path << token or @path[-1] += token
|
25
|
+
bracket_count += token.count('[') - token.count(']')
|
26
|
+
end
|
13
27
|
end
|
14
28
|
end
|
15
|
-
|
16
|
-
def
|
17
|
-
|
18
|
-
if block_given?
|
19
|
-
yield @wrapper
|
20
|
-
else
|
21
|
-
@wrapper
|
22
|
-
end
|
29
|
+
|
30
|
+
def on(object)
|
31
|
+
JsonPath::Enumerable.new(self, object)
|
23
32
|
end
|
24
|
-
|
33
|
+
|
25
34
|
end
|
@@ -1,44 +1,12 @@
|
|
1
|
-
require 'strscan'
|
2
|
-
|
3
1
|
class JsonPath
|
4
|
-
class
|
5
|
-
|
6
|
-
scanner = StringScanner.new(expression)
|
7
|
-
@path = []
|
8
|
-
bracket_count = 0
|
9
|
-
while not scanner.eos?
|
10
|
-
token = scanner.scan_until(/($|\$|@|[a-zA-Z]+|\[.*?\]|\.\.|\.(?!\.))/)
|
11
|
-
case token
|
12
|
-
when '.'
|
13
|
-
# do nothing
|
14
|
-
when /^[a-zA-Z]+$/
|
15
|
-
@path << "['#{token}']"
|
16
|
-
else
|
17
|
-
bracket_count == 0 && @path << token or @path[-1] += token
|
18
|
-
bracket_count += token.count('[') - token.count(']')
|
19
|
-
end
|
20
|
-
end
|
21
|
-
@object = object
|
22
|
-
end
|
2
|
+
class Enumerable
|
3
|
+
include ::Enumerable
|
23
4
|
|
24
|
-
def
|
25
|
-
|
26
|
-
false
|
5
|
+
def initialize(path, object)
|
6
|
+
@path, @object = path.path, object
|
27
7
|
end
|
28
8
|
|
29
|
-
def
|
30
|
-
store = []
|
31
|
-
each(node) {|o| store << o}
|
32
|
-
store
|
33
|
-
end
|
34
|
-
|
35
|
-
def map(node = @object)
|
36
|
-
store = []
|
37
|
-
each(node) {|o| store << (yield o)}
|
38
|
-
store
|
39
|
-
end
|
40
|
-
|
41
|
-
def each(node = @object, pos = 0, options = {}, &blk)
|
9
|
+
def each(node = @object, pos = 0, &blk)
|
42
10
|
if pos == @path.size
|
43
11
|
return blk.call(node)
|
44
12
|
else
|
@@ -59,14 +27,8 @@ class JsonPath
|
|
59
27
|
end
|
60
28
|
when ??
|
61
29
|
(node.is_a?(Hash) ? node.keys : (0..node.size)).each do |e|
|
62
|
-
::JsonPath.
|
63
|
-
|
64
|
-
begin
|
65
|
-
each(node[e], pos + 1, &blk) if jp.test?(node[e])
|
66
|
-
rescue
|
67
|
-
# ignore ..
|
68
|
-
end
|
69
|
-
end
|
30
|
+
subenum = ::JsonPath.new(sub_path[2,sub_path.size - 3]).on(node[e])
|
31
|
+
each(node[e], pos + 1, &blk) if subenum.any?{|n| true}
|
70
32
|
end
|
71
33
|
else
|
72
34
|
if node.is_a?(Array)
|
@@ -82,7 +44,7 @@ class JsonPath
|
|
82
44
|
else
|
83
45
|
blk.call(node) if pos == (@path.size - 1) && eval("node #{@path[pos]}")
|
84
46
|
end
|
85
|
-
|
47
|
+
|
86
48
|
if pos > 0 && @path[pos-1] == '..'
|
87
49
|
case node
|
88
50
|
when Hash
|
@@ -94,4 +56,5 @@ class JsonPath
|
|
94
56
|
end
|
95
57
|
end
|
96
58
|
end
|
97
|
-
end
|
59
|
+
end
|
60
|
+
|
data/spec/jsonpath_spec.rb
CHANGED
@@ -2,86 +2,88 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe "JsonPath" do
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
"
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
"
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
"
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
"
|
25
|
-
|
26
|
-
|
27
|
-
|
5
|
+
before(:each) do
|
6
|
+
@object = { "store"=> {
|
7
|
+
"book" => [
|
8
|
+
{ "category"=> "reference",
|
9
|
+
"author"=> "Nigel Rees",
|
10
|
+
"title"=> "Sayings of the Century",
|
11
|
+
"price"=> 8.95
|
12
|
+
},
|
13
|
+
{ "category"=> "fiction",
|
14
|
+
"author"=> "Evelyn Waugh",
|
15
|
+
"title"=> "Sword of Honour",
|
16
|
+
"price"=> 12.99
|
17
|
+
},
|
18
|
+
{ "category"=> "fiction",
|
19
|
+
"author"=> "Herman Melville",
|
20
|
+
"title"=> "Moby Dick",
|
21
|
+
"isbn"=> "0-553-21311-3",
|
22
|
+
"price"=> 8.99
|
23
|
+
},
|
24
|
+
{ "category"=> "fiction",
|
25
|
+
"author"=> "J. R. R. Tolkien",
|
26
|
+
"title"=> "The Lord of the Rings",
|
27
|
+
"isbn"=> "0-395-19395-8",
|
28
|
+
"price"=> 22.99
|
29
|
+
}
|
30
|
+
],
|
31
|
+
"bicycle"=> {
|
32
|
+
"color"=> "red",
|
33
|
+
"price"=> 19.95
|
28
34
|
}
|
29
|
-
],
|
30
|
-
"bicycle"=> {
|
31
|
-
"color"=> "red",
|
32
|
-
"price"=> 19.95
|
33
35
|
}
|
34
36
|
}
|
35
|
-
|
36
|
-
json = JsonPath.wrap(object)
|
37
|
+
end
|
38
|
+
#json = JsonPath.wrap(object)
|
37
39
|
|
38
40
|
it "should lookup a direct path" do
|
39
|
-
|
41
|
+
JsonPath.new('$.store.*').on(@object).to_a.first['book'].size.should == 4
|
40
42
|
end
|
41
43
|
|
42
44
|
it "should retrieve all authors" do
|
43
|
-
|
44
|
-
object['store']['book'][0]['author'],
|
45
|
-
object['store']['book'][1]['author'],
|
46
|
-
object['store']['book'][2]['author'],
|
47
|
-
object['store']['book'][3]['author']
|
45
|
+
JsonPath.new('$..author').on(@object).to_a.should == [
|
46
|
+
@object['store']['book'][0]['author'],
|
47
|
+
@object['store']['book'][1]['author'],
|
48
|
+
@object['store']['book'][2]['author'],
|
49
|
+
@object['store']['book'][3]['author']
|
48
50
|
]
|
49
51
|
end
|
50
52
|
|
51
53
|
it "should retrieve all prices" do
|
52
|
-
|
53
|
-
object['store']['bicycle']['price'],
|
54
|
-
object['store']['book'][0]['price'],
|
55
|
-
object['store']['book'][1]['price'],
|
56
|
-
object['store']['book'][2]['price'],
|
57
|
-
object['store']['book'][3]['price']
|
54
|
+
JsonPath.new('$..price').on(@object).to_a.should == [
|
55
|
+
@object['store']['bicycle']['price'],
|
56
|
+
@object['store']['book'][0]['price'],
|
57
|
+
@object['store']['book'][1]['price'],
|
58
|
+
@object['store']['book'][2]['price'],
|
59
|
+
@object['store']['book'][3]['price']
|
58
60
|
]
|
59
61
|
end
|
60
62
|
|
61
63
|
it "should recognize all types of array splices" do
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
64
|
+
JsonPath.new('$..book[0:1:1]').on(@object).to_a.should == [@object['store']['book'][0], @object['store']['book'][1]]
|
65
|
+
JsonPath.new('$..book[1::2]').on(@object).to_a.should == [@object['store']['book'][1], @object['store']['book'][3]]
|
66
|
+
JsonPath.new('$..book[::2]').on(@object).to_a.should == [@object['store']['book'][0], @object['store']['book'][2]]
|
67
|
+
JsonPath.new('$..book[:-2:2]').on(@object).to_a.should == [@object['store']['book'][0], @object['store']['book'][2]]
|
68
|
+
JsonPath.new('$..book[2::]').on(@object).to_a.should == [@object['store']['book'][2], @object['store']['book'][3]]
|
67
69
|
end
|
68
70
|
|
69
71
|
it "should recognize array comma syntax" do
|
70
|
-
|
71
|
-
|
72
|
+
JsonPath.new('$..book[0,1]').on(@object).to_a.should == [@object['store']['book'][0], @object['store']['book'][1]]
|
73
|
+
JsonPath.new('$..book[2,-1::]').on(@object).to_a.should == [@object['store']['book'][2], @object['store']['book'][3]]
|
72
74
|
end
|
73
75
|
|
74
76
|
it "should support filters" do
|
75
|
-
|
76
|
-
|
77
|
+
JsonPath.new("$..book[?(@['isbn'])]").on(@object).to_a.should == [@object['store']['book'][2], @object['store']['book'][3]]
|
78
|
+
JsonPath.new("$..book[?(@['price'] < 10)]").on(@object).to_a.should == [@object['store']['book'][0], @object['store']['book'][2]]
|
77
79
|
end
|
78
80
|
|
79
81
|
it "should support eval'd array indicies" do
|
80
|
-
|
82
|
+
JsonPath.new('$..book[(@.length-2)]').on(@object).to_a.should == [@object['store']['book'][2]]
|
81
83
|
end
|
82
84
|
|
83
85
|
it "should correct retrieve the right number of all nodes" do
|
84
|
-
|
86
|
+
JsonPath.new('$..*').on(@object).to_a.size.should == 28
|
85
87
|
end
|
86
88
|
|
87
89
|
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require File.dirname(__FILE__) << "/test_helper"
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
class ReferenceTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
context 'Sample 1' do
|
7
|
+
setup { @json = %({"a":"a","b":"b","c d":"e"}) }
|
8
|
+
#should 'resolve a simple path' do
|
9
|
+
# assert_resolves(object, "$.a", ["a"])
|
10
|
+
#end
|
11
|
+
#should 'resolve a path with quotes in brackets' do
|
12
|
+
# assert_resolves(object, "$['a']", ["a"])
|
13
|
+
#end
|
14
|
+
should 'resolve a path with a space' do
|
15
|
+
assert_resolves(object, "$.'c d'", ["e"])
|
16
|
+
end
|
17
|
+
#should 'resolve a star' do
|
18
|
+
# assert_resolves(object, "$.*", ["a", "b", "e"])
|
19
|
+
#end
|
20
|
+
#should 'resolve a star with quotes in brackets' do
|
21
|
+
# assert_resolves(object, "$['*']", ["a", "b", "e"])
|
22
|
+
#end
|
23
|
+
#should 'resolve a star with quotes' do
|
24
|
+
# assert_resolves(object, "$[*]", ["a", "b", "e"])
|
25
|
+
#end
|
26
|
+
end
|
27
|
+
#context 'Sample 2' do
|
28
|
+
# setup { @json = %([1, "2", 3.14, true, null]) }
|
29
|
+
# should 'resolve with a number in brackets' do
|
30
|
+
# assert_resolves(object, "$[0]", [1])
|
31
|
+
# end
|
32
|
+
# should 'resolve another number in brackets' do
|
33
|
+
# assert_resolves(object, "$[4]", [nil])
|
34
|
+
# end
|
35
|
+
# should 'resolve a star in brackets' do
|
36
|
+
# assert_resolves(object, "$[*]", [1, "2", 3.14, true, nil])
|
37
|
+
# end
|
38
|
+
# should 'resolve an end slice' do
|
39
|
+
# assert_resolves(object, "$[-1:]", [nil])
|
40
|
+
# end
|
41
|
+
#end
|
42
|
+
#context 'Sample 3' do
|
43
|
+
# setup { @json = %({"points":[{"id": "i1", "x": 4, "y": -5}, {"id": "i2", "x": -2, "y": 2, "z": 1}, {"id": "i3", "x": 8, "y": 3}, {"id": "i4", "x": -6, "y": -1}, {"id": "i5", "x": 0, "y": 2, "z": 1}, {"id": "i6", "x": 1, "y": 4}]}) }
|
44
|
+
# should 'resolve correctly' do
|
45
|
+
# assert_resolves(object, "$.points[1]", [{"id" => "i2", "x" => -2, "y" => 2, "z" => 1}])
|
46
|
+
# end
|
47
|
+
# should 'resolve a chained path' do
|
48
|
+
# assert_resolves(object, "$.points[4].x", [0])
|
49
|
+
# end
|
50
|
+
# should 'resolve by attribute match' do
|
51
|
+
# assert_resolves(object, "$.points[?(@['id']=='i4')].x", [-6])
|
52
|
+
# end
|
53
|
+
# should 'resolve a chained path with a star in brackets' do
|
54
|
+
# assert_resolves(object, "$.points[*].x", [4, -2, 8, -6, 0, 1])
|
55
|
+
# end
|
56
|
+
# should 'resolve by attribute operation' do
|
57
|
+
# assert_resolves(object, "$['points'][?(@['x']*@['x']+@['y']*@['y'] > 50)].id", ["i3"])
|
58
|
+
# end
|
59
|
+
# should 'resolve by attribute existence' do
|
60
|
+
# assert_resolves(object, "$.points[?(@['z'])].id", ["i2", "i5"])
|
61
|
+
# end
|
62
|
+
# should 'resolve by length property operation' do
|
63
|
+
# assert_resolves(object, "$.points[(@.length-1)].id", ["i6"])
|
64
|
+
# end
|
65
|
+
#end
|
66
|
+
#context 'Sample 4' do
|
67
|
+
# setup { @json = %({"menu":{"header":"SVG Viewer","items":[{"id": "Open"}, {"id": "OpenNew", "label": "Open New"}, null, {"id": "ZoomIn", "label": "Zoom In"}, {"id": "ZoomOut", "label": "Zoom Out"}, {"id": "OriginalView", "label": "Original View"}, null, {"id": "Quality"}, {"id": "Pause"}, {"id": "Mute"}, null, {"id": "Find", "label": "Find..."}, {"id": "FindAgain", "label": "Find Again"}, {"id": "Copy"}, {"id": "CopyAgain", "label": "Copy Again"}, {"id": "CopySVG", "label": "Copy SVG"}, {"id": "ViewSVG", "label": "View SVG"}, {"id": "ViewSource", "label": "View Source"}, {"id": "SaveAs", "label": "Save As"}, null, {"id": "Help"}, {"id": "About", "label": "About Adobe CVG Viewer..."}]}}) }
|
68
|
+
# should 'resolve testing on attribute' do
|
69
|
+
# assert_resolves(object, "$.menu.items[?(@ && @['id'] && !@['label'])].id", ["Open", "Quality", "Pause", "Mute", "Copy", "Help"])
|
70
|
+
# end
|
71
|
+
# should 'resolve testing on attribute with regular expression' do
|
72
|
+
# assert_resolves(object, "$.menu.items[?(@ && @['label'] && @['label'] =~ /SVG/)].id", ["CopySVG", "ViewSVG"])
|
73
|
+
# end
|
74
|
+
# should 'resolve on negative' do
|
75
|
+
# # !nil == true in Ruby
|
76
|
+
# assert_resolves(object, "$.menu.items[?(!@)]", [nil, nil, nil, nil])
|
77
|
+
# end
|
78
|
+
# should 'resolve descendant with number in brackets' do
|
79
|
+
# assert_resolves(object, "$..[0]", [{"id" => "Open"}])
|
80
|
+
# end
|
81
|
+
#end
|
82
|
+
#context 'Sample 5' do
|
83
|
+
# setup { @json = %({"a":[1, 2, 3, 4],"b":[5, 6, 7, 8]}) }
|
84
|
+
# should 'resolve descendant with number in brackets' do
|
85
|
+
# assert_resolves(object, "$..[0]", [1, 5])
|
86
|
+
# end
|
87
|
+
# should 'resolve descendant last items' do
|
88
|
+
# assert_resolves(object, "$..[-1:]", [4, 8])
|
89
|
+
# end
|
90
|
+
# should 'resolve by descendant value' do
|
91
|
+
# assert_resolves(object, "$..[?(@.is_a?(Numeric) && @ % 2 == 0)]", [2, 4, 6, 8])
|
92
|
+
# end
|
93
|
+
#end
|
94
|
+
#context 'Sample 6' do
|
95
|
+
# setup { @json = %({"lin":{"color":"red","x":2,"y":3},"cir":{"color":"blue","x":5,"y":2,"r":1},"arc":{"color":"green","x":2,"y":4,"r":2,"phi0":30,"dphi":120},"pnt":{"x":0,"y":7}}) }
|
96
|
+
# should 'resolve by operation in quotes' do
|
97
|
+
# assert_resolves(object, "$.'?(@['color'])'.x", [2, 5, 2])
|
98
|
+
# end
|
99
|
+
# should 'resolve by multiple quoted values in brackets' do
|
100
|
+
# assert_resolves(object, "$['lin','cir'].color", ["red", "blue"])
|
101
|
+
# end
|
102
|
+
#end
|
103
|
+
#context 'Sample 7' do
|
104
|
+
# setup { @json = %({"text":["hello", "world2.0"]}) }
|
105
|
+
# should 'resolve correctly filter 1' do
|
106
|
+
# assert_resolves(object, "$.text[?(@.length > 5)]", ["world2.0"])
|
107
|
+
# end
|
108
|
+
# should 'resolve correctly filter 2' do
|
109
|
+
# assert_resolves(object, "$.text[?(@[0, 1] == 'h')]", ["hello"])
|
110
|
+
# end
|
111
|
+
#end
|
112
|
+
#context 'Sample 8' do
|
113
|
+
# setup { @json = %({"a":{"a":2,"b":3},"b":{"a":4,"b":5},"c":{"a":{"a":6,"b":7},"c":8}}) }
|
114
|
+
# should 'resolve descendant' do
|
115
|
+
# assert_resolves(object, "$..a", [{"a" => 2, "b" => 3}, 2, 4, {"a" => 6, "b" => 7}, 6])
|
116
|
+
# end
|
117
|
+
#end
|
118
|
+
#context 'Sample 10' do
|
119
|
+
# setup { @json = %({"a":[{"a": 5, "@": 2, "$": 3}, {"a": 6, "@": 3, "$": 4}, {"a": 7, "@": 4, "$": 5}]}) }
|
120
|
+
# should 'resolve with quoted operation and escaped special character' do
|
121
|
+
# assert_resolves(object, "$.a[?(@['\\@']==3)]", [{"a" => 6, "@" => 3, "$" => 4}])
|
122
|
+
# end
|
123
|
+
# should 'resolve with quotes and brackets in operation' do
|
124
|
+
# assert_resolves(object, "$.a[?(@['$']==5)]", [{"a" => 7, "@" => 4, "$" => 5}])
|
125
|
+
# end
|
126
|
+
#end
|
127
|
+
|
128
|
+
private
|
129
|
+
|
130
|
+
def object
|
131
|
+
JSON.parse(@json)
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'shoulda'
|
4
|
+
|
5
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
6
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
7
|
+
require 'jsonpath'
|
8
|
+
|
9
|
+
class Test::Unit::TestCase
|
10
|
+
|
11
|
+
private
|
12
|
+
def assert_resolves(obj, path, result)
|
13
|
+
assert_equal safe_sort(result), safe_sort(JsonPath.new(path).on(obj).to_a)
|
14
|
+
end
|
15
|
+
|
16
|
+
def safe_sort(objs)
|
17
|
+
objs.sort_by do |obj|
|
18
|
+
obj ? obj.to_s : 0.to_s
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jsonpath
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- Joshua Hull
|
@@ -9,7 +14,7 @@ autorequire:
|
|
9
14
|
bindir: bin
|
10
15
|
cert_chain: []
|
11
16
|
|
12
|
-
date: 2010-
|
17
|
+
date: 2010-03-27 00:00:00 -04:00
|
13
18
|
default_executable:
|
14
19
|
dependencies: []
|
15
20
|
|
@@ -25,9 +30,9 @@ files:
|
|
25
30
|
- README.rdoc
|
26
31
|
- Rakefile
|
27
32
|
- VERSION
|
33
|
+
- jsonpath.gemspec
|
28
34
|
- lib/jsonpath.rb
|
29
|
-
- lib/jsonpath/
|
30
|
-
- lib/jsonpath/wrapper.rb
|
35
|
+
- lib/jsonpath/enumerable.rb
|
31
36
|
- spec/jsonpath_spec.rb
|
32
37
|
- spec/spec.opts
|
33
38
|
- spec/spec_helper.rb
|
@@ -44,21 +49,25 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
44
49
|
requirements:
|
45
50
|
- - ">="
|
46
51
|
- !ruby/object:Gem::Version
|
52
|
+
segments:
|
53
|
+
- 0
|
47
54
|
version: "0"
|
48
|
-
version:
|
49
55
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
50
56
|
requirements:
|
51
57
|
- - ">="
|
52
58
|
- !ruby/object:Gem::Version
|
59
|
+
segments:
|
60
|
+
- 0
|
53
61
|
version: "0"
|
54
|
-
version:
|
55
62
|
requirements: []
|
56
63
|
|
57
64
|
rubyforge_project:
|
58
|
-
rubygems_version: 1.3.
|
65
|
+
rubygems_version: 1.3.6
|
59
66
|
signing_key:
|
60
67
|
specification_version: 3
|
61
68
|
summary: Ruby implementation of http://goessner.net/articles/JsonPath/
|
62
69
|
test_files:
|
63
70
|
- spec/jsonpath_spec.rb
|
64
71
|
- spec/spec_helper.rb
|
72
|
+
- test/reference_test.rb
|
73
|
+
- test/test_helper.rb
|