diff --git a/lib/oga/xpath/compiler.rb b/lib/oga/xpath/compiler.rb index f4d6eab..f1ef376 100644 --- a/lib/oga/xpath/compiler.rb +++ b/lib/oga/xpath/compiler.rb @@ -714,8 +714,10 @@ module Oga needle_lit.assign(try_match_first_node(needle, input)) end .followed_by do - conversion.to_string(haystack_lit) + converted = conversion.to_string(haystack_lit) .include?(conversion.to_string(needle_lit)) + + block_given? ? converted.if_true { yield } : converted end end @@ -961,11 +963,7 @@ module Oga converted = conversion.to_string(haystack_var) .start_with?(conversion.to_string(needle_var)) - if block_given? - converted.if_true { yield } - else - converted - end + block_given? ? converted.if_true { yield } : converted end end diff --git a/spec/oga/xpath/compiler/calls/contains_spec.rb b/spec/oga/xpath/compiler/calls/contains_spec.rb index 4dd2eaa..7c94242 100644 --- a/spec/oga/xpath/compiler/calls/contains_spec.rb +++ b/spec/oga/xpath/compiler/calls/contains_spec.rb @@ -4,34 +4,45 @@ describe Oga::XPath::Compiler do describe 'contains() function' do before do @document = parse('foofoobar') + + @a1 = @document.children[0].children[0] end - it 'returns true if the 1st string contains the 2nd string' do - evaluate_xpath(@document, 'contains("foobar", "oo")').should == true + describe 'at the top-level' do + it 'returns true if the 1st string contains the 2nd string' do + evaluate_xpath(@document, 'contains("foobar", "oo")').should == true + end + + it "returns false if the 1st string doesn't contain the 2nd string" do + evaluate_xpath(@document, 'contains("foobar", "baz")').should == false + end + + it 'returns true if the 1st node set contains the 2nd string' do + evaluate_xpath(@document, 'contains(root/a, "oo")').should == true + end + + it 'returns true if the 1st node set contains the 2nd node set' do + evaluate_xpath(@document, 'contains(root/b, root/a)').should == true + end + + it "returns false if the 1st node doesn't contain the 2nd node set" do + evaluate_xpath(@document, 'contains(root/a, root/b)').should == false + end + + it 'returns true if the 1st string contains the 2nd node set' do + evaluate_xpath(@document, 'contains("foobar", root/a)').should == true + end + + it 'returns true when using two empty strings' do + evaluate_xpath(@document, 'contains("", "")').should == true + end end - it "returns false if the 1st string doesn't contain the 2nd string" do - evaluate_xpath(@document, 'contains("foobar", "baz")').should == false - end - - it 'returns true if the 1st node set contains the 2nd string' do - evaluate_xpath(@document, 'contains(root/a, "oo")').should == true - end - - it 'returns true if the 1st node set contains the 2nd node set' do - evaluate_xpath(@document, 'contains(root/b, root/a)').should == true - end - - it "returns false if the 1st node doesn't contain the 2nd node set" do - evaluate_xpath(@document, 'contains(root/a, root/b)').should == false - end - - it 'returns true if the 1st string contains the 2nd node set' do - evaluate_xpath(@document, 'contains("foobar", root/a)').should == true - end - - it 'returns true when using two empty strings' do - evaluate_xpath(@document, 'contains("", "")').should == true + describe 'in a predicate' do + it 'returns a NodeSet containing all matching nodes' do + evaluate_xpath(@document, 'root/a[contains("foo", "foo")]') + .should == node_set(@a1) + end end end end diff --git a/spec/oga/xpath/compiler/calls/starts_with_spec.rb b/spec/oga/xpath/compiler/calls/starts_with_spec.rb index c2c6310..4c9e9a4 100644 --- a/spec/oga/xpath/compiler/calls/starts_with_spec.rb +++ b/spec/oga/xpath/compiler/calls/starts_with_spec.rb @@ -4,34 +4,45 @@ describe Oga::XPath::Compiler do describe 'starts-with() function' do before do @document = parse('foofoobar') + + @a1 = @document.children[0].children[0] end - it 'returns true if the 1st string starts with the 2nd string' do - evaluate_xpath(@document, 'starts-with("foobar", "foo")').should == true + describe 'at the top-level' do + it 'returns true if the 1st string starts with the 2nd string' do + evaluate_xpath(@document, 'starts-with("foobar", "foo")').should == true + end + + it "returns false if the 1st string doesn't start with the 2nd string" do + evaluate_xpath(@document, 'starts-with("foobar", "baz")').should == false + end + + it 'returns true if the 1st node set starts with the 2nd string' do + evaluate_xpath(@document, 'starts-with(root/a, "foo")').should == true + end + + it 'returns true if the 1st node set starts with the 2nd node set' do + evaluate_xpath(@document, 'starts-with(root/b, root/a)').should == true + end + + it "returns false if the 1st node set doesn't start with the 2nd string" do + evaluate_xpath(@document, 'starts-with(root/a, "baz")').should == false + end + + it 'returns true if the 1st string starts with the 2nd node set' do + evaluate_xpath(@document, 'starts-with("foobar", root/a)').should == true + end + + it 'returns true when using two empty strings' do + evaluate_xpath(@document, 'starts-with("", "")').should == true + end end - it "returns false if the 1st string doesn't start with the 2nd string" do - evaluate_xpath(@document, 'starts-with("foobar", "baz")').should == false - end - - it 'returns true if the 1st node set starts with the 2nd string' do - evaluate_xpath(@document, 'starts-with(root/a, "foo")').should == true - end - - it 'returns true if the 1st node set starts with the 2nd node set' do - evaluate_xpath(@document, 'starts-with(root/b, root/a)').should == true - end - - it "returns false if the 1st node set doesn't start with the 2nd string" do - evaluate_xpath(@document, 'starts-with(root/a, "baz")').should == false - end - - it 'returns true if the 1st string starts with the 2nd node set' do - evaluate_xpath(@document, 'starts-with("foobar", root/a)').should == true - end - - it 'returns true when using two empty strings' do - evaluate_xpath(@document, 'starts-with("", "")').should == true + describe 'in a predicate' do + it 'returns a NodeSet containing all matching nodes' do + evaluate_xpath(@document, 'root/a[starts-with("foo", "foo")]') + .should == node_set(@a1) + end end end end