asciidoctor 1.5.6.2 → 1.5.7

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.

Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.adoc +330 -143
  3. data/README-fr.adoc +441 -0
  4. data/README-jp.adoc +418 -0
  5. data/README-zh_CN.adoc +430 -0
  6. data/README.adoc +454 -0
  7. data/Rakefile +57 -0
  8. data/asciidoctor.gemspec +7 -1
  9. data/data/locale/attributes-ar.adoc +22 -0
  10. data/data/locale/attributes-bg.adoc +22 -0
  11. data/data/locale/attributes-ca.adoc +22 -0
  12. data/data/locale/attributes-cs.adoc +22 -0
  13. data/data/locale/attributes-da.adoc +22 -0
  14. data/data/locale/attributes-de.adoc +22 -0
  15. data/data/locale/attributes-en.adoc +23 -0
  16. data/data/locale/attributes-es.adoc +22 -0
  17. data/data/locale/attributes-fa.adoc +22 -0
  18. data/data/locale/attributes-fi.adoc +22 -0
  19. data/data/locale/attributes-fr.adoc +22 -0
  20. data/data/locale/attributes-hu.adoc +22 -0
  21. data/data/locale/attributes-id.adoc +22 -0
  22. data/data/locale/attributes-it.adoc +22 -0
  23. data/data/locale/attributes-ja.adoc +22 -0
  24. data/data/locale/attributes-kr.adoc +22 -0
  25. data/data/locale/attributes-nb.adoc +22 -0
  26. data/data/locale/attributes-nl.adoc +22 -0
  27. data/data/locale/attributes-nn.adoc +22 -0
  28. data/data/locale/attributes-pl.adoc +22 -0
  29. data/data/locale/attributes-pt.adoc +22 -0
  30. data/data/locale/attributes-pt_BR.adoc +22 -0
  31. data/data/locale/attributes-ro.adoc +22 -0
  32. data/data/locale/attributes-ru.adoc +22 -0
  33. data/data/locale/attributes-sr.adoc +22 -0
  34. data/data/locale/attributes-sr_Latn.adoc +22 -0
  35. data/data/locale/attributes-tr.adoc +22 -0
  36. data/data/locale/attributes-uk.adoc +22 -0
  37. data/data/locale/attributes-zh_CN.adoc +22 -0
  38. data/data/locale/attributes-zh_TW.adoc +22 -0
  39. data/data/locale/attributes.adoc +8 -649
  40. data/data/stylesheets/asciidoctor-default.css +77 -72
  41. data/features/xref.feature +366 -7
  42. data/lib/asciidoctor.rb +107 -93
  43. data/lib/asciidoctor/abstract_block.rb +247 -239
  44. data/lib/asciidoctor/abstract_node.rb +56 -58
  45. data/lib/asciidoctor/block.rb +3 -3
  46. data/lib/asciidoctor/callouts.rb +1 -1
  47. data/lib/asciidoctor/cli/invoker.rb +36 -9
  48. data/lib/asciidoctor/cli/options.rb +63 -25
  49. data/lib/asciidoctor/converter.rb +23 -13
  50. data/lib/asciidoctor/converter/base.rb +4 -0
  51. data/lib/asciidoctor/converter/docbook45.rb +16 -9
  52. data/lib/asciidoctor/converter/docbook5.rb +115 -97
  53. data/lib/asciidoctor/converter/factory.rb +29 -31
  54. data/lib/asciidoctor/converter/html5.rb +229 -192
  55. data/lib/asciidoctor/converter/manpage.rb +72 -50
  56. data/lib/asciidoctor/converter/template.rb +12 -12
  57. data/lib/asciidoctor/core_ext.rb +5 -1
  58. data/lib/asciidoctor/core_ext/1.8.7/base64/strict_encode64.rb +6 -0
  59. data/lib/asciidoctor/document.rb +168 -77
  60. data/lib/asciidoctor/extensions.rb +79 -47
  61. data/lib/asciidoctor/helpers.rb +33 -11
  62. data/lib/asciidoctor/inline.rb +3 -2
  63. data/lib/asciidoctor/list.rb +2 -1
  64. data/lib/asciidoctor/logging.rb +122 -0
  65. data/lib/asciidoctor/parser.rb +406 -382
  66. data/lib/asciidoctor/path_resolver.rb +169 -162
  67. data/lib/asciidoctor/reader.rb +166 -121
  68. data/lib/asciidoctor/section.rb +45 -28
  69. data/lib/asciidoctor/stylesheets.rb +13 -5
  70. data/lib/asciidoctor/substitutors.rb +328 -254
  71. data/lib/asciidoctor/table.rb +105 -48
  72. data/lib/asciidoctor/timings.rb +34 -6
  73. data/lib/asciidoctor/version.rb +1 -1
  74. data/man/asciidoctor.1 +41 -23
  75. data/man/asciidoctor.adoc +14 -8
  76. data/test/api_test.rb +1004 -0
  77. data/test/attributes_test.rb +241 -50
  78. data/test/blocks_test.rb +549 -124
  79. data/test/converter_test.rb +170 -78
  80. data/test/document_test.rb +208 -767
  81. data/test/extensions_test.rb +188 -53
  82. data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +1 -1
  83. data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +1 -1
  84. data/test/fixtures/file-with-missing-include.adoc +1 -0
  85. data/test/fixtures/include-file.jsx +8 -0
  86. data/test/fixtures/lists.adoc +96 -0
  87. data/test/fixtures/other-chapters.adoc +11 -0
  88. data/test/fixtures/outer-include.adoc +5 -0
  89. data/test/fixtures/sample.asciidoc +5 -1
  90. data/test/fixtures/subdir/index.adoc +3 -0
  91. data/test/fixtures/subdir/inner-include.adoc +3 -0
  92. data/test/fixtures/subdir/middle-include.adoc +5 -0
  93. data/test/fixtures/tagged-class-enclosed.rb +0 -1
  94. data/test/fixtures/unclosed-tag.adoc +3 -0
  95. data/test/fixtures/unexpected-end-tag.adoc +4 -0
  96. data/test/invoker_test.rb +101 -40
  97. data/test/links_test.rb +266 -72
  98. data/test/lists_test.rb +243 -45
  99. data/test/logger_test.rb +211 -0
  100. data/test/manpage_test.rb +124 -6
  101. data/test/options_test.rb +46 -1
  102. data/test/paragraphs_test.rb +23 -10
  103. data/test/parser_test.rb +30 -1
  104. data/test/paths_test.rb +115 -33
  105. data/test/preamble_test.rb +1 -1
  106. data/test/reader_test.rb +337 -81
  107. data/test/sections_test.rb +656 -72
  108. data/test/substitutions_test.rb +182 -57
  109. data/test/tables_test.rb +324 -57
  110. data/test/test_helper.rb +77 -32
  111. data/test/text_test.rb +7 -7
  112. metadata +67 -3
