summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Allen <dan.j.allen@gmail.com>2019-03-20 00:27:51 -0600
committerDan Allen <dan.j.allen@gmail.com>2019-03-20 00:33:29 -0600
commitd41ba53c83ffde604939e289c71a1bb18fce2d59 (patch)
tree03f26ef8acc00259299136eab94c571a32b961cd
parent580f0b3487d658d95c2404abb5a24dc37cb8948b (diff)
find_by should reject node when :reject directive is used with ID selector
- reject node if ID selector matches, but filter returns :reject directive - simplify find_by implementation
-rw-r--r--lib/asciidoctor/abstract_block.rb11
-rw-r--r--test/api_test.rb39
2 files changed, 46 insertions, 4 deletions
diff --git a/lib/asciidoctor/abstract_block.rb b/lib/asciidoctor/abstract_block.rb
index 4ecfcac4..b85d7cde 100644
--- a/lib/asciidoctor/abstract_block.rb
+++ b/lib/asciidoctor/abstract_block.rb
@@ -441,25 +441,28 @@ class AbstractBlock < AbstractNode
(!(style_selector = selector[:style]) || style_selector == @style) &&
(!(role_selector = selector[:role]) || (has_role? role_selector)) &&
(!(id_selector = selector[:id]) || id_selector == @id)
- if id_selector
- block_given? && !(yield self) ? result.clear : (result.replace [self])
- raise ::StopIteration
- elsif block_given?
+ if block_given?
if (verdict = yield self)
case verdict
# the :skip_children keyword is deprecated
when :prune, :skip_children
result << self
+ raise ::StopIteration if id_selector
return result
# the :skip keyword is deprecated and may be repurposed
when :reject, :skip
+ raise ::StopIteration if id_selector
return result
else
result << self
+ raise ::StopIteration if id_selector
end
+ elsif id_selector
+ raise ::StopIteration
end
else
result << self
+ raise ::StopIteration if id_selector
end
end
case @context
diff --git a/test/api_test.rb b/test/api_test.rb
index ec785dff..50f43fba 100644
--- a/test/api_test.rb
+++ b/test/api_test.rb
@@ -741,6 +741,45 @@ context 'API' do
assert_equal :paragraph, result[1].context
end
+ test 'find_by should reject node matched by ID selector if block returns :reject' do
+ input = <<~'EOS'
+ [.rolename]
+ paragraph 1
+
+ [.rolename#idname]
+ paragraph 2
+ EOS
+ doc = Asciidoctor.load input
+ result = doc.find_by id: 'idname', role: 'rolename'
+ refute_nil result
+ assert_equal 1, result.size
+ assert_equal doc.blocks[1], result[0]
+ result = doc.find_by(id: 'idname', role: 'rolename') { :reject }
+ refute_nil result
+ assert_equal 0, result.size
+ end
+
+ test 'find_by should accept node matched by ID selector if block returns :prune' do
+ input = <<~'EOS'
+ [.rolename]
+ paragraph 1
+
+ [.rolename#idname]
+ ====
+ paragraph 2
+ ====
+ EOS
+ doc = Asciidoctor.load input
+ result = doc.find_by id: 'idname', role: 'rolename'
+ refute_nil result
+ assert_equal 1, result.size
+ assert_equal doc.blocks[1], result[0]
+ result = doc.find_by(id: 'idname', role: 'rolename') { :prune }
+ refute_nil result
+ assert_equal 1, result.size
+ assert_equal doc.blocks[1], result[0]
+ end
+
test 'find_by should accept node but reject its children if block returns :prune' do
input = <<~'EOS'
====