asciidoctor 0.0.9 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of asciidoctor might be problematic. Click here for more details.
- data/README.asciidoc +163 -41
- data/Rakefile +3 -1
- data/asciidoctor.gemspec +13 -5
- data/bin/asciidoctor +6 -3
- data/bin/asciidoctor-safe +13 -0
- data/lib/asciidoctor.rb +237 -26
- data/lib/asciidoctor/abstract_node.rb +27 -17
- data/lib/asciidoctor/attribute_list.rb +6 -0
- data/lib/asciidoctor/backends/base_template.rb +3 -4
- data/lib/asciidoctor/backends/docbook45.rb +114 -55
- data/lib/asciidoctor/backends/html5.rb +173 -104
- data/lib/asciidoctor/cli/invoker.rb +105 -0
- data/lib/asciidoctor/cli/options.rb +146 -0
- data/lib/asciidoctor/document.rb +135 -35
- data/lib/asciidoctor/lexer.rb +86 -33
- data/lib/asciidoctor/list_item.rb +2 -2
- data/lib/asciidoctor/reader.rb +6 -7
- data/lib/asciidoctor/section.rb +17 -5
- data/lib/asciidoctor/substituters.rb +216 -97
- data/lib/asciidoctor/table.rb +9 -2
- data/lib/asciidoctor/version.rb +1 -1
- data/man/asciidoctor.1 +212 -0
- data/man/asciidoctor.ad +156 -0
- data/test/attributes_test.rb +108 -5
- data/test/blocks_test.rb +102 -15
- data/test/document_test.rb +214 -3
- data/test/fixtures/encoding.asciidoc +4 -0
- data/test/fixtures/sample.asciidoc +26 -0
- data/test/invoker_test.rb +254 -0
- data/test/lexer_test.rb +53 -0
- data/test/links_test.rb +30 -0
- data/test/lists_test.rb +648 -9
- data/test/options_test.rb +68 -0
- data/test/paragraphs_test.rb +65 -1
- data/test/reader_test.rb +18 -4
- data/test/{headers_test.rb → sections_test.rb} +237 -0
- data/test/substitutions_test.rb +247 -5
- data/test/tables_test.rb +22 -4
- data/test/test_helper.rb +47 -3
- data/test/text_test.rb +20 -4
- metadata +34 -6
- data/noof.rb +0 -16
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'asciidoctor/cli/options'
|
3
|
+
|
4
|
+
context 'Options' do
|
5
|
+
test 'should return error code 0 when help flag is present' do
|
6
|
+
redirect_streams do |stdout, stderr|
|
7
|
+
exitval = Asciidoctor::Cli::Options.parse!(%w(-h))
|
8
|
+
assert_equal 0, exitval
|
9
|
+
assert_match(/^Usage:/, stdout.string)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
test 'should return error code 1 when invalid option present' do
|
14
|
+
redirect_streams do |stdout, stderr|
|
15
|
+
exitval = Asciidoctor::Cli::Options.parse!(%w(--foobar))
|
16
|
+
assert_equal 1, exitval
|
17
|
+
assert_equal 'asciidoctor: invalid option: --foobar', stderr.string.chomp
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
test 'should return error code 1 when option has invalid argument' do
|
22
|
+
redirect_streams do |stdout, stderr|
|
23
|
+
exitval = Asciidoctor::Cli::Options.parse!(%w(-b foo input.ad))
|
24
|
+
assert_equal 1, exitval
|
25
|
+
assert_equal 'asciidoctor: invalid argument: -b foo', stderr.string.chomp
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
test 'should return error code 1 when option is missing required argument' do
|
30
|
+
redirect_streams do |stdout, stderr|
|
31
|
+
exitval = Asciidoctor::Cli::Options.parse!(%w(-b))
|
32
|
+
assert_equal 1, exitval
|
33
|
+
assert_equal 'asciidoctor: option missing argument: -b', stderr.string.chomp
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
test 'should emit warning when unparsed options remain' do
|
38
|
+
redirect_streams do |stdout, stderr|
|
39
|
+
options = Asciidoctor::Cli::Options.parse!(%w(-b docbook extra junk test/fixtures/sample.asciidoc))
|
40
|
+
assert options.is_a? Hash
|
41
|
+
assert_equal 'asciidoctor: WARNING: extra arguments detected (unparsed arguments: \'extra\', \'junk\')', stderr.string.chomp
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
test 'basic argument assignment' do
|
46
|
+
options = Asciidoctor::Cli::Options.parse!(%w(-v -s -d book test/fixtures/sample.asciidoc))
|
47
|
+
|
48
|
+
assert_equal true, options[:verbose]
|
49
|
+
assert_equal false, options[:header_footer]
|
50
|
+
assert_equal 'book', options[:attributes]['doctype']
|
51
|
+
assert_equal 'test/fixtures/sample.asciidoc', options[:input_file]
|
52
|
+
end
|
53
|
+
|
54
|
+
test 'standard attribute assignment' do
|
55
|
+
options = Asciidoctor::Cli::Options.parse!(%w(-a imagesdir=images,icons test/fixtures/sample.asciidoc))
|
56
|
+
|
57
|
+
assert_equal 'images', options[:attributes]['imagesdir']
|
58
|
+
assert_equal '', options[:attributes]['icons']
|
59
|
+
end
|
60
|
+
|
61
|
+
test 'multiple attribute arguments' do
|
62
|
+
options = Asciidoctor::Cli::Options.parse!(%w(-a imagesdir=images -a icons test/fixtures/sample.asciidoc))
|
63
|
+
|
64
|
+
assert_equal 'images', options[:attributes]['imagesdir']
|
65
|
+
assert_equal '', options[:attributes]['icons']
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
data/test/paragraphs_test.rb
CHANGED
@@ -17,6 +17,70 @@ context "Paragraphs" do
|
|
17
17
|
rendered = render_string("Title\n=====\n\nPreamble.\n\n== First Section\n\nParagraph 1\n\nParagraph 2\n\n\n== Second Section\n\nLast words")
|
18
18
|
assert_xpath '//p[text()="Paragraph 2"]', rendered, 1
|
19
19
|
end
|
20
|
+
|
21
|
+
test 'does not treat wrapped line as a list item' do
|
22
|
+
input = <<-EOS
|
23
|
+
paragraph
|
24
|
+
. wrapped line
|
25
|
+
EOS
|
26
|
+
|
27
|
+
output = render_embedded_string input
|
28
|
+
assert_css 'p', output, 1
|
29
|
+
assert_xpath %(//p[text()="paragraph\n. wrapped line"]), output, 1
|
30
|
+
end
|
31
|
+
|
32
|
+
test 'does not treat wrapped line as a block title' do
|
33
|
+
input = <<-EOS
|
34
|
+
paragraph
|
35
|
+
.wrapped line
|
36
|
+
EOS
|
37
|
+
|
38
|
+
output = render_embedded_string input
|
39
|
+
assert_css 'p', output, 1
|
40
|
+
assert_xpath %(//p[text()="paragraph\n.wrapped line"]), output, 1
|
41
|
+
end
|
42
|
+
|
43
|
+
test 'expands index term macros in DocBook backend' do
|
44
|
+
input = <<-EOS
|
45
|
+
Here is an index entry for ((tigers)).
|
46
|
+
indexterm:[Big cats,Tigers,Siberian Tiger]
|
47
|
+
Here is an index entry for indexterm2:[Linux].
|
48
|
+
(((Operating Systems,Linux,Fedora)))
|
49
|
+
Note that multi-entry terms generate separate index entries.
|
50
|
+
EOS
|
51
|
+
|
52
|
+
output = render_embedded_string input, :attributes => {'backend' => 'docbook45'}
|
53
|
+
assert_xpath '/simpara', output, 1
|
54
|
+
term1 = (xmlnodes_at_xpath '(//indexterm)[1]', output, 1).first
|
55
|
+
assert_equal '<indexterm><primary>tigers</primary></indexterm>', term1.to_s
|
56
|
+
assert term1.next.content.start_with?('tigers')
|
57
|
+
|
58
|
+
term2 = (xmlnodes_at_xpath '(//indexterm)[2]', output, 1).first
|
59
|
+
term2_elements = term2.elements
|
60
|
+
assert_equal 3, term2_elements.size
|
61
|
+
assert_equal '<primary>Big cats</primary>', term2_elements[0].to_s
|
62
|
+
assert_equal '<secondary>Tigers</secondary>', term2_elements[1].to_s
|
63
|
+
assert_equal '<tertiary>Siberian Tiger</tertiary>', term2_elements[2].to_s
|
64
|
+
|
65
|
+
term3 = (xmlnodes_at_xpath '(//indexterm)[3]', output, 1).first
|
66
|
+
term3_elements = term3.elements
|
67
|
+
assert_equal 2, term3_elements.size
|
68
|
+
assert_equal '<primary>Tigers</primary>', term3_elements[0].to_s
|
69
|
+
assert_equal '<secondary>Siberian Tiger</secondary>', term3_elements[1].to_s
|
70
|
+
|
71
|
+
term4 = (xmlnodes_at_xpath '(//indexterm)[4]', output, 1).first
|
72
|
+
term4_elements = term4.elements
|
73
|
+
assert_equal 1, term4_elements.size
|
74
|
+
assert_equal '<primary>Siberian Tiger</primary>', term4_elements[0].to_s
|
75
|
+
|
76
|
+
term5 = (xmlnodes_at_xpath '(//indexterm)[5]', output, 1).first
|
77
|
+
assert_equal '<indexterm><primary>Linux</primary></indexterm>', term5.to_s
|
78
|
+
assert term5.next.content.start_with?('Linux')
|
79
|
+
|
80
|
+
assert_xpath '(//indexterm)[6]/*', output, 3
|
81
|
+
assert_xpath '(//indexterm)[7]/*', output, 2
|
82
|
+
assert_xpath '(//indexterm)[8]/*', output, 1
|
83
|
+
end
|
20
84
|
end
|
21
85
|
|
22
86
|
context "code" do
|
@@ -58,7 +122,7 @@ You're good to go!
|
|
58
122
|
output = render_string("[quote, A famous person, A famous book (1999)]\n____\nFamous quote.\n____")
|
59
123
|
assert_xpath '//*[@class = "quoteblock"]', output, 1
|
60
124
|
assert_xpath '//*[@class = "quoteblock"]/*[@class = "attribution"]', output, 1
|
61
|
-
assert_xpath '//*[@class = "quoteblock"]/*[@class = "attribution"]/
|
125
|
+
assert_xpath '//*[@class = "quoteblock"]/*[@class = "attribution"]/cite[text() = "A famous book (1999)"]', output, 1
|
62
126
|
# TODO I can't seem to match the attribution (author) w/ xpath
|
63
127
|
end
|
64
128
|
|
data/test/reader_test.rb
CHANGED
@@ -231,15 +231,15 @@ include::include-file.asciidoc[]
|
|
231
231
|
context 'build secure asset path' do
|
232
232
|
test 'allows us to specify a path relative to the current dir' do
|
233
233
|
doc = Asciidoctor::Document.new
|
234
|
-
|
234
|
+
Asciidoctor::Reader.new(["foo"], doc)
|
235
235
|
legit_path = Dir.pwd + "/foo"
|
236
236
|
assert_equal legit_path, doc.normalize_asset_path(legit_path)
|
237
237
|
end
|
238
238
|
|
239
239
|
test "keeps naughty absolute paths from getting outside" do
|
240
|
-
naughty_path = "
|
240
|
+
naughty_path = "#{disk_root}etc/passwd"
|
241
241
|
doc = Asciidoctor::Document.new
|
242
|
-
|
242
|
+
Asciidoctor::Reader.new(["foo"], doc)
|
243
243
|
secure_path = doc.normalize_asset_path(naughty_path)
|
244
244
|
assert naughty_path != secure_path
|
245
245
|
assert_match(/^#{doc.base_dir}/, secure_path)
|
@@ -248,7 +248,7 @@ include::include-file.asciidoc[]
|
|
248
248
|
test "keeps naughty relative paths from getting outside" do
|
249
249
|
naughty_path = "safe/ok/../../../../../etc/passwd"
|
250
250
|
doc = Asciidoctor::Document.new
|
251
|
-
|
251
|
+
Asciidoctor::Reader.new(["foo"], doc)
|
252
252
|
secure_path = doc.normalize_asset_path(naughty_path)
|
253
253
|
assert naughty_path != secure_path
|
254
254
|
assert_match(/^#{doc.base_dir}/, secure_path)
|
@@ -283,6 +283,20 @@ endif::holygrail[]
|
|
283
283
|
end
|
284
284
|
|
285
285
|
context 'Text processing' do
|
286
|
+
test 'should clean CRLF from end of lines' do
|
287
|
+
input = <<-EOS
|
288
|
+
source\r
|
289
|
+
with\r
|
290
|
+
CRLF\r
|
291
|
+
endlines\r
|
292
|
+
EOS
|
293
|
+
|
294
|
+
reader = Asciidoctor::Reader.new(input.lines.entries, Asciidoctor::Document.new)
|
295
|
+
reader.lines.each do |line|
|
296
|
+
assert !line.end_with?("\r\n")
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
286
300
|
test 'sanitize attribute name' do
|
287
301
|
assert_equal 'foobar', @reader.sanitize_attribute_name("Foo Bar")
|
288
302
|
assert_equal 'foo', @reader.sanitize_attribute_name("foo")
|
@@ -28,6 +28,16 @@ context 'Sections' do
|
|
28
28
|
assert_equal 'section_one', sec.id
|
29
29
|
end
|
30
30
|
|
31
|
+
test 'synthetic id separator can be customized' do
|
32
|
+
sec = block_from_string(":idseparator: -\n\n== Section One")
|
33
|
+
assert_equal '_section-one', sec.id
|
34
|
+
end
|
35
|
+
|
36
|
+
test 'synthetic id separator can be set to blank' do
|
37
|
+
sec = block_from_string(":idseparator:\n\n== Section One")
|
38
|
+
assert_equal '_sectionone', sec.id
|
39
|
+
end
|
40
|
+
|
31
41
|
test 'synthetic ids can be disabled' do
|
32
42
|
sec = block_from_string(":sectids!:\n\n== Section One\n")
|
33
43
|
assert sec.id.nil?
|
@@ -198,6 +208,119 @@ text
|
|
198
208
|
end
|
199
209
|
end
|
200
210
|
|
211
|
+
context 'Floating Title' do
|
212
|
+
test 'should create floating title if style is float' do
|
213
|
+
input = <<-EOS
|
214
|
+
[float]
|
215
|
+
= Plain Ol' Heading
|
216
|
+
|
217
|
+
not in section
|
218
|
+
EOS
|
219
|
+
|
220
|
+
output = render_embedded_string input
|
221
|
+
assert_xpath '/h1[@id="_plain_ol_heading"]', output, 1
|
222
|
+
assert_xpath '/h1[@class="float"]', output, 1
|
223
|
+
assert_xpath %(/h1[@class="float"][text()="Plain Ol' Heading"]), output, 1
|
224
|
+
assert_xpath '/h1/following-sibling::*[@class="paragraph"]', output, 1
|
225
|
+
assert_xpath '/h1/following-sibling::*[@class="paragraph"]/p', output, 1
|
226
|
+
assert_xpath '/h1/following-sibling::*[@class="paragraph"]/p[text()="not in section"]', output, 1
|
227
|
+
end
|
228
|
+
|
229
|
+
test 'should create floating title if style is discrete' do
|
230
|
+
input = <<-EOS
|
231
|
+
[discrete]
|
232
|
+
=== Plain Ol' Heading
|
233
|
+
|
234
|
+
not in section
|
235
|
+
EOS
|
236
|
+
|
237
|
+
output = render_embedded_string input
|
238
|
+
assert_xpath '/h3', output, 1
|
239
|
+
assert_xpath '/h3[@id="_plain_ol_heading"]', output, 1
|
240
|
+
assert_xpath '/h3[@class="discrete"]', output, 1
|
241
|
+
assert_xpath %(/h3[@class="discrete"][text()="Plain Ol' Heading"]), output, 1
|
242
|
+
assert_xpath '/h3/following-sibling::*[@class="paragraph"]', output, 1
|
243
|
+
assert_xpath '/h3/following-sibling::*[@class="paragraph"]/p', output, 1
|
244
|
+
assert_xpath '/h3/following-sibling::*[@class="paragraph"]/p[text()="not in section"]', output, 1
|
245
|
+
end
|
246
|
+
|
247
|
+
test 'floating title should be a block with context floating_title' do
|
248
|
+
input = <<-EOS
|
249
|
+
[float]
|
250
|
+
=== Plain Ol' Heading
|
251
|
+
|
252
|
+
not in section
|
253
|
+
EOS
|
254
|
+
|
255
|
+
doc = document_from_string input
|
256
|
+
floatingtitle = doc.blocks.first
|
257
|
+
assert floatingtitle.is_a?(Asciidoctor::Block)
|
258
|
+
assert !floatingtitle.is_a?(Asciidoctor::Section)
|
259
|
+
assert_equal :floating_title, floatingtitle.context
|
260
|
+
end
|
261
|
+
|
262
|
+
test 'should not include floating title in toc' do
|
263
|
+
input = <<-EOS
|
264
|
+
:toc:
|
265
|
+
|
266
|
+
== Section One
|
267
|
+
|
268
|
+
[float]
|
269
|
+
=== Miss Independent
|
270
|
+
|
271
|
+
== Section Two
|
272
|
+
EOS
|
273
|
+
|
274
|
+
output = render_string input
|
275
|
+
assert_xpath '//*[@id="toc"]', output, 1
|
276
|
+
assert_xpath %(//*[@id="toc"]//a[contains(text(), " Section ")]), output, 2
|
277
|
+
assert_xpath %(//*[@id="toc"]//a[text()="Miss Independent"]), output, 0
|
278
|
+
end
|
279
|
+
|
280
|
+
test 'should not set id on floating title if sectids attribute is unset' do
|
281
|
+
input = <<-EOS
|
282
|
+
[float]
|
283
|
+
=== Plain Ol' Heading
|
284
|
+
|
285
|
+
not in section
|
286
|
+
EOS
|
287
|
+
|
288
|
+
output = render_embedded_string input, :attributes => {'sectids' => nil}
|
289
|
+
assert_xpath '/h3', output, 1
|
290
|
+
assert_xpath '/h3[@id="_plain_ol_heading"]', output, 0
|
291
|
+
assert_xpath '/h3[@class="float"]', output, 1
|
292
|
+
end
|
293
|
+
|
294
|
+
test 'should use explicit id for floating title if specified' do
|
295
|
+
input = <<-EOS
|
296
|
+
[[free]]
|
297
|
+
[float]
|
298
|
+
== Plain Ol' Heading
|
299
|
+
|
300
|
+
not in section
|
301
|
+
EOS
|
302
|
+
|
303
|
+
output = render_embedded_string input
|
304
|
+
assert_xpath '/h2', output, 1
|
305
|
+
assert_xpath '/h2[@id="free"]', output, 1
|
306
|
+
assert_xpath '/h2[@class="float"]', output, 1
|
307
|
+
end
|
308
|
+
|
309
|
+
test 'should add role to class attribute on floating title' do
|
310
|
+
input = <<-EOS
|
311
|
+
[float, role="isolated"]
|
312
|
+
== Plain Ol' Heading
|
313
|
+
|
314
|
+
not in section
|
315
|
+
EOS
|
316
|
+
|
317
|
+
output = render_embedded_string input
|
318
|
+
assert_xpath '/h2', output, 1
|
319
|
+
assert_xpath '/h2[@id="_plain_ol_heading"]', output, 1
|
320
|
+
assert_xpath '/h2[@class="float isolated"]', output, 1
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
201
324
|
context 'Section Numbering' do
|
202
325
|
test 'should create section number with one entry for level 1' do
|
203
326
|
sect1 = Asciidoctor::Section.new(nil)
|
@@ -306,6 +429,120 @@ paragraph
|
|
306
429
|
end
|
307
430
|
end
|
308
431
|
|
432
|
+
context 'Special sections' do
|
433
|
+
test 'should assign sectname and caption to appendix section' do
|
434
|
+
input = <<-EOS
|
435
|
+
[appendix]
|
436
|
+
== Attribute Options
|
437
|
+
|
438
|
+
Details
|
439
|
+
EOS
|
440
|
+
|
441
|
+
output = block_from_string input
|
442
|
+
assert_equal 'appendix', output.sectname
|
443
|
+
assert_equal 'Appendix A: ', output.attr('caption')
|
444
|
+
end
|
445
|
+
|
446
|
+
test 'should render appendix title prefixed with caption' do
|
447
|
+
input = <<-EOS
|
448
|
+
[appendix]
|
449
|
+
== Attribute Options
|
450
|
+
|
451
|
+
Details
|
452
|
+
EOS
|
453
|
+
|
454
|
+
output = render_embedded_string input
|
455
|
+
assert_xpath '//h2[text()="Appendix A: Attribute Options"]', output, 1
|
456
|
+
end
|
457
|
+
|
458
|
+
test 'should increment appendix number for each appendix section' do
|
459
|
+
input = <<-EOS
|
460
|
+
[appendix]
|
461
|
+
== Attribute Options
|
462
|
+
|
463
|
+
Details
|
464
|
+
|
465
|
+
[appendix]
|
466
|
+
== Migration
|
467
|
+
|
468
|
+
Details
|
469
|
+
EOS
|
470
|
+
|
471
|
+
output = render_embedded_string input
|
472
|
+
assert_xpath '(//h2)[1][text()="Appendix A: Attribute Options"]', output, 1
|
473
|
+
assert_xpath '(//h2)[2][text()="Appendix B: Migration"]', output, 1
|
474
|
+
end
|
475
|
+
|
476
|
+
test 'should not number special sections or subsections' do
|
477
|
+
input = <<-EOS
|
478
|
+
:numbered:
|
479
|
+
|
480
|
+
== Section One
|
481
|
+
|
482
|
+
[appendix]
|
483
|
+
== Attribute Options
|
484
|
+
|
485
|
+
Details
|
486
|
+
|
487
|
+
[appendix]
|
488
|
+
== Migration
|
489
|
+
|
490
|
+
Details
|
491
|
+
|
492
|
+
=== Gotchas
|
493
|
+
|
494
|
+
Details
|
495
|
+
|
496
|
+
[glossary]
|
497
|
+
== Glossary
|
498
|
+
|
499
|
+
Terms
|
500
|
+
EOS
|
501
|
+
|
502
|
+
output = render_embedded_string input
|
503
|
+
assert_xpath '(//h2)[1][text()="1. Section One"]', output, 1
|
504
|
+
assert_xpath '(//h2)[2][text()="Appendix A: Attribute Options"]', output, 1
|
505
|
+
assert_xpath '(//h2)[3][text()="Appendix B: Migration"]', output, 1
|
506
|
+
assert_xpath '(//h3)[1][text()="Gotchas"]', output, 1
|
507
|
+
assert_xpath '(//h2)[4][text()="Glossary"]', output, 1
|
508
|
+
end
|
509
|
+
|
510
|
+
test 'should not number special sections or subsections in toc' do
|
511
|
+
input = <<-EOS
|
512
|
+
:numbered:
|
513
|
+
:toc:
|
514
|
+
|
515
|
+
== Section One
|
516
|
+
|
517
|
+
[appendix]
|
518
|
+
== Attribute Options
|
519
|
+
|
520
|
+
Details
|
521
|
+
|
522
|
+
[appendix]
|
523
|
+
== Migration
|
524
|
+
|
525
|
+
Details
|
526
|
+
|
527
|
+
=== Gotchas
|
528
|
+
|
529
|
+
Details
|
530
|
+
|
531
|
+
[glossary]
|
532
|
+
== Glossary
|
533
|
+
|
534
|
+
Terms
|
535
|
+
EOS
|
536
|
+
|
537
|
+
output = render_string input
|
538
|
+
assert_xpath '//*[@id="toc"]/ol//li/a[text()="1. Section One"]', output, 1
|
539
|
+
assert_xpath '//*[@id="toc"]/ol//li/a[text()="Appendix A: Attribute Options"]', output, 1
|
540
|
+
assert_xpath '//*[@id="toc"]/ol//li/a[text()="Appendix B: Migration"]', output, 1
|
541
|
+
assert_xpath '//*[@id="toc"]/ol//li/a[text()="Gotchas"]', output, 1
|
542
|
+
assert_xpath '//*[@id="toc"]/ol//li/a[text()="Glossary"]', output, 1
|
543
|
+
end
|
544
|
+
end
|
545
|
+
|
309
546
|
context "heading patterns in blocks" do
|
310
547
|
test "should not interpret a listing block as a heading" do
|
311
548
|
input = <<-EOS
|