summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Allen <dan.j.allen@gmail.com>2021-06-19 23:56:11 -0600
committerGitHub <noreply@github.com>2021-06-19 23:56:11 -0600
commit3a43951cebf0dbbbbaa838963e94f53969a2b32d (patch)
treea8cac90b17c46084c2748a0d54fdfc4122fa0b7b
parent5a0b0bb46760dea2a3c7dc0dd357cd8fa8390e12 (diff)
resolves #4086 only interpret negated wildcard in include tag filter as implicit globstar if it precedes other tags (PR #4087)
-rw-r--r--CHANGELOG.adoc1
-rw-r--r--lib/asciidoctor/reader.rb16
-rw-r--r--test/reader_test.rb253
3 files changed, 243 insertions, 27 deletions
diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc
index 8aa47fbb..07e3bbfb 100644
--- a/CHANGELOG.adoc
+++ b/CHANGELOG.adoc
@@ -20,6 +20,7 @@ This project utilizes semantic versioning.
Bug Fixes::
* Include all lines outside of specified tagged region when tag filter on include directive is a single negated tag (#4048)
+ * Only interpret negated wildcard in tag filter on include directive as implicit globstar if it precedes other tags (#4086)
* Change ifeval directive to resolve to false if comparison operation cannot be performed (#4046)
* Don't crash if :to_file option is passed to load or load_file and value is not a string (#4055)
* Use automatic link text if ID in shorthand xref is followed by dangling comma (e.g., `+<<idname,>>+`)
diff --git a/lib/asciidoctor/reader.rb b/lib/asciidoctor/reader.rb
index c1f3e991..ce79d4c4 100644
--- a/lib/asciidoctor/reader.rb
+++ b/lib/asciidoctor/reader.rb
@@ -1106,16 +1106,18 @@ class PreprocessorReader < Reader
elsif inc_tags
inc_lines, inc_offset, inc_lineno, tag_stack, tags_used, active_tag = [], nil, 0, [], ::Set.new, nil
if inc_tags.key? '**'
+ select = base_select = inc_tags.delete '**'
if inc_tags.key? '*'
- select = base_select = inc_tags.delete '**'
wildcard = inc_tags.delete '*'
- else
- select = base_select = wildcard = inc_tags.delete '**'
+ elsif !select && inc_tags.values.first == false
+ wildcard = true
end
- elsif (wildcard = inc_tags.delete '*').nil?
- select = base_select = !(inc_tags.value? true)
+ elsif inc_tags.key? '*'
+ select = base_select = inc_tags.keys.first == '*' ?
+ !(wildcard = inc_tags.delete '*') :
+ ((wildcard = inc_tags.delete '*') ? false : false)
else
- select = base_select = !wildcard
+ select = base_select = !(inc_tags.value? true)
end
begin
reader.call inc_path, read_mode do |f|
@@ -1166,7 +1168,7 @@ class PreprocessorReader < Reader
end
shift
if inc_offset
- parsed_attrs['partial-option'] = '' unless base_select && wildcard && inc_tags.empty?
+ parsed_attrs['partial-option'] = '' unless base_select && wildcard != false && inc_tags.empty?
# FIXME not accounting for skipped lines in reader line numbering
push_include inc_lines, inc_path, relpath, inc_offset, parsed_attrs
end
diff --git a/test/reader_test.rb b/test/reader_test.rb
index 09c7714c..21bb5146 100644
--- a/test/reader_test.rb
+++ b/test/reader_test.rb
@@ -1141,7 +1141,7 @@ class ReaderTest < Minitest::Test
end
end
- test 'include directive does not select lines with tag directives within selected tag region' do
+ test 'include directive does not select lines containing tag directives within selected tag region' do
input = <<~'EOS'
++++
include::fixtures/include-file.adoc[tags=snippet]
@@ -1175,7 +1175,7 @@ class ReaderTest < Minitest::Test
end
end
EOS
- assert_includes output, expected
+ assert_includes output, %(<pre>#{expected}</pre>)
end
test 'include directive takes all lines without tag directives when value is double asterisk' do
@@ -1202,7 +1202,7 @@ class ReaderTest < Minitest::Test
end
end
EOS
- assert_includes output, expected
+ assert_includes output, %(<pre>#{expected}</pre>)
end
test 'include directive takes all lines except negated tags when value contains double asterisk' do
@@ -1221,7 +1221,122 @@ class ReaderTest < Minitest::Test
end
end
EOS
- assert_includes output, expected
+ assert_includes output, %(<pre>#{expected}</pre>)
+ end
+
+ test 'include directive takes all lines including nested tags except negated tags when value contains double asterisk' do
+ input = <<~'EOS'
+ ----
+ include::fixtures/tagged-class.rb[tags=**;!init]
+ ----
+ EOS
+
+ output = convert_string_to_embedded input, safe: :safe, base_dir: DIRNAME
+ # NOTE cannot use single-quoted heredoc because of https://github.com/jruby/jruby/issues/4260
+ expected = <<~EOS.chop
+ class Dog
+
+ def bark
+ if @breed == 'beagle'
+ 'woof woof woof woof woof'
+ else
+ 'woof woof'
+ end
+ end
+ end
+ EOS
+ assert_includes output, %(<pre>#{expected}</pre>)
+ end
+
+ test 'include directive takes all lines outside of tags when value is double asterisk followed by negated wildcard' do
+ input = <<~'EOS'
+ ----
+ include::fixtures/tagged-class.rb[tags=**;!*]
+ ----
+ EOS
+
+ output = convert_string_to_embedded input, safe: :safe, base_dir: DIRNAME
+ expected = <<~'EOS'.chop
+ class Dog
+ end
+ EOS
+ assert_includes output, %(<pre>#{expected}</pre>)
+ end
+
+ # FIXME this is a weird one since we'd expect it to only select the specified tags; but it's always been this way
+ test 'include directive takes all lines except for lines containing tag directive if value is globstar followed by nested tag names' do
+ input = <<~'EOS'
+ ----
+ include::fixtures/tagged-class.rb[tags=**;bark-beagle;bark-all]
+ ----
+ EOS
+
+ output = convert_string_to_embedded input, safe: :safe, base_dir: DIRNAME
+ # NOTE cannot use single-quoted heredoc because of https://github.com/jruby/jruby/issues/4260
+ expected = <<~EOS.chop
+ class Dog
+ def initialize breed
+ @breed = breed
+ end
+
+ def bark
+ if @breed == 'beagle'
+ 'woof woof woof woof woof'
+ else
+ 'woof woof'
+ end
+ end
+ end
+ EOS
+ assert_includes output, %(<pre>#{expected}</pre>)
+ end
+
+ # FIXME this is a weird one since we'd expect it to only select the specified tags; but it's always been this way
+ test 'include directive takes all lines except for lines containing tag directive when value is globstar followed by outer tag name' do
+ input = <<~'EOS'
+ ----
+ include::fixtures/tagged-class.rb[tags=**;bark]
+ ----
+ EOS
+
+ output = convert_string_to_embedded input, safe: :safe, base_dir: DIRNAME
+ # NOTE cannot use single-quoted heredoc because of https://github.com/jruby/jruby/issues/4260
+ expected = <<~EOS.chop
+ class Dog
+ def initialize breed
+ @breed = breed
+ end
+
+ def bark
+ if @breed == 'beagle'
+ 'woof woof woof woof woof'
+ else
+ 'woof woof'
+ end
+ end
+ end
+ EOS
+ assert_includes output, %(<pre>#{expected}</pre>)
+ end
+
+ test 'include directive takes all lines inside unspecified tags when value is negated globstar followed by negated tags' do
+ input = <<~'EOS'
+ ----
+ include::fixtures/tagged-class.rb[tags=!**;!init]
+ ----
+ EOS
+
+ output = convert_string_to_embedded input, safe: :safe, base_dir: DIRNAME
+ expected = <<~EOS.chop
+ \x20 def bark
+ \x20 if @breed == 'beagle'
+ \x20 'woof woof woof woof woof'
+ \x20 else
+ \x20 'woof woof'
+ \x20 end
+ \x20 end
+ EOS
+ assert_includes output, %(<pre>#{expected}</pre>)
end
test 'include directive takes all lines except negated tags when value only contains negated tag' do
@@ -1240,7 +1355,7 @@ class ReaderTest < Minitest::Test
end
end
EOS
- assert_includes output, expected
+ assert_includes output, %(<pre>#{expected}</pre>)
end
test 'include directive takes all lines except negated tags when value only contains negated tags' do
@@ -1251,12 +1366,11 @@ class ReaderTest < Minitest::Test
EOS
output = convert_string_to_embedded input, safe: :safe, base_dir: DIRNAME
- # NOTE cannot use single-quoted heredoc because of https://github.com/jruby/jruby/issues/4260
- expected = <<~EOS.chop
+ expected = <<~'EOS'.chop
class Dog
end
EOS
- assert_includes output, expected
+ assert_includes output, %(<pre>#{expected}</pre>)
end
test 'should recognize tag wildcard if not at head of list' do
@@ -1281,12 +1395,36 @@ class ReaderTest < Minitest::Test
end
end
EOS
- assert_includes output, expected
+ assert_includes output, %(<pre>#{expected}</pre>)
end
test 'include directive selects lines for all tags when value of tags attribute is wildcard' do
input = <<~'EOS'
----
+ include::fixtures/tagged-class.rb[tags=*]
+ ----
+ EOS
+
+ output = convert_string_to_embedded input, safe: :safe, base_dir: DIRNAME
+ expected = <<~EOS.chop
+ \x20 def initialize breed
+ \x20 @breed = breed
+ \x20 end
+
+ \x20 def bark
+ \x20 if @breed == 'beagle'
+ \x20 'woof woof woof woof woof'
+ \x20 else
+ \x20 'woof woof'
+ \x20 end
+ \x20 end
+ EOS
+ assert_includes output, %(<pre>#{expected}</pre>)
+ end
+
+ test 'include directive selects lines for all tags when value of tags attribute is wildcard and tag enclosed content' do
+ input = <<~'EOS'
+ ----
include::fixtures/tagged-class-enclosed.rb[tags=*]
----
EOS
@@ -1308,7 +1446,7 @@ class ReaderTest < Minitest::Test
end
end
EOS
- assert_includes output, expected
+ assert_includes output, %(<pre>#{expected}</pre>)
end
test 'include directive selects lines for all tags except exclusions when value of tags attribute is wildcard' do
@@ -1332,10 +1470,10 @@ class ReaderTest < Minitest::Test
end
end
EOS
- assert_includes output, expected
+ assert_includes output, %(<pre>#{expected}</pre>)
end
- test 'include directive skips lines all tagged regions when value of tags attribute is negated wildcard' do
+ test 'include directive skips all tagged regions when value of tags attribute is negated wildcard' do
input = <<~'EOS'
----
include::fixtures/tagged-class.rb[tags=!*]
@@ -1344,13 +1482,34 @@ class ReaderTest < Minitest::Test
output = convert_string_to_embedded input, safe: :safe, base_dir: DIRNAME
expected = %(class Dog\nend)
- assert_includes output, expected
+ assert_includes output, %(<pre>#{expected}</pre>)
end
- test 'include directive skips lines all tagged regions except ones enabled when value of tags attribute is negated wildcard' do
+ test 'include directive skips all tagged regions except ones enabled when value of tags attribute is negated wildcard' do
+ ['!*;init', '**;!*;init'].each do |pattern|
+ input = <<~EOS
+ ----
+ include::fixtures/tagged-class.rb[tags=#{pattern}]
+ ----
+ EOS
+
+ output = convert_string_to_embedded input, safe: :safe, base_dir: DIRNAME
+ # NOTE cannot use single-quoted heredoc because of https://github.com/jruby/jruby/issues/4260
+ expected = <<~EOS.chop
+ class Dog
+ def initialize breed
+ @breed = breed
+ end
+ end
+ EOS
+ assert_includes output, %(<pre>#{expected}</pre>)
+ end
+ end
+
+ test 'include directive includes regions outside tags and specified tags when value begins with negated wildcard' do
input = <<~'EOS'
----
- include::fixtures/tagged-class.rb[tags=!*;init]
+ include::fixtures/tagged-class.rb[tags=!*;bark]
----
EOS
@@ -1358,12 +1517,44 @@ class ReaderTest < Minitest::Test
# NOTE cannot use single-quoted heredoc because of https://github.com/jruby/jruby/issues/4260
expected = <<~EOS.chop
class Dog
- def initialize breed
- @breed = breed
+
+ def bark
end
end
EOS
- assert_includes output, expected
+ assert_includes output, %(<pre>#{expected}</pre>)
+ end
+
+ test 'include directive includes tag except for nested tags when tag is followed by negated wildcard' do
+ ['bark;!*', '!**;bark;!*', '!**;!*;bark'].each do |pattern|
+ input = <<~EOS
+ ----
+ include::fixtures/tagged-class.rb[tags=#{pattern}]
+ ----
+ EOS
+
+ output = convert_string_to_embedded input, safe: :safe, base_dir: DIRNAME
+ expected = <<~EOS.chop
+ \x20 def bark
+ \x20 end
+ EOS
+ assert_includes output, %(<pre>#{expected}</pre>)
+ end
+ end
+
+ test 'include directive includes tag except for nested tags when tag is preceded by negated globstar and negated star' do
+ input = <<~'EOS'
+ ----
+ include::fixtures/tagged-class.rb[tags=!**;!*;bark]
+ ----
+ EOS
+
+ output = convert_string_to_embedded input, safe: :safe, base_dir: DIRNAME
+ expected = <<~EOS.chop
+ \x20 def bark
+ \x20 end
+ EOS
+ assert_includes output, %(<pre>#{expected}</pre>)
end
test 'include directive does not include tag that has been included then excluded' do
@@ -1378,7 +1569,29 @@ class ReaderTest < Minitest::Test
class Dog
end
EOS
- assert_includes output, expected
+ assert_includes output, %(<pre>#{expected}</pre>)
+ end
+
+ test 'include directive only includes lines inside specified tag, even if proceeded by negated globstar' do
+ ['bark', '!**;bark'].each do |pattern|
+ input = <<~EOS
+ ----
+ include::fixtures/tagged-class.rb[tags=#{pattern}]
+ ----
+ EOS
+
+ output = convert_string_to_embedded input, safe: :safe, base_dir: DIRNAME
+ expected = <<~EOS.chop
+ \x20 def bark
+ \x20 if @breed == 'beagle'
+ \x20 'woof woof woof woof woof'
+ \x20 else
+ \x20 'woof woof'
+ \x20 end
+ \x20 end
+ EOS
+ assert_includes output, %(<pre>#{expected}</pre>)
+ end
end
test 'include directive selects specified tagged lines and ignores the other tag directives' do
@@ -1398,7 +1611,7 @@ class ReaderTest < Minitest::Test
end
end
EOS
- assert_includes output, expected
+ assert_includes output, %(<pre>#{expected}</pre>)
end
test 'should warn if specified tag is not found in include file' do