siren 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,181 @@
1
+ $dir = File.dirname(__FILE__)
2
+
3
+ require $dir + '/../lib/siren'
4
+ require 'test/unit'
5
+
6
+ Dir[$dir + '/fixtures/**/*.rb'].each { |fixture| require fixture }
7
+
8
+ $VERBOSE = nil
9
+
10
+ class SirenTest < Test::Unit::TestCase
11
+
12
+ def fixtures(name)
13
+ @fixtures ||= {}
14
+ @fixtures[name.to_sym] ||= Siren.parse(File.read("#{$dir}/fixtures/#{name}.json"))
15
+ end
16
+
17
+ def test_parser
18
+
19
+ assert_equal(
20
+ {"foo" => 12},
21
+ Siren.parse('{"foo": 12}') )
22
+
23
+ assert_equal(
24
+ {"foo" => {"something" => true}},
25
+ Siren.parse('{"foo": {"something": true}}') )
26
+
27
+ assert_equal(
28
+ {"list" => [1,2,"value"]},
29
+ Siren.parse('{"list": [1, 2, "value"]}') )
30
+
31
+ assert_equal(
32
+ {"list" => []},
33
+ Siren.parse(' { "list" : [ ] } ') )
34
+
35
+ assert_equal( {}, Siren.parse("{}") )
36
+ assert_equal( [], Siren.parse("[]") )
37
+ assert_equal( nil, Siren.parse("undefined") )
38
+
39
+ assert_equal( 'something "funny"', Siren.parse('{"key": "something \\"funny\\""}')["key"] )
40
+ end
41
+
42
+ def test_parser_with_callback
43
+ value = Siren.parse('{"list": [1,2,3,[56,34],4,5,6]}') do |holder, key, v|
44
+ Numeric === v ? key + v : v
45
+ end
46
+
47
+ assert_equal( {"list" => [1,3,5,[56,35],8,10,12]}, value )
48
+ end
49
+
50
+ def test_casting
51
+ mike = Person.new('ford')
52
+ bob = Person.new('bentley', 'ferrari', 'zonda')
53
+ assert_equal( {"people" => [mike, bob]}, fixtures(:people) )
54
+
55
+ assert_kind_of Person, Siren.parse('{"type": "person"}')
56
+ end
57
+
58
+ def test_referencing
59
+ person = fixtures(:refs).first
60
+ assert person.equal?(person["favourite"])
61
+ person = fixtures(:refs)[1]
62
+ assert person.equal?(person.favourite)
63
+
64
+ romeo, juliet = fixtures(:refs)[2..3]
65
+ assert romeo.equal?(juliet.favourite)
66
+ assert juliet.equal?(romeo.favourite)
67
+
68
+ assert_equal "romeo", romeo.handle
69
+
70
+ Siren.parse '[{"id": "whizz", "name": "jcoglan"}]'
71
+ assert_equal 'jcoglan', Siren.query("whizz.name", {})
72
+ end
73
+
74
+ def test_computation_expression
75
+ assert_equal 6, Siren.query("13 % 7", {})
76
+ assert_equal "foobar", Siren.query("'foo' + 'bar'", {:val => 7})
77
+ end
78
+
79
+ def test_field_access
80
+ assert_equal "FOO", Siren.query("$.upcase", "foo")
81
+ assert_equal 99, Siren.query("$['key']", {"key" => 99})
82
+ assert_equal 4, Siren.query("$.values[$.key]", {"key" => 2, "values" => [3,9,4,6]})
83
+ assert_equal 6, Siren.query("$['foo']", {'foo' => 6})
84
+ assert_equal [4,5], Siren.query("$[ 'foo', 'bar' ]", {'foo' => 4, 'bar' => 5})
85
+
86
+ doc = Siren.parse <<-JSON
87
+ {"id": "recursor", "rec": 6, "hmm": {"rec": 7}, "backref": {"$ref": "recursor"}}
88
+ JSON
89
+
90
+ assert_equal [6,7], Siren.query("$..rec", doc)
91
+ end
92
+
93
+ def test_array_filters
94
+ assert_equal 5, Siren.query("$.store.*", fixtures(:store)).flatten.size
95
+ assert_equal 2, Siren.query("$.store[*]", fixtures(:store)).size
96
+
97
+ assert_equal [5,6,7], Siren.query("$[? @ > 4 ]", 1..7)
98
+ assert_equal 1, Siren.query("$[? @ = ('foo')]", %w(bar foo baz)).size
99
+ assert_equal 2, Siren.query("$[?( @ != 'foo' )]", %w(bar foo baz)).size
100
+
101
+ data = {"keys" => [1,7,9,5,6], :values => [4,0,5,2,8,1,7,9]}
102
+ assert_equal 9, Siren.query("$.keys[? @ >= 9][0]", data)
103
+ assert_equal [1,3,4,5], Siren.query("$[? @ > 2 & @ < 6 | @ = 1]", 1..9)
104
+
105
+ assert_equal [2,4,6], Siren.query("$[1:5:2]", [1,2,3,4,5,6,7,8,9])
106
+ assert_equal [2,3,4,5,6], Siren.query("$[1:5]", [1,2,3,4,5,6,7,8,9])
107
+
108
+ assert_equal [0,3,6,9], Siren.query("$..[? @ % 3 = 0][/@]", {
109
+ "foo" => 4,
110
+ "bar" => 3,
111
+ "something" => {
112
+ "else" => 9,
113
+ "me" => [5,8,2,6,7,0]
114
+ }
115
+ })
116
+ end
117
+
118
+ def test_filters_with_cross_references
119
+ data = {"keys" => [1,7,9,5,6], :values => [4,0,5,2,8,1,7,9]}
120
+ assert_equal [4,0,5,2,1], Siren.query("$.values[? $.keys[? @ = 6][0] > @ ]", data)
121
+
122
+ assert_equal 2, Siren.query("$.data[? $.value != @]",
123
+ {"value" => "foo", "data" => %w(bar foo baz)}).size
124
+
125
+ assert_equal 9, Siren.query("$.key[? @ = ($.val - 2) + 4][0]",
126
+ {:key => [0,2,9,4,7], :val => 7})
127
+
128
+ assert_equal [7,8], Siren.query("$.val[? @ > $.key.*.size * 2]",
129
+ {:key => [9,5,7], :val => 1..8})
130
+ end
131
+
132
+ def test_string_matching
133
+ assert_equal ["Sayings of the Century", "The Lord of the Rings"],
134
+ Siren.query("$.store.book[? @.title = '* of the *'][= title]", fixtures(:store))
135
+
136
+ assert_equal [],
137
+ Siren.query("$.store.book[? @.title = '* Of the *'][= title]", fixtures(:store))
138
+
139
+ assert_equal ["Sayings of the Century", "The Lord of the Rings"],
140
+ Siren.query("$.store.book[? @.title ~ '* Of the *'][= title]", fixtures(:store))
141
+
142
+ assert_equal ["Sayings of the Century"],
143
+ Siren.query("$.store.book[? @.title = '??????? of the ???????'][= title]", fixtures(:store))
144
+
145
+ assert_equal [],
146
+ Siren.query("$.store.book[? @.title = '? of the ?'][= title]", fixtures(:store))
147
+
148
+ assert_equal '302 [QSA,L]', Siren.query("$[? @ = '302 [QSA,L]'][0]", ['302 [QSA,L]'])
149
+ end
150
+
151
+ def test_bookstore
152
+ assert_equal "The Lord of the Rings",
153
+ Siren.query("$.store.book[@.length - 1]", fixtures(:store))["title"]
154
+
155
+ assert_equal [ "Sayings of the Century", "The Lord of the Rings" ],
156
+ Siren.query("$.store.book[0,3]", fixtures(:store)).map { |b| b["title"] }
157
+
158
+ assert_equal [ "Sayings of the Century", "Sword of Honour",
159
+ "Moby Dick", "The Lord of the Rings" ],
160
+ Siren.query("$.store.book[=title ]", fixtures(:store))
161
+ end
162
+
163
+ def test_sorting
164
+ assert_equal [ "Moby Dick", "Sayings of the Century",
165
+ "Sword of Honour", "The Lord of the Rings" ],
166
+ Siren.query("$.store.book[/title][= @.title ]", fixtures(:store))
167
+
168
+ assert_equal ["Nigel Rees", "J. R. R. Tolkien", "Herman Melville", "Evelyn Waugh"],
169
+ Siren.query("$.store.book[= author ][\\ @]", fixtures(:store))
170
+
171
+ assert_equal [ "Jonny Greenwood", "Colin Greenwood", "Ed O'Brien",
172
+ "Phil Selway", "Thom Yorke" ],
173
+ Siren.query("$[ /last, \\ @.first]", fixtures(:names)).
174
+ map { |n| "#{ n['first'] } #{ n['last'] }" }
175
+ end
176
+
177
+ def test_embeded_queries
178
+ assert_equal %w[John Paul], fixtures(:beatles)['adults'].map { |b| b['name'] }
179
+ end
180
+ end
181
+
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: siren
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - James Coglan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-07-07 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: treetop
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: eventful
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: hoe
37
+ type: :development
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 2.3.2
44
+ version:
45
+ description: ""
46
+ email:
47
+ - jcoglan@googlemail.com
48
+ executables: []
49
+
50
+ extensions: []
51
+
52
+ extra_rdoc_files:
53
+ - History.txt
54
+ - Manifest.txt
55
+ - README.txt
56
+ files:
57
+ - History.txt
58
+ - Manifest.txt
59
+ - README.txt
60
+ - Rakefile
61
+ - lib/siren.rb
62
+ - lib/siren/json.tt
63
+ - lib/siren/json.rb
64
+ - lib/siren/json_query.tt
65
+ - lib/siren/json_query.rb
66
+ - lib/siren/json_query_nodes.rb
67
+ - lib/siren/node.rb
68
+ - lib/siren/parser.rb
69
+ - lib/siren/reference.rb
70
+ - lib/siren/walker.rb
71
+ - test/test_siren.rb
72
+ - test/fixtures/beatles.json
73
+ - test/fixtures/car.rb
74
+ - test/fixtures/names.json
75
+ - test/fixtures/people.json
76
+ - test/fixtures/person.rb
77
+ - test/fixtures/refs.json
78
+ - test/fixtures/store.json
79
+ has_rdoc: true
80
+ homepage: http://github.com/jcoglan/siren
81
+ licenses: []
82
+
83
+ post_install_message:
84
+ rdoc_options:
85
+ - --main
86
+ - README.txt
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: "0"
94
+ version:
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: "0"
100
+ version:
101
+ requirements: []
102
+
103
+ rubyforge_project: siren
104
+ rubygems_version: 1.3.3
105
+ signing_key:
106
+ specification_version: 3
107
+ summary: ""
108
+ test_files:
109
+ - test/test_siren.rb