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