siren 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +16 -0
- data/Manifest.txt +22 -0
- data/README.txt +318 -0
- data/Rakefile +19 -0
- data/lib/siren.rb +76 -0
- data/lib/siren/json.rb +1039 -0
- data/lib/siren/json.tt +86 -0
- data/lib/siren/json_query.rb +2414 -0
- data/lib/siren/json_query.tt +184 -0
- data/lib/siren/json_query_nodes.rb +333 -0
- data/lib/siren/node.rb +37 -0
- data/lib/siren/parser.rb +205 -0
- data/lib/siren/reference.rb +30 -0
- data/lib/siren/walker.rb +33 -0
- data/test/fixtures/beatles.json +11 -0
- data/test/fixtures/car.rb +14 -0
- data/test/fixtures/names.json +7 -0
- data/test/fixtures/people.json +34 -0
- data/test/fixtures/person.rb +15 -0
- data/test/fixtures/refs.json +26 -0
- data/test/fixtures/store.json +32 -0
- data/test/test_siren.rb +181 -0
- metadata +109 -0
data/test/test_siren.rb
ADDED
@@ -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
|