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.
- 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
|