diff options
| author | Dan Allen <dan.j.allen@gmail.com> | 2021-06-19 23:56:11 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-06-19 23:56:11 -0600 |
| commit | 3a43951cebf0dbbbbaa838963e94f53969a2b32d (patch) | |
| tree | a8cac90b17c46084c2748a0d54fdfc4122fa0b7b | |
| parent | 5a0b0bb46760dea2a3c7dc0dd357cd8fa8390e12 (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.adoc | 1 | ||||
| -rw-r--r-- | lib/asciidoctor/reader.rb | 16 | ||||
| -rw-r--r-- | test/reader_test.rb | 253 |
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 |
