json_select 0.1.0 → 0.1.1
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/.travis.yml +7 -0
- data/Gemfile +1 -0
- data/Rakefile +5 -0
- data/lib/json_select.rb +8 -13
- data/lib/json_select/ast/combination_selector.rb +5 -5
- data/lib/json_select/ast/complex_expr.rb +7 -7
- data/lib/json_select/ast/even_expr.rb +3 -3
- data/lib/json_select/ast/hash_selector.rb +3 -3
- data/lib/json_select/ast/odd_expr.rb +3 -3
- data/lib/json_select/ast/pseudo_selector.rb +9 -9
- data/lib/json_select/ast/simple_expr.rb +3 -3
- data/lib/json_select/ast/type_selector.rb +3 -3
- data/lib/json_select/selector.rb +140 -58
- data/lib/json_select/selector_parser.rb +272 -113
- data/lib/json_select/selector_parser.tt +21 -25
- data/lib/json_select/version.rb +2 -2
- data/spec/conformance_spec.rb +26 -12
- data/spec/fixtures/basic_children.ast +6 -0
- data/spec/fixtures/basic_children.output +1 -0
- data/spec/fixtures/basic_children.selector +1 -0
- data/spec/fixtures/basic_combination.ast +5 -0
- data/spec/fixtures/basic_combination.output +1 -0
- data/spec/fixtures/basic_combination.selector +1 -0
- data/spec/fixtures/basic_universal.output +2 -1
- data/spec/ruby_extensions_spec.rb +28 -0
- metadata +17 -3
- data/lib/json_select/parser.rb +0 -19
@@ -1,11 +1,10 @@
|
|
1
|
-
|
2
|
-
grammar SelectorParser
|
1
|
+
grammar JSONSelectSelector
|
3
2
|
|
4
3
|
# selectors_group
|
5
4
|
# : selector [ `,` selector ]*
|
6
5
|
# ;
|
7
6
|
rule selectors_group
|
8
|
-
a:selector b:( ',' c:selector )* <JSONSelect::Ast::SelectorGroup>
|
7
|
+
ws* a:selector b:( ws* ',' ws* c:selector )* ws* <JSONSelect::Ast::SelectorGroup>
|
9
8
|
end
|
10
9
|
|
11
10
|
# selector
|
@@ -19,7 +18,7 @@ grammar SelectorParser
|
|
19
18
|
# : `>` | \s+
|
20
19
|
# ;
|
21
20
|
rule combinator
|
22
|
-
'>' /
|
21
|
+
(ws* '>' ws* ) / (ws+)
|
23
22
|
end
|
24
23
|
|
25
24
|
# simple_selector_sequence
|
@@ -40,14 +39,14 @@ grammar SelectorParser
|
|
40
39
|
rule type_selector
|
41
40
|
('object' / 'array' / 'number' / 'string' / 'boolean' / 'null') <JSONSelect::Ast::TypeSelector>
|
42
41
|
end
|
43
|
-
|
42
|
+
|
44
43
|
# universal
|
45
44
|
# : '*'
|
46
45
|
# ;
|
47
46
|
rule universal
|
48
47
|
'*' <JSONSelect::Ast::UniversalSelector>
|
49
48
|
end
|
50
|
-
|
49
|
+
|
51
50
|
# hash
|
52
51
|
# : `.` name
|
53
52
|
# | `.` json_string
|
@@ -63,8 +62,8 @@ grammar SelectorParser
|
|
63
62
|
# | `:` pseudo_function_name `(` expression `)`
|
64
63
|
# ;
|
65
64
|
rule pseudo
|
66
|
-
( ':' a:pseudo_class_name <JSONSelect::Ast::PseudoSelector> ) /
|
67
|
-
( ':' a:pseudo_function_name '(' e:expression ')' <JSONSelect::Ast::PseudoSelector> )
|
65
|
+
( ':' a:pseudo_class_name <JSONSelect::Ast::PseudoSelector> ) /
|
66
|
+
( ':' a:pseudo_function_name '(' ws* e:expression ws* ')' <JSONSelect::Ast::PseudoSelector> )
|
68
67
|
end
|
69
68
|
|
70
69
|
# pseudo_class_name
|
@@ -72,7 +71,7 @@ grammar SelectorParser
|
|
72
71
|
rule pseudo_class_name
|
73
72
|
'root' / 'first-child' / 'last-child' / 'only-child'
|
74
73
|
end
|
75
|
-
|
74
|
+
|
76
75
|
# pseudo_function_name
|
77
76
|
# : `nth-child` | `nth-last-child`
|
78
77
|
rule pseudo_function_name
|
@@ -83,26 +82,20 @@ grammar SelectorParser
|
|
83
82
|
# /* expression is and of the form "an+b" */
|
84
83
|
# : TODO
|
85
84
|
# ;
|
86
|
-
# /^ \(
|
87
|
-
# (?: ([+-]?) ([0-9]*) n (?:([+-]) ([0-9]) )?
|
88
|
-
# | (odd|even)
|
89
|
-
# | ( [+-]? [0-9]+ )
|
90
|
-
# )
|
91
|
-
# \) /;
|
92
85
|
rule expression
|
93
86
|
('odd' <JSONSelect::Ast::OddExpr> ) /
|
94
87
|
('even' <JSONSelect::Ast::EvenExpr>) /
|
95
|
-
( a:[+-]? b:[0-9]* 'n' c:( [+-] [0-9] )? <JSONSelect::Ast::ComplexExpr> ) /
|
88
|
+
( a:[+-]? b:[0-9]* 'n' ws* c:( [+-] ws* [0-9] )? <JSONSelect::Ast::ComplexExpr> ) /
|
96
89
|
( [+-]? [0-9]+ <JSONSelect::Ast::SimpleExpr> )
|
97
90
|
end
|
98
|
-
|
91
|
+
|
99
92
|
# json_string
|
100
93
|
# : `"` json_chars* `"`
|
101
94
|
# ;
|
102
95
|
rule json_string
|
103
96
|
["] json_chars* ["]
|
104
97
|
end
|
105
|
-
|
98
|
+
|
106
99
|
# json_chars
|
107
100
|
# : any-Unicode-character-except-"-or-\-or-control-character
|
108
101
|
# | `\"`
|
@@ -113,27 +106,27 @@ grammar SelectorParser
|
|
113
106
|
# | `\n`
|
114
107
|
# | `\r`
|
115
108
|
# | `\t`
|
116
|
-
# | \u four-hex-digits
|
109
|
+
# | \u four-hex-digits
|
117
110
|
# ;
|
118
111
|
rule json_chars
|
119
112
|
[^\\"] /
|
120
113
|
( [\\] ["\\/bfnrt] )
|
121
114
|
end
|
122
|
-
|
115
|
+
|
123
116
|
# name
|
124
117
|
# : nmstart nmchar*
|
125
118
|
# ;
|
126
119
|
rule name
|
127
120
|
nmstart nmchar*
|
128
121
|
end
|
129
|
-
|
122
|
+
|
130
123
|
# nmstart
|
131
124
|
# : escape | [_a-zA-Z] | nonascii
|
132
125
|
# ;
|
133
126
|
rule nmstart
|
134
127
|
escape / [_a-zA-Z] / nonascii
|
135
128
|
end
|
136
|
-
|
129
|
+
|
137
130
|
# nmchar
|
138
131
|
# : [_a-zA-Z0-9-]
|
139
132
|
# | escape
|
@@ -143,13 +136,13 @@ grammar SelectorParser
|
|
143
136
|
[_a-zA-Z0-9-] / escape / nonascii
|
144
137
|
end
|
145
138
|
|
146
|
-
# escape
|
139
|
+
# escape
|
147
140
|
# : \\[^\r\n\f0-9a-fA-F]
|
148
141
|
# ;
|
149
142
|
rule escape
|
150
143
|
[\\] [^\r\n\f0-9a-fA-F]
|
151
144
|
end
|
152
|
-
|
145
|
+
|
153
146
|
# nonascii
|
154
147
|
# : [^\0-0177]
|
155
148
|
# ;
|
@@ -157,5 +150,8 @@ grammar SelectorParser
|
|
157
150
|
[^\0-0177]
|
158
151
|
end
|
159
152
|
|
160
|
-
|
153
|
+
rule ws
|
154
|
+
[ \t\r\n]
|
155
|
+
end
|
156
|
+
|
161
157
|
end
|
data/lib/json_select/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
VERSION = "0.1.
|
1
|
+
class JSONSelect
|
2
|
+
VERSION = "0.1.1"
|
3
3
|
end
|
data/spec/conformance_spec.rb
CHANGED
@@ -1,41 +1,55 @@
|
|
1
1
|
describe "JSONSelect", "conformance" do
|
2
|
-
|
2
|
+
|
3
3
|
%w( basic ).each do |test|
|
4
4
|
selectors = "../fixtures/#{test}_*.selector"
|
5
5
|
selectors = Dir[File.expand_path(selectors, __FILE__)]
|
6
|
-
|
6
|
+
|
7
7
|
describe "(#{test})" do
|
8
|
-
|
8
|
+
|
9
9
|
let(:input) do
|
10
10
|
path = File.expand_path("../fixtures/#{test}.json", __FILE__)
|
11
11
|
Yajl::Parser.parse(File.read(path))
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
selectors.each do |selector|
|
15
15
|
basename = File.basename(selector, '.selector')
|
16
16
|
name = basename[(test.size + 1)..-1]
|
17
17
|
output = File.expand_path("../fixtures/#{basename}.output", __FILE__)
|
18
18
|
ast = File.expand_path("../fixtures/#{basename}.ast", __FILE__)
|
19
|
-
|
19
|
+
|
20
20
|
describe "(#{name})" do
|
21
|
-
|
21
|
+
|
22
22
|
it "parses the selector" do
|
23
23
|
ast = Yajl::Parser.parse(File.read(ast))
|
24
24
|
s = JSONSelect(File.read(selector).strip)
|
25
|
-
s.should be_a(JSONSelect
|
26
|
-
s.ast.should == ast
|
25
|
+
s.should be_a(JSONSelect)
|
26
|
+
Yajl::Parser.parse(Yajl::Encoder.encode(s.ast)).should == ast
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
it "produces the correct output" do
|
30
30
|
s = JSONSelect(File.read(selector).strip)
|
31
31
|
e = []
|
32
32
|
Yajl::Parser.parse(File.read(output)) { |o| e << o }
|
33
|
-
s.
|
33
|
+
s.matches(input).should == e
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
|
+
it "finds the first matching child" do
|
37
|
+
s = JSONSelect(File.read(selector).strip)
|
38
|
+
e = []
|
39
|
+
Yajl::Parser.parse(File.read(output)) { |o| e << o }
|
40
|
+
s.match(input).should == e.first
|
41
|
+
end
|
42
|
+
|
43
|
+
it "can correctly test the object" do
|
44
|
+
s = JSONSelect(File.read(selector).strip)
|
45
|
+
e = []
|
46
|
+
Yajl::Parser.parse(File.read(output)) { |o| e << o }
|
47
|
+
s.test(input).should be_true
|
48
|
+
end
|
49
|
+
|
36
50
|
end
|
37
51
|
end
|
38
|
-
|
52
|
+
|
39
53
|
end
|
40
54
|
end
|
41
55
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
"Lloyd"
|
@@ -0,0 +1 @@
|
|
1
|
+
.name > .first
|
@@ -0,0 +1 @@
|
|
1
|
+
"Lloyd"
|
@@ -0,0 +1 @@
|
|
1
|
+
.name .first
|
@@ -0,0 +1,28 @@
|
|
1
|
+
describe "JSONSelect", "Ruby extensions" do
|
2
|
+
|
3
|
+
it "treats Symbol keys as Strings" do
|
4
|
+
JSONSelect('.name .first').
|
5
|
+
match(:name => { :first => 'hello' }).
|
6
|
+
should == 'hello'
|
7
|
+
end
|
8
|
+
|
9
|
+
it "treats Symbol values as Strings" do
|
10
|
+
JSONSelect('.name string.uid').
|
11
|
+
match(:name => { :uid => :hello }).
|
12
|
+
should == :hello
|
13
|
+
end
|
14
|
+
|
15
|
+
it "treats Objects which respond to #json_select_each as Objects" do
|
16
|
+
class Person < Struct.new(:name, :age)
|
17
|
+
def json_select_each
|
18
|
+
yield(:name, self.name)
|
19
|
+
yield(:age, self.age)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
JSONSelect('object.person string.name').
|
24
|
+
match(:person => Person.new('Simon Menke', 24)).
|
25
|
+
should == 'Simon Menke'
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: json_select
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.1.
|
5
|
+
version: 0.1.1
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Simon Menke
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-05-
|
13
|
+
date: 2011-05-24 00:00:00 +02:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -35,6 +35,7 @@ extra_rdoc_files: []
|
|
35
35
|
|
36
36
|
files:
|
37
37
|
- .gitignore
|
38
|
+
- .travis.yml
|
38
39
|
- Gemfile
|
39
40
|
- LICENSE
|
40
41
|
- README.md
|
@@ -52,7 +53,6 @@ files:
|
|
52
53
|
- lib/json_select/ast/simple_selector.rb
|
53
54
|
- lib/json_select/ast/type_selector.rb
|
54
55
|
- lib/json_select/ast/universal_selector.rb
|
55
|
-
- lib/json_select/parser.rb
|
56
56
|
- lib/json_select/selector.rb
|
57
57
|
- lib/json_select/selector_parser.rb
|
58
58
|
- lib/json_select/selector_parser.tt
|
@@ -62,6 +62,12 @@ files:
|
|
62
62
|
- spec/fixtures/alltests.txt
|
63
63
|
- spec/fixtures/basic.json
|
64
64
|
- spec/fixtures/basic.xml
|
65
|
+
- spec/fixtures/basic_children.ast
|
66
|
+
- spec/fixtures/basic_children.output
|
67
|
+
- spec/fixtures/basic_children.selector
|
68
|
+
- spec/fixtures/basic_combination.ast
|
69
|
+
- spec/fixtures/basic_combination.output
|
70
|
+
- spec/fixtures/basic_combination.selector
|
65
71
|
- spec/fixtures/basic_first-child.ast
|
66
72
|
- spec/fixtures/basic_first-child.output
|
67
73
|
- spec/fixtures/basic_first-child.selector
|
@@ -107,6 +113,7 @@ files:
|
|
107
113
|
- spec/fixtures/basic_universal.ast
|
108
114
|
- spec/fixtures/basic_universal.output
|
109
115
|
- spec/fixtures/basic_universal.selector
|
116
|
+
- spec/ruby_extensions_spec.rb
|
110
117
|
- spec/spec_helper.rb
|
111
118
|
has_rdoc: true
|
112
119
|
homepage: http://github.com/fd/json_select
|
@@ -142,6 +149,12 @@ test_files:
|
|
142
149
|
- spec/fixtures/alltests.txt
|
143
150
|
- spec/fixtures/basic.json
|
144
151
|
- spec/fixtures/basic.xml
|
152
|
+
- spec/fixtures/basic_children.ast
|
153
|
+
- spec/fixtures/basic_children.output
|
154
|
+
- spec/fixtures/basic_children.selector
|
155
|
+
- spec/fixtures/basic_combination.ast
|
156
|
+
- spec/fixtures/basic_combination.output
|
157
|
+
- spec/fixtures/basic_combination.selector
|
145
158
|
- spec/fixtures/basic_first-child.ast
|
146
159
|
- spec/fixtures/basic_first-child.output
|
147
160
|
- spec/fixtures/basic_first-child.selector
|
@@ -187,4 +200,5 @@ test_files:
|
|
187
200
|
- spec/fixtures/basic_universal.ast
|
188
201
|
- spec/fixtures/basic_universal.output
|
189
202
|
- spec/fixtures/basic_universal.selector
|
203
|
+
- spec/ruby_extensions_spec.rb
|
190
204
|
- spec/spec_helper.rb
|
data/lib/json_select/parser.rb
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
class JSONSelect::Parser
|
2
|
-
|
3
|
-
def initialize(source)
|
4
|
-
@parser = JSONSelect::SelectorParserParser.new
|
5
|
-
@source = source
|
6
|
-
end
|
7
|
-
|
8
|
-
def parse
|
9
|
-
tree = @parser.parse(@source)
|
10
|
-
if tree
|
11
|
-
JSONSelect::Selector.new(tree.to_ast)
|
12
|
-
else
|
13
|
-
raise JSONSelect::ParseError, @parser.failure_reason
|
14
|
-
# puts parser.failure_line
|
15
|
-
# puts parser.failure_column
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
end
|