siren 0.2.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,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