Parsing support for more XPath operators.

This still messes up some tests due to botched token precedence (by the looks
of it).
This commit is contained in:
Yorick Peterse committed 2014-06-22 21:27:53 +02:00
1 parent 514c342cab
commit 6a2f4fa82d
4 files changed
+298 -35

No files matched your search

@@ -0,0 +1,148 @@
require 'spec_helper'
describe Oga::XPath::Parser do
context 'operator precedence' do
example 'parse "A or B or C"' do
parse_xpath('A or B or C').should == s(
:path,
s(
:or,
s(:or, s(:test, nil, 'A'), s(:test, nil, 'B')),
s(:test, nil, 'C')
)
)
end
example 'parse "A and B and C"' do
parse_xpath('A and B and C').should == s(
:path,
s(
:and,
s(:and, s(:test, nil, 'A'), s(:test, nil, 'B')),
s(:test, nil, 'C')
)
)
end
example 'parse "A = B = C"' do
parse_xpath('A = B = C').should == s(
:path,
s(
:eq,
s(:eq, s(:test, nil, 'A'), s(:test, nil, 'B')),
s(:test, nil, 'C')
)
)
end
example 'parse "A != B != C"' do
parse_xpath('A != B != C').should == s(
:path,
s(
:neq,
s(:neq, s(:test, nil, 'A'), s(:test, nil, 'B')),
s(:test, nil, 'C')
)
)
end
example 'parse "A <= B <= C"' do
parse_xpath('A <= B <= C').should == s(
:path,
s(
:lte,
s(:lte, s(:test, nil, 'A'), s(:test, nil, 'B')),
s(:test, nil, 'C')
)
)
end
example 'parse "A < B < C"' do
parse_xpath('A < B < C').should == s(
:path,
s(
:lt,
s(:lt, s(:test, nil, 'A'), s(:test, nil, 'B')),
s(:test, nil, 'C')
)
)
end
example 'parse "A >= B >= C"' do
parse_xpath('A >= B >= C').should == s(
:path,
s(
:gte,
s(:gte, s(:test, nil, 'A'), s(:test, nil, 'B')),
s(:test, nil, 'C')
)
)
end
example 'parse "A > B > C"' do
parse_xpath('A > B > C').should == s(
:path,
s(
:gt,
s(:gt, s(:test, nil, 'A'), s(:test, nil, 'B')),
s(:test, nil, 'C')
)
)
end
example 'parse "A or B and C"' do
parse_xpath('A or B and C').should == s(
:path,
s(
:and,
s(:or, s(:test, nil, 'A'), s(:test, nil, 'B')),
s(:test, nil, 'C')
)
)
end
example 'parse "A and B = C"' do
parse_xpath('A and B = C').should == s(
:path,
s(
:eq,
s(:and, s(:test, nil, 'A'), s(:test, nil, 'B')),
s(:test, nil, 'C')
)
)
end
example 'parse "A = B < C"' do
parse_xpath('A = B < C').should == s(
:path,
s(
:lt,
s(:eq, s(:test, nil, 'A'), s(:test, nil, 'B')),
s(:test, nil, 'C')
)
)
end
example 'parse "A < B | C"' do
parse_xpath('A < B | C').should == s(
:path,
s(
:lt,
s(:test, nil, 'A'),
s(:pipe, s(:test, nil, 'B'), s(:test, nil, 'C'))
)
)
end
example 'parse "A > B or C"' do
parse_xpath('A > B or C').should == s(
:path,
s(
:or,
s(:gt, s(:test, nil, 'A'), s(:test, nil, 'B')),
s(:test, nil, 'C')
)
)
end
end
end
+103
View File
@@ -0,0 +1,103 @@
require 'spec_helper'
describe Oga::XPath::Parser do
context 'operators' do
example 'parse the pipe operator' do
parse_xpath('A | B').should == s(
:path,
s(:pipe, s(:test, nil, 'A'), s(:test, nil, 'B'))
)
end
example 'parse the and operator' do
parse_xpath('A and B').should == s(
:path,
s(:and, s(:test, nil, 'A'), s(:test, nil, 'B'))
)
end
example 'parse the or operator' do
parse_xpath('A or B').should == s(
:path,
s(:or, s(:test, nil, 'A'), s(:test, nil, 'B'))
)
end
example 'parse the plus operator' do
parse_xpath('A + B').should == s(
:path,
s(:add, s(:test, nil, 'A'), s(:test, nil, 'B'))
)
end
example 'parse the div operator' do
parse_xpath('A div B').should == s(
:path,
s(:div, s(:test, nil, 'A'), s(:test, nil, 'B'))
)
end
example 'parse the mod operator' do
parse_xpath('A mod B').should == s(
:path,
s(:mod, s(:test, nil, 'A'), s(:test, nil, 'B'))
)
end
example 'parse the equals operator' do
parse_xpath('A = B').should == s(
:path,
s(:eq, s(:test, nil, 'A'), s(:test, nil, 'B'))
)
end
example 'parse the not-equals operator' do
parse_xpath('A != B').should == s(
:path,
s(:neq, s(:test, nil, 'A'), s(:test, nil, 'B'))
)
end
example 'parse the lower-than operator' do
parse_xpath('A < B').should == s(
:path,
s(:lt, s(:test, nil, 'A'), s(:test, nil, 'B'))
)
end
example 'parse the greater-than operator' do
parse_xpath('A > B').should == s(
:path,
s(:gt, s(:test, nil, 'A'), s(:test, nil, 'B'))
)
end
example 'parse the lower-or-equal operator' do
parse_xpath('A <= B').should == s(
:path,
s(:lte, s(:test, nil, 'A'), s(:test, nil, 'B'))
)
end
example 'parse the greater-or-equal operator' do
parse_xpath('A >= B').should == s(
:path,
s(:gte, s(:test, nil, 'A'), s(:test, nil, 'B'))
)
end
example 'parse the mul operator' do
parse_xpath('A * B').should == s(
:path,
s(:mul, s(:test, nil, 'A'), s(:test, nil, 'B'))
)
end
example 'parse the subtraction operator' do
parse_xpath('A - B').should == s(
:path,
s(:sub, s(:test, nil, 'A'), s(:test, nil, 'B'))
)
end
end
end
+24 -30
View File
@@ -3,21 +3,18 @@ require 'spec_helper'
describe Oga::XPath::Parser do
context 'predicates' do
example 'parse a single predicate' do
parse_xpath('/foo[@class="bar"]').should == s(
:absolute,
parse_xpath('foo[@class="bar"]').should == s(
:path,
s(
:path,
:test,
nil,
'foo',
s(
:test,
nil,
'foo',
:path,
s(
:path,
s(
:eq,
s(:axis, 'attribute', s(:test, nil, 'class')),
s(:string, 'bar')
)
:eq,
s(:axis, 'attribute', s(:test, nil, 'class')),
s(:string, 'bar')
)
)
)
@@ -25,28 +22,25 @@ describe Oga::XPath::Parser do
end
example 'parse a predicate using the or operator' do
parse_xpath('/foo[@class="bar" or @class="baz"]').should == s(
:absolute,
parse_xpath('foo[@class="bar" or @class="baz"]').should == s(
:path,
s(
:path,
:test,
nil,
'foo',
s(
:test,
nil,
'foo',
:path,
s(
:path,
:or,
s(
:or,
s(
:eq,
s(:axis, 'attribute', s(:test, nil, 'class')),
s(:string, 'bar')
),
s(
:eq,
s(:axis, 'attribute', s(:test, nil, 'class')),
s(:string, 'baz')
)
:eq,
s(:axis, 'attribute', s(:test, nil, 'class')),
s(:string, 'bar')
),
s(
:eq,
s(:axis, 'attribute', s(:test, nil, 'class')),
s(:string, 'baz')
)
)
)