@@ -0,0 +1,211 @@
1
+ # encoding: UTF-8
2
+ unless defined? ASCIIDOCTOR_PROJECT_DIR
3
+ $: << File.dirname(__FILE__); $:.uniq!
4
+ require 'test_helper'
5
+ end
6
+
7
+ context 'Logger' do
8
+ MyLogger = Class.new Logger
9
+
10
+ context 'LoggerManager' do
11
+ test 'provides access to logger via static logger method' do
12
+ logger = Asciidoctor::LoggerManager.logger
13
+ refute_nil logger
14
+ assert_kind_of Logger, logger
15
+ end
16
+
17
+ test 'allows logger instance to be changed' do
18
+ old_logger = Asciidoctor::LoggerManager.logger
19
+ new_logger = MyLogger.new $stdout
20
+ begin
21
+ Asciidoctor::LoggerManager.logger = new_logger
22
+ assert_same new_logger, Asciidoctor::LoggerManager.logger
23
+ ensure
24
+ Asciidoctor::LoggerManager.logger = old_logger
25
+ end
26
+ end
27
+
28
+ test 'setting logger instance to falsy value resets instance to default logger' do
29
+ old_logger = Asciidoctor::LoggerManager.logger
30
+ begin
31
+ Asciidoctor::LoggerManager.logger = MyLogger.new $stdout
32
+ Asciidoctor::LoggerManager.logger = nil
33
+ refute_nil Asciidoctor::LoggerManager.logger
34
+ assert_kind_of Logger, Asciidoctor::LoggerManager.logger
35
+ ensure
36
+ Asciidoctor::LoggerManager.logger = old_logger
37
+ end
38
+ end
39
+
40
+ test 'creates logger instance from static logger_class property' do
41
+ old_logger_class = Asciidoctor::LoggerManager.logger_class
42
+ old_logger = Asciidoctor::LoggerManager.logger
43
+ begin
44
+ Asciidoctor::LoggerManager.logger_class = MyLogger
45
+ Asciidoctor::LoggerManager.logger = nil
46
+ refute_nil Asciidoctor::LoggerManager.logger
47
+ assert_kind_of MyLogger, Asciidoctor::LoggerManager.logger
48
+ ensure
49
+ Asciidoctor::LoggerManager.logger_class = old_logger_class
50
+ Asciidoctor::LoggerManager.logger = old_logger
51
+ end
52
+ end
53
+ end
54
+
55
+ context 'Logger' do
56
+ test 'configures default logger with progname set to asciidoctor' do
57
+ assert_equal 'asciidoctor', Asciidoctor::LoggerManager.logger.progname
58
+ end
59
+
60
+ test 'configures default logger with level set to WARN' do
61
+ assert_equal Logger::Severity::WARN, Asciidoctor::LoggerManager.logger.level
62
+ end
63
+
64
+ test 'configures default logger to write messages to $stderr' do
65
+ out_string, err_string = redirect_streams do |out, err|
66
+ Asciidoctor::LoggerManager.logger.warn 'this is a call'
67
+ [out.string, err.string]
68
+ end
69
+ assert_empty out_string
70
+ refute_empty err_string
71
+ assert_includes err_string, 'this is a call'
72
+ end
73
+
74
+ test 'configures default logger to use a formatter that matches traditional format' do
75
+ err_string = redirect_streams do |_, err|
76
+ Asciidoctor::LoggerManager.logger.warn 'this is a call'
77
+ Asciidoctor::LoggerManager.logger.fatal 'it cannot be done'
78
+ err.string
79
+ end
80
+ assert_includes err_string, %(asciidoctor: WARNING: this is a call)
81
+ assert_includes err_string, %(asciidoctor: FAILED: it cannot be done)
82
+ end
83
+ end
84
+
85
+ context ':logger API option' do
86
+ test 'should be able to set logger when invoking load API' do
87
+ old_logger = Asciidoctor::LoggerManager.logger
88
+ new_logger = MyLogger.new $stdout
89
+ begin
90
+ Asciidoctor.load 'contents', :logger => new_logger
91
+ assert_same new_logger, Asciidoctor::LoggerManager.logger
92
+ ensure
93
+ Asciidoctor::LoggerManager.logger = old_logger
94
+ end
95
+ end
96
+
97
+ test 'should be able to set logger when invoking load_file API' do
98
+ old_logger = Asciidoctor::LoggerManager.logger
99
+ new_logger = MyLogger.new $stdout
100
+ begin
101
+ Asciidoctor.load_file fixture_path('basic.asciidoc'), :logger => new_logger
102
+ assert_same new_logger, Asciidoctor::LoggerManager.logger
103
+ ensure
104
+ Asciidoctor::LoggerManager.logger = old_logger
105
+ end
106
+ end
107
+
108
+ test 'should be able to set logger when invoking convert API' do
109
+ old_logger = Asciidoctor::LoggerManager.logger
110
+ new_logger = MyLogger.new $stdout
111
+ begin
112
+ Asciidoctor.convert 'contents', :logger => new_logger
113
+ assert_same new_logger, Asciidoctor::LoggerManager.logger
114
+ ensure
115
+ Asciidoctor::LoggerManager.logger = old_logger
116
+ end
117
+ end
118
+
119
+ test 'should be able to set logger when invoking convert_file API' do
120
+ old_logger = Asciidoctor::LoggerManager.logger
121
+ new_logger = MyLogger.new $stdout
122
+ begin
123
+ Asciidoctor.convert_file fixture_path('basic.asciidoc'), :to_file => false, :logger => new_logger
124
+ assert_same new_logger, Asciidoctor::LoggerManager.logger
125
+ ensure
126
+ Asciidoctor::LoggerManager.logger = old_logger
127
+ end
128
+ end
129
+ end
130
+
131
+ context 'Logging' do
132
+ test 'including Logging gives instance methods on module access to logging infrastructure' do
133
+ module SampleModuleA
134
+ include Asciidoctor::Logging
135
+ def get_logger
136
+ logger
137
+ end
138
+ end
139
+
140
+ class SampleClassA
141
+ include SampleModuleA
142
+ end
143
+ assert_same Asciidoctor::LoggerManager.logger, SampleClassA.new.get_logger
144
+ assert SampleClassA.private_method_defined? :logger
145
+ end
146
+
147
+ test 'including Logging gives static methods on module access to logging infrastructure' do
148
+ module SampleModuleB
149
+ include Asciidoctor::Logging
150
+ def self.get_logger
151
+ logger
152
+ end
153
+ end
154
+
155
+ assert_same Asciidoctor::LoggerManager.logger, SampleModuleB.get_logger
156
+ end
157
+
158
+ test 'including Logging gives instance methods on class access to logging infrastructure' do
159
+ class SampleClassC
160
+ include Asciidoctor::Logging
161
+ def get_logger
162
+ logger
163
+ end
164
+ end
165
+
166
+ assert_same Asciidoctor::LoggerManager.logger, SampleClassC.new.get_logger
167
+ assert SampleClassC.private_method_defined? :logger
168
+ end
169
+
170
+ test 'including Logging gives static methods on class access to logging infrastructure' do
171
+ class SampleClassD
172
+ include Asciidoctor::Logging
173
+ def self.get_logger
174
+ logger
175
+ end
176
+ end
177
+
178
+ assert_same Asciidoctor::LoggerManager.logger, SampleClassD.get_logger
179
+ end
180
+
181
+ test 'can create an auto-formatting message with context' do
182
+ class SampleClassE
183
+ include Asciidoctor::Logging
184
+ def create_message cursor
185
+ message_with_context 'Asciidoctor was here', :source_location => cursor
186
+ end
187
+ end
188
+
189
+ cursor = Asciidoctor::Reader::Cursor.new 'file.adoc', fixturedir, 'file.adoc', 5
190
+ message = SampleClassE.new.create_message cursor
191
+ assert_equal 'Asciidoctor was here', message[:text]
192
+ assert_same cursor, message[:source_location]
193
+ assert_equal 'file.adoc: line 5: Asciidoctor was here', message.inspect
194
+ end
195
+
196
+ test 'writes message prefixed with program name and source location to stderr' do
197
+ input = <<-EOS
198
+ [#first]
199
+ first paragraph
200
+
201
+ [#first]
202
+ another first paragraph
203
+ EOS
204
+ messages = redirect_streams do |_, err|
205
+ render_embedded_string input
206
+ err.string
207
+ end
208
+ assert_equal 'asciidoctor: WARNING: <stdin>: line 5: id assigned to block already in use: first', messages.chomp
209
+ end
210
+ end
211
+ end
@@ -37,33 +37,85 @@ context 'Manpage' do
37
37
  assert_equal 'command', doc.attributes['docname']
38
38
  end
39
39
 
40
+ test 'should output multiple mannames in NAME section' do
41
+ input = SAMPLE_MANPAGE_HEADER.sub(/^command - /, 'command, alt_command - ')
42
+ output = Asciidoctor.convert input, :backend => :manpage, :header_footer => true
43
+ assert_includes output.lines, %(command, alt_command \\- does stuff\n)
44
+ end
45
+
46
+ test 'should skip line comments in NAME section' do
47
+ input = <<-EOS
48
+ = foobar (1)
49
+ Author Name
50
+ :doctype: manpage
51
+ :man manual: Foo Bar Manual
52
+ :man source: Foo Bar 1.0
53
+
54
+ == NAME
55
+
56
+ // follows the form `name - description`
57
+ foobar - puts some foo on the bar
58
+ // a little bit of this, a little bit of that
59
+
60
+ == SYNOPSIS
61
+
62
+ *foobar* [_OPTIONS_]...
63
+
64
+ == DESCRIPTION
65
+
66
+ When you need to put some foo on the bar.
67
+ EOS
68
+
69
+ doc = Asciidoctor.load input, :backend => :manpage, :header_footer => true
70
+ assert_equal 'puts some foo on the bar', (doc.attr 'manpurpose')
71
+ end
72
+
40
73
  test 'should define default linkstyle' do
41
74
  input = SAMPLE_MANPAGE_HEADER
42
75
  output = Asciidoctor.convert input, :backend => :manpage, :header_footer => true
43
- assert_includes output.lines, %(.LINKSTYLE blue R < >\n)
76
+ assert_includes output.lines, %(. LINKSTYLE blue R < >\n)
44
77
  end
45
78
 
46
79
  test 'should use linkstyle defined by man-linkstyle attribute' do
47
80
  input = SAMPLE_MANPAGE_HEADER
48
81
  output = Asciidoctor.convert input, :backend => :manpage, :header_footer => true,
49
82
  :attributes => { 'man-linkstyle' => 'cyan B \[fo] \[fc]' }
50
- assert_includes output.lines, %(.LINKSTYLE cyan B \\[fo] \\[fc]\n)
83
+ assert_includes output.lines, %(. LINKSTYLE cyan B \\[fo] \\[fc]\n)
51
84
  end
52
85
 
53
86
  test 'should require specialchars in value of man-linkstyle attribute defined in document to be escaped' do
54
87
  input = %(:man-linkstyle: cyan R < >
55
88
  #{SAMPLE_MANPAGE_HEADER})
56
89
  output = Asciidoctor.convert input, :backend => :manpage, :header_footer => true
57
- assert_includes output.lines, %(.LINKSTYLE cyan R &lt; &gt;\n)
90
+ assert_includes output.lines, %(. LINKSTYLE cyan R &lt; &gt;\n)
58
91
 
59
92
  input = %(:man-linkstyle: pass:[cyan R < >]
60
93
  #{SAMPLE_MANPAGE_HEADER})
61
94
  output = Asciidoctor.convert input, :backend => :manpage, :header_footer => true
62
- assert_includes output.lines, %(.LINKSTYLE cyan R < >\n)
95
+ assert_includes output.lines, %(. LINKSTYLE cyan R < >\n)
63
96
  end
64
97
  end
65
98
 
66
99
  context 'Manify' do
100
+ test 'should unescape literal ampersand' do
101
+ input = %(#{SAMPLE_MANPAGE_HEADER}
102
+
103
+ (C) & (R) are translated to character references, but not the &.)
104
+ output = Asciidoctor.convert input, :backend => :manpage
105
+ assert_equal '\\(co & \\(rg are translated to character references, but not the &.', output.lines.entries.last.chomp
106
+ end
107
+
108
+ test 'should replace em dashes' do
109
+ input = %(#{SAMPLE_MANPAGE_HEADER}
110
+
111
+ go -- to
112
+
113
+ go--to)
114
+ output = Asciidoctor.convert input, :backend => :manpage
115
+ assert_includes output, 'go \\(em to'
116
+ assert_includes output, 'go\\(emto'
117
+ end
118
+
67
119
  test 'should escape lone period' do
68
120
  input = %(#{SAMPLE_MANPAGE_HEADER}
69
121
 
@@ -98,7 +150,7 @@ BBB this line and the one above it should be visible)
98
150
 
99
151
  "`hello`" '`goodbye`' *strong* _weak_ `even`)
100
152
  output = Asciidoctor.convert input, :backend => :manpage
101
- assert_equal '\(lqhello\(rq \(oqgoodbye\(cq \fBstrong\fP \fIweak\fP \f[CR]even\fP', output.lines.entries.last.chomp
153
+ assert_equal '\(lqhello\(rq \(oqgoodbye\(cq \fBstrong\fP \fIweak\fP \f(CReven\fP', output.lines.entries.last.chomp
102
154
  end
103
155
 
104
156
  test 'should escape backslashes in content' do
@@ -216,15 +268,81 @@ Please search |\c
216
268
  .URL "http://discuss.asciidoctor.org" "the forums" "|"
217
269
  before asking.', output.lines.entries[-4..-1].join
218
270
  end
271
+
272
+ test 'should be able to use monospaced text inside a link' do
273
+ input = %(#{SAMPLE_MANPAGE_HEADER}
274
+
275
+ Enter the link:cat[`cat`] command.)
276
+ output = Asciidoctor.convert input, :backend => :manpage
277
+ assert_equal '.sp
278
+ Enter the \c
279
+ .URL "cat" "\f(CRcat\fP" " "
280
+ command.', output.lines.entries[-4..-1].join
281
+ end
282
+ end
283
+
284
+ context 'MTO macro' do
285
+ test 'should convert inline email macro into MTO macro' do
286
+ input = %(#{SAMPLE_MANPAGE_HEADER}
287
+ First paragraph.
288
+
289
+ mailto:doc@example.org[Contact the doc])
290
+ output = Asciidoctor.convert input, :backend => :manpage
291
+ assert_equal '.sp
292
+ First paragraph.
293
+ .sp
294
+ .MTO "doc\\(atexample.org" "Contact the doc" ""', output.lines.entries[-4..-1].join
295
+ end
296
+
297
+ test 'should set text of MTO macro to blank for implicit email' do
298
+ input = %(#{SAMPLE_MANPAGE_HEADER}
299
+ Bugs fixed daily by doc@example.org.)
300
+ output = Asciidoctor.convert input, :backend => :manpage
301
+ assert output.end_with? 'Bugs fixed daily by \\c
302
+ .MTO "doc\\(atexample.org" "" "."'
303
+ end
219
304
  end
220
305
 
221
306
  context 'Table' do
307
+ test 'should create header, body, and footer rows in correct order' do
308
+ input = %(#{SAMPLE_MANPAGE_HEADER}
309
+
310
+ [%header%footer]
311
+ |===
312
+ |Header
313
+ |Body 1
314
+ |Body 2
315
+ |Footer
316
+ |===)
317
+ output = Asciidoctor.convert input, :backend => :manpage
318
+ assert output.end_with? 'allbox tab(:);
319
+ lt.
320
+ T{
321
+ .sp
322
+ Header
323
+ T}
324
+ T{
325
+ .sp
326
+ Body 1
327
+ T}
328
+ T{
329
+ .sp
330
+ Body 2
331
+ T}
332
+ T{
333
+ .sp
334
+ Footer
335
+ T}
336
+ .TE
337
+ .sp'
338
+ end
339
+
222
340
  test 'should manify normal table cell content' do
223
341
  input = %(#{SAMPLE_MANPAGE_HEADER}
224
342
 
225
- [%header%footer,cols=2*]
226
343
  |===
227
344
  |*Col A* |_Col B_
345
+
228
346
  |*bold* |`mono`
229
347
  |_italic_ | #mark#
230
348
  |===)
@@ -31,6 +31,24 @@ context 'Options' do
31
31
  assert_includes output, '.TH "ASCIIDOCTOR"'
32
32
  end
33
33
 
34
+ test 'should print message and return error code 1 when manpage is not found' do
35
+ old_manpage_path = ENV['ASCIIDOCTOR_MANPAGE_PATH']
36
+ begin
37
+ ENV['ASCIIDOCTOR_MANPAGE_PATH'] = (manpage_path = fixture_path 'no-such-file.1')
38
+ redirect_streams do |out, stderr|
39
+ exitval = Asciidoctor::Cli::Options.parse!(%w(-h manpage))
40
+ assert_equal 1, exitval
41
+ assert_equal %(asciidoctor: FAILED: manual page not found: #{manpage_path}), stderr.string.chomp
42
+ end
43
+ ensure
44
+ if old_manpage_path
45
+ ENV['ASCIIDOCTOR_MANPAGE_PATH'] = old_manpage_path
46
+ else
47
+ ENV.delete 'ASCIIDOCTOR_MANPAGE_PATH'
48
+ end
49
+ end
50
+ end
51
+
34
52
  test 'should return error code 1 when invalid option present' do
35
53
  redirect_streams do |stdout, stderr|
36
54
  exitval = Asciidoctor::Cli::Options.parse!(%w(--foobar))
@@ -58,7 +76,7 @@ context 'Options' do
58
76
  test 'should emit warning when unparsed options remain' do
59
77
  redirect_streams do |stdout, stderr|
60
78
  options = Asciidoctor::Cli::Options.parse!(%w(-b docbook - -))
61
- assert options.is_a? Hash
79
+ assert_kind_of Hash, options
62
80
  assert_match(/asciidoctor: WARNING: extra arguments .*/, stderr.string.chomp)
63
81
  end
64
82
  end
@@ -184,6 +202,33 @@ context 'Options' do
184
202
  end
185
203
  end
186
204
 
205
+ test 'should set failure level to FATAL by default' do
206
+ options = Asciidoctor::Cli::Options.parse! %W(test/fixtures/sample.asciidoc)
207
+ assert_equal ::Logger::Severity::FATAL, options[:failure_level]
208
+ end
209
+
210
+ test 'should allow failure level to be set to WARN' do
211
+ %w(w warn WARN warning WARNING).each do |val|
212
+ options = Asciidoctor::Cli::Options.parse!(%W(--failure-level=#{val} test/fixtures/sample.asciidoc))
213
+ assert_equal ::Logger::Severity::WARN, options[:failure_level]
214
+ end
215
+ end
216
+
217
+ test 'should allow failure level to be set to ERROR' do
218
+ %w(e err ERR error ERROR).each do |val|
219
+ options = Asciidoctor::Cli::Options.parse!(%W(--failure-level=#{val} test/fixtures/sample.asciidoc))
220
+ assert_equal ::Logger::Severity::ERROR, options[:failure_level]
221
+ end
222
+ end
223
+
224
+ test 'should not allow failure level to be set to unknown value' do
225
+ exit_code, messages = redirect_streams do |_, err|
226
+ [(Asciidoctor::Cli::Options.parse! %W(--failure-level=foobar test/fixtures/sample.asciidoc)), err.string]
227
+ end
228
+ assert_equal 1, exit_code
229
+ assert_includes messages, 'invalid argument: --failure-level=foobar'
230
+ end
231
+
187
232
  test 'should set verbose to 2 when -v flag is specified' do
188
233
  options = Asciidoctor::Cli::Options.parse!(%w(-v test/fixtures/sample.asciidoc))
189
234
  assert_equal 2, options[:verbose]