asciidoctor 1.5.8 → 2.0.17

Sign up to get free protection for your applications and to get access to all the features.
Files changed (197) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +11 -0
  3. data/CHANGELOG.adoc +628 -45
  4. data/LICENSE +2 -1
  5. data/README-de.adoc +28 -38
  6. data/README-fr.adoc +30 -43
  7. data/README-jp.adoc +255 -201
  8. data/README-zh_CN.adoc +40 -44
  9. data/README.adoc +170 -143
  10. data/asciidoctor.gemspec +22 -34
  11. data/bin/asciidoctor +5 -4
  12. data/data/locale/attributes-ar.adoc +4 -3
  13. data/data/locale/attributes-be.adoc +23 -0
  14. data/data/locale/attributes-bg.adoc +4 -3
  15. data/data/locale/attributes-ca.adoc +6 -5
  16. data/data/locale/attributes-cs.adoc +4 -3
  17. data/data/locale/attributes-da.adoc +6 -5
  18. data/data/locale/attributes-de.adoc +6 -5
  19. data/data/locale/attributes-en.adoc +4 -4
  20. data/data/locale/attributes-es.adoc +6 -5
  21. data/data/locale/attributes-fa.adoc +4 -3
  22. data/data/locale/attributes-fi.adoc +4 -3
  23. data/data/locale/attributes-fr.adoc +8 -7
  24. data/data/locale/attributes-hu.adoc +4 -3
  25. data/data/locale/attributes-id.adoc +4 -3
  26. data/data/locale/attributes-it.adoc +6 -5
  27. data/data/locale/attributes-ja.adoc +4 -3
  28. data/data/locale/{attributes-kr.adoc → attributes-ko.adoc} +4 -3
  29. data/data/locale/attributes-nb.adoc +4 -3
  30. data/data/locale/attributes-nl.adoc +6 -5
  31. data/data/locale/attributes-nn.adoc +4 -3
  32. data/data/locale/attributes-pl.adoc +8 -7
  33. data/data/locale/attributes-pt.adoc +6 -5
  34. data/data/locale/attributes-pt_BR.adoc +6 -5
  35. data/data/locale/attributes-ro.adoc +4 -3
  36. data/data/locale/attributes-ru.adoc +6 -5
  37. data/data/locale/attributes-sr.adoc +4 -4
  38. data/data/locale/attributes-sr_Latn.adoc +4 -4
  39. data/data/locale/attributes-sv.adoc +4 -4
  40. data/data/locale/attributes-th.adoc +23 -0
  41. data/data/locale/attributes-tr.adoc +4 -3
  42. data/data/locale/attributes-uk.adoc +6 -5
  43. data/data/locale/attributes-vi.adoc +23 -0
  44. data/data/locale/attributes-zh_CN.adoc +4 -3
  45. data/data/locale/attributes-zh_TW.adoc +4 -3
  46. data/data/reference/syntax.adoc +296 -0
  47. data/data/stylesheets/asciidoctor-default.css +120 -114
  48. data/data/stylesheets/coderay-asciidoctor.css +15 -17
  49. data/lib/asciidoctor/abstract_block.rb +146 -140
  50. data/lib/asciidoctor/abstract_node.rb +152 -170
  51. data/lib/asciidoctor/attribute_list.rb +77 -89
  52. data/lib/asciidoctor/block.rb +29 -28
  53. data/lib/asciidoctor/callouts.rb +4 -2
  54. data/lib/asciidoctor/cli/invoker.rb +20 -24
  55. data/lib/asciidoctor/cli/options.rb +107 -96
  56. data/lib/asciidoctor/cli.rb +3 -2
  57. data/lib/asciidoctor/convert.rb +199 -0
  58. data/lib/asciidoctor/converter/composite.rb +40 -48
  59. data/lib/asciidoctor/converter/docbook5.rb +627 -644
  60. data/lib/asciidoctor/converter/html5.rb +1053 -951
  61. data/lib/asciidoctor/converter/manpage.rb +581 -532
  62. data/lib/asciidoctor/converter/template.rb +232 -271
  63. data/lib/asciidoctor/converter.rb +370 -185
  64. data/lib/asciidoctor/core_ext/float/truncate.rb +20 -0
  65. data/lib/asciidoctor/core_ext/hash/merge.rb +8 -0
  66. data/lib/asciidoctor/core_ext/match_data/names.rb +7 -0
  67. data/lib/asciidoctor/core_ext/nil_or_empty.rb +1 -0
  68. data/lib/asciidoctor/core_ext/regexp/is_match.rb +4 -2
  69. data/lib/asciidoctor/core_ext.rb +8 -17
  70. data/lib/asciidoctor/document.rb +503 -461
  71. data/lib/asciidoctor/extensions.rb +127 -174
  72. data/lib/asciidoctor/helpers.rb +184 -107
  73. data/lib/asciidoctor/inline.rb +9 -12
  74. data/lib/asciidoctor/list.rb +11 -29
  75. data/lib/asciidoctor/load.rb +119 -0
  76. data/lib/asciidoctor/logging.rb +22 -17
  77. data/lib/asciidoctor/parser.rb +673 -719
  78. data/lib/asciidoctor/path_resolver.rb +48 -33
  79. data/lib/asciidoctor/reader.rb +383 -338
  80. data/lib/asciidoctor/rouge_ext.rb +39 -0
  81. data/lib/asciidoctor/rx.rb +723 -0
  82. data/lib/asciidoctor/section.rb +17 -16
  83. data/lib/asciidoctor/stylesheets.rb +19 -37
  84. data/lib/asciidoctor/substitutors.rb +926 -1022
  85. data/lib/asciidoctor/syntax_highlighter/coderay.rb +88 -0
  86. data/lib/asciidoctor/syntax_highlighter/highlightjs.rb +34 -0
  87. data/lib/asciidoctor/syntax_highlighter/html_pipeline.rb +10 -0
  88. data/lib/asciidoctor/syntax_highlighter/prettify.rb +30 -0
  89. data/lib/asciidoctor/syntax_highlighter/pygments.rb +157 -0
  90. data/lib/asciidoctor/syntax_highlighter/rouge.rb +143 -0
  91. data/lib/asciidoctor/syntax_highlighter.rb +253 -0
  92. data/lib/asciidoctor/table.rb +152 -114
  93. data/lib/asciidoctor/timings.rb +7 -5
  94. data/lib/asciidoctor/version.rb +2 -1
  95. data/lib/asciidoctor/writer.rb +30 -0
  96. data/lib/asciidoctor.rb +266 -1340
  97. data/man/asciidoctor.1 +49 -47
  98. data/man/asciidoctor.adoc +54 -45
  99. metadata +50 -245
  100. data/CONTRIBUTING.adoc +0 -185
  101. data/Gemfile +0 -60
  102. data/Rakefile +0 -129
  103. data/bin/asciidoctor-safe +0 -15
  104. data/features/open_block.feature +0 -92
  105. data/features/pass_block.feature +0 -66
  106. data/features/step_definitions.rb +0 -49
  107. data/features/text_formatting.feature +0 -57
  108. data/features/xref.feature +0 -1039
  109. data/lib/asciidoctor/converter/base.rb +0 -59
  110. data/lib/asciidoctor/converter/docbook45.rb +0 -93
  111. data/lib/asciidoctor/converter/factory.rb +0 -226
  112. data/lib/asciidoctor/core_ext/1.8.7/base64/strict_encode64.rb +0 -6
  113. data/lib/asciidoctor/core_ext/1.8.7/concurrent/hash.rb +0 -5
  114. data/lib/asciidoctor/core_ext/1.8.7/hash/key.rb +0 -4
  115. data/lib/asciidoctor/core_ext/1.8.7/io/binread.rb +0 -6
  116. data/lib/asciidoctor/core_ext/1.8.7/io/write.rb +0 -5
  117. data/lib/asciidoctor/core_ext/1.8.7/string/chr.rb +0 -6
  118. data/lib/asciidoctor/core_ext/1.8.7/string/limit_bytesize.rb +0 -29
  119. data/lib/asciidoctor/core_ext/1.8.7/symbol/empty.rb +0 -6
  120. data/lib/asciidoctor/core_ext/1.8.7/symbol/length.rb +0 -6
  121. data/lib/asciidoctor/core_ext/string/limit_bytesize.rb +0 -10
  122. data/test/api_test.rb +0 -1240
  123. data/test/attribute_list_test.rb +0 -242
  124. data/test/attributes_test.rb +0 -1623
  125. data/test/blocks_test.rb +0 -3870
  126. data/test/converter_test.rb +0 -470
  127. data/test/document_test.rb +0 -1853
  128. data/test/extensions_test.rb +0 -1560
  129. data/test/fixtures/asciidoc_index.txt +0 -521
  130. data/test/fixtures/basic-docinfo-footer.html +0 -6
  131. data/test/fixtures/basic-docinfo-footer.xml +0 -8
  132. data/test/fixtures/basic-docinfo.html +0 -1
  133. data/test/fixtures/basic-docinfo.xml +0 -4
  134. data/test/fixtures/basic.asciidoc +0 -5
  135. data/test/fixtures/chapter-a.adoc +0 -3
  136. data/test/fixtures/child-include.adoc +0 -5
  137. data/test/fixtures/circle.svg +0 -9
  138. data/test/fixtures/custom-backends/erb/html5/block_paragraph.html.erb +0 -6
  139. data/test/fixtures/custom-backends/haml/docbook45/block_paragraph.xml.haml +0 -6
  140. data/test/fixtures/custom-backends/haml/html5/block_paragraph.html.haml +0 -3
  141. data/test/fixtures/custom-backends/haml/html5/block_sidebar.html.haml +0 -5
  142. data/test/fixtures/custom-backends/haml/html5-tweaks/block_paragraph.html.haml +0 -1
  143. data/test/fixtures/custom-backends/slim/docbook45/block_paragraph.xml.slim +0 -6
  144. data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +0 -3
  145. data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +0 -5
  146. data/test/fixtures/custom-docinfodir/basic-docinfo.html +0 -1
  147. data/test/fixtures/custom-docinfodir/docinfo.html +0 -1
  148. data/test/fixtures/docinfo-footer.html +0 -1
  149. data/test/fixtures/docinfo-footer.xml +0 -9
  150. data/test/fixtures/docinfo.html +0 -1
  151. data/test/fixtures/docinfo.xml +0 -3
  152. data/test/fixtures/doctime-localtime.adoc +0 -2
  153. data/test/fixtures/dot.gif +0 -0
  154. data/test/fixtures/encoding.asciidoc +0 -13
  155. data/test/fixtures/file-with-missing-include.adoc +0 -1
  156. data/test/fixtures/grandchild-include.adoc +0 -3
  157. data/test/fixtures/hello-asciidoctor.pdf +0 -69
  158. data/test/fixtures/include-file.asciidoc +0 -24
  159. data/test/fixtures/include-file.jsx +0 -8
  160. data/test/fixtures/include-file.ml +0 -3
  161. data/test/fixtures/include-file.xml +0 -5
  162. data/test/fixtures/lists.adoc +0 -96
  163. data/test/fixtures/master.adoc +0 -5
  164. data/test/fixtures/mismatched-end-tag.adoc +0 -7
  165. data/test/fixtures/other-chapters.adoc +0 -11
  166. data/test/fixtures/outer-include.adoc +0 -5
  167. data/test/fixtures/parent-include-restricted.adoc +0 -5
  168. data/test/fixtures/parent-include.adoc +0 -5
  169. data/test/fixtures/sample.asciidoc +0 -30
  170. data/test/fixtures/section-a.adoc +0 -4
  171. data/test/fixtures/stylesheets/custom.css +0 -3
  172. data/test/fixtures/subdir/index.adoc +0 -3
  173. data/test/fixtures/subdir/inner-include.adoc +0 -3
  174. data/test/fixtures/subdir/middle-include.adoc +0 -5
  175. data/test/fixtures/subs-docinfo.html +0 -2
  176. data/test/fixtures/subs.adoc +0 -6
  177. data/test/fixtures/tagged-class-enclosed.rb +0 -25
  178. data/test/fixtures/tagged-class.rb +0 -23
  179. data/test/fixtures/tip.gif +0 -0
  180. data/test/fixtures/unclosed-tag.adoc +0 -3
  181. data/test/fixtures/unexpected-end-tag.adoc +0 -4
  182. data/test/invoker_test.rb +0 -745
  183. data/test/links_test.rb +0 -855
  184. data/test/lists_test.rb +0 -5151
  185. data/test/logger_test.rb +0 -211
  186. data/test/manpage_test.rb +0 -660
  187. data/test/options_test.rb +0 -262
  188. data/test/paragraphs_test.rb +0 -562
  189. data/test/parser_test.rb +0 -742
  190. data/test/paths_test.rb +0 -395
  191. data/test/preamble_test.rb +0 -173
  192. data/test/reader_test.rb +0 -2161
  193. data/test/sections_test.rb +0 -3575
  194. data/test/substitutions_test.rb +0 -2066
  195. data/test/tables_test.rb +0 -2036
  196. data/test/test_helper.rb +0 -447
  197. data/test/text_test.rb +0 -309
data/test/test_helper.rb DELETED
@@ -1,447 +0,0 @@
1
- # encoding: UTF-8
2
- ASCIIDOCTOR_TEST_DIR = File.expand_path File.dirname __FILE__
3
- ASCIIDOCTOR_PROJECT_DIR = File.dirname ASCIIDOCTOR_TEST_DIR
4
- ASCIIDOCTOR_LIB_DIR = ENV['ASCIIDOCTOR_LIB_DIR'] || File.join(ASCIIDOCTOR_PROJECT_DIR, 'lib')
5
- Dir.chdir ASCIIDOCTOR_PROJECT_DIR
6
-
7
- if RUBY_VERSION < '1.9'
8
- require 'rubygems'
9
- end
10
-
11
- require 'simplecov' if ENV['COVERAGE'] == 'true'
12
-
13
- require File.join(ASCIIDOCTOR_LIB_DIR, 'asciidoctor')
14
-
15
- require 'socket'
16
- require 'nokogiri'
17
- require 'tempfile'
18
- require 'tmpdir'
19
-
20
- autoload :FileUtils, 'fileutils'
21
- autoload :Pathname, 'pathname'
22
- autoload :Open3, 'open3'
23
-
24
- RE_XMLNS_ATTRIBUTE = / xmlns="[^"]+"/
25
- RE_DOCTYPE = /\s*<!DOCTYPE (.*)/
26
-
27
- require 'minitest/autorun'
28
-
29
- # Minitest 4 doesn't have Minitest::Test
30
- Minitest::Test = MiniTest::Unit::TestCase unless defined? Minitest::Test
31
-
32
- class Minitest::Test
33
- def windows?
34
- RbConfig::CONFIG['host_os'] =~ /win|ming/
35
- end
36
-
37
- def disk_root
38
- %(#{windows? ? ASCIIDOCTOR_PROJECT_DIR.split('/')[0] : ''}/)
39
- end
40
-
41
- def empty_document options = {}
42
- if options[:parse]
43
- (Asciidoctor::Document.new [], options).parse
44
- else
45
- Asciidoctor::Document.new [], options
46
- end
47
- end
48
-
49
- def empty_safe_document options = {}
50
- options[:safe] = :safe
51
- Asciidoctor::Document.new [], options
52
- end
53
-
54
- def sample_doc_path(name)
55
- name = name.to_s
56
- unless name.include?('.')
57
- ['asciidoc', 'txt'].each do |ext|
58
- if File.exist?(fixture_path("#{name}.#{ext}"))
59
- name = "#{name}.#{ext}"
60
- break
61
- end
62
- end
63
- end
64
- fixture_path(name)
65
- end
66
-
67
- def testdir
68
- ASCIIDOCTOR_TEST_DIR
69
- end
70
-
71
- def fixturedir
72
- File.join testdir, 'fixtures'
73
- end
74
-
75
- def fixture_path name
76
- File.join fixturedir, name
77
- end
78
-
79
- def example_document(name, opts = {})
80
- document_from_string IO.read(sample_doc_path(name)), opts
81
- end
82
-
83
- def xmlnodes_at_css(css, content, count = nil)
84
- xmlnodes_at_path(:css, css, content, count)
85
- end
86
-
87
- def xmlnodes_at_xpath(xpath, content, count = nil)
88
- xmlnodes_at_path(:xpath, xpath, content, count)
89
- end
90
-
91
- def xmlnodes_at_path(type, path, content, count = nil)
92
- doc = xmldoc_from_string content
93
- case type
94
- when :xpath
95
- namespaces = doc.respond_to?(:root) ? doc.root.namespaces : {}
96
- results = doc.xpath("#{path.sub('/', './')}", namespaces)
97
- when :css
98
- results = doc.css(path)
99
- end
100
- count == 1 ? results.first : results
101
- end
102
-
103
- # Generate an xpath attribute matcher that matches a name in the class attribute
104
- def contains_class(name)
105
- %(contains(concat(' ', normalize-space(@class), ' '), ' #{name} '))
106
- end
107
-
108
- def assert_css(css, content, count = nil)
109
- assert_path(:css, css, content, count)
110
- end
111
-
112
- def assert_xpath(xpath, content, count = nil)
113
- assert_path(:xpath, xpath, content, count)
114
- end
115
-
116
- def assert_path(type, path, content, count = nil)
117
- case type
118
- when :xpath
119
- type_name = 'XPath'
120
- when :css
121
- type_name = 'CSS'
122
- end
123
-
124
- results = xmlnodes_at_path type, path, content
125
-
126
- if (count == true || count == false)
127
- if (count != results)
128
- flunk "#{type_name} #{path} yielded #{results} rather than #{count} for:\n#{content}"
129
- else
130
- assert true
131
- end
132
- elsif (count && results.size != count)
133
- flunk "#{type_name} #{path} yielded #{results.size} elements rather than #{count} for:\n#{content}"
134
- elsif (count.nil? && results.empty?)
135
- flunk "#{type_name} #{path} not found in:\n#{content}"
136
- else
137
- assert true
138
- end
139
- end
140
-
141
- def assert_message logger, severity, expected_message, kind = String, idx = nil
142
- unless idx
143
- assert_equal 1, logger.messages.size
144
- idx = 0
145
- end
146
- message = logger.messages[idx]
147
- assert_equal severity, message[:severity]
148
- assert_kind_of kind, message[:message]
149
- if kind == String
150
- actual_message = message[:message]
151
- else
152
- refute_nil message[:message][:source_location]
153
- actual_message = message[:message].inspect
154
- end
155
- if expected_message.start_with? '~'
156
- assert_includes actual_message, expected_message[1..-1]
157
- else
158
- assert_equal expected_message, actual_message
159
- end
160
- end
161
-
162
- def assert_messages logger, expected_messages
163
- assert_equal expected_messages.size, logger.messages.size
164
- expected_messages.each_with_index do |expected_message_details, idx|
165
- severity, expected_message, kind = expected_message_details
166
- assert_message logger, severity, expected_message, (kind || String), idx
167
- end
168
- end
169
-
170
- def xmldoc_from_string(content)
171
- if content.match(RE_XMLNS_ATTRIBUTE)
172
- Nokogiri::XML::Document.parse(content)
173
- elsif !(doctype_match = content.match(RE_DOCTYPE))
174
- Nokogiri::HTML::DocumentFragment.parse(content)
175
- elsif doctype_match[1].start_with? 'html'
176
- Nokogiri::HTML::Document.parse(content)
177
- else
178
- Nokogiri::XML::Document.parse(content)
179
- end
180
- end
181
-
182
- def document_from_string(src, opts = {})
183
- assign_default_test_options opts
184
- if opts[:parse]
185
- (Asciidoctor::Document.new src.lines.entries, opts).parse
186
- else
187
- Asciidoctor::Document.new src.lines.entries, opts
188
- end
189
- end
190
-
191
- def block_from_string(src, opts = {})
192
- opts[:header_footer] = false
193
- doc = document_from_string src, opts
194
- doc.blocks.first
195
- end
196
-
197
- def convert_string(src, opts = {})
198
- keep_namespaces = opts.delete(:keep_namespaces)
199
- if keep_namespaces
200
- document_from_string(src, opts).convert
201
- else
202
- # this is required because nokogiri is ignorant
203
- result = document_from_string(src, opts).convert
204
- result = result.sub(RE_XMLNS_ATTRIBUTE, '') if result
205
- result
206
- end
207
- end
208
-
209
- def convert_string_to_embedded(src, opts = {})
210
- opts[:header_footer] = false
211
- document_from_string(src, opts).convert
212
- end
213
-
214
- def convert_inline_string(src, opts = {})
215
- opts[:doctype] = :inline
216
- document_from_string(src, opts).convert
217
- end
218
-
219
- def parse_header_metadata(source, doc = nil)
220
- reader = Asciidoctor::Reader.new source.split ::Asciidoctor::LF
221
- [::Asciidoctor::Parser.parse_header_metadata(reader, doc), reader]
222
- end
223
-
224
- def assign_default_test_options(opts)
225
- opts[:header_footer] = true unless opts.key? :header_footer
226
- opts[:parse] = true unless opts.key? :parse
227
- if opts[:header_footer]
228
- # don't embed stylesheet unless test requests the default behavior
229
- if opts.has_key? :linkcss_default
230
- opts.delete(:linkcss_default)
231
- else
232
- opts[:attributes] ||= {}
233
- opts[:attributes]['linkcss'] = ''
234
- end
235
- end
236
- if (template_dir = ENV['TEMPLATE_DIR'])
237
- opts[:template_dir] = template_dir unless opts.has_key? :template_dir
238
- end
239
- nil
240
- end
241
-
242
- # Decode the numeric character reference, such as 8212, to a Unicode glyph
243
- # so it may be used in an XPath expression.
244
- #
245
- # Examples
246
- #
247
- # decode_char 60
248
- # # => "<"
249
- #
250
- # Returns the decoded String that corresponds to the numeric character reference
251
- def decode_char number
252
- [number].pack 'U1'
253
- end
254
-
255
- def invoke_cli_with_filenames(argv = [], filenames = [], &block)
256
- filepaths = Array.new
257
-
258
- filenames.each {|filename|
259
- if filenames.nil? || ::Pathname.new(filename).absolute?
260
- filepaths << filename
261
- else
262
- filepaths << (fixture_path filename)
263
- end
264
- }
265
-
266
- invoker = Asciidoctor::Cli::Invoker.new(argv + filepaths)
267
-
268
- invoker.invoke!(&block)
269
- invoker
270
- end
271
-
272
- def invoke_cli_to_buffer(argv = [], filename = 'sample.asciidoc', &block)
273
- invoke_cli(argv, filename, [StringIO.new, StringIO.new], &block)
274
- end
275
-
276
- def invoke_cli(argv = [], filename = 'sample.asciidoc', buffers = nil, &block)
277
- if filename.nil? || filename == '-' || ::Pathname.new(filename).absolute?
278
- filepath = filename
279
- else
280
- filepath = fixture_path filename
281
- end
282
- invoker = Asciidoctor::Cli::Invoker.new(argv + [filepath])
283
- if buffers
284
- invoker.redirect_streams(*buffers)
285
- end
286
- invoker.invoke!(&block)
287
- invoker
288
- end
289
-
290
- def redirect_streams
291
- old_stdout, $stdout = $stdout, (tmp_stdout = ::StringIO.new)
292
- old_stderr, $stderr = $stderr, (tmp_stderr = ::StringIO.new)
293
- old_logger = Asciidoctor::LoggerManager.logger
294
- old_logger_level = old_logger.level
295
- new_logger = (Asciidoctor::LoggerManager.logger = Asciidoctor::Logger.new $stderr)
296
- new_logger.level = old_logger_level
297
- yield tmp_stdout, tmp_stderr
298
- ensure
299
- $stdout, $stderr = old_stdout, old_stderr
300
- Asciidoctor::LoggerManager.logger = old_logger
301
- end
302
-
303
- def resolve_localhost
304
- (RUBY_VERSION < '1.9' || RUBY_ENGINE == 'rbx') ? Socket.gethostname :
305
- Socket.ip_address_list.find {|addr| addr.ipv4? }.ip_address
306
- end
307
-
308
- def using_memory_logger
309
- old_logger = Asciidoctor::LoggerManager.logger
310
- memory_logger = Asciidoctor::MemoryLogger.new
311
- begin
312
- Asciidoctor::LoggerManager.logger = memory_logger
313
- yield memory_logger
314
- ensure
315
- Asciidoctor::LoggerManager.logger = old_logger
316
- end
317
- end
318
-
319
- def in_verbose_mode
320
- begin
321
- old_verbose, $VERBOSE = $VERBOSE, true
322
- yield
323
- ensure
324
- $VERBOSE = old_verbose
325
- end
326
- end
327
-
328
- def using_test_webserver host = resolve_localhost, port = 9876
329
- server = TCPServer.new host, port
330
- base_dir = testdir
331
- t = Thread.new do
332
- while (session = server.accept)
333
- request = session.gets
334
- resource = nil
335
- if (m = /GET (\S+) HTTP\/1\.1$/.match(request.chomp))
336
- resource = (resource = m[1]) == '' ? '.' : resource
337
- else
338
- session.print %(HTTP/1.1 405 Method Not Allowed\r\nContent-Type: text/plain\r\n\r\n)
339
- session.print %(405 - Method not allowed\n)
340
- session.close
341
- break
342
- end
343
-
344
- if resource == '/name/asciidoctor'
345
- session.print %(HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n)
346
- session.print %({"name": "asciidoctor"}\n)
347
- elsif File.file?(resource_file = (File.join base_dir, resource))
348
- mimetype = if (ext = ::File.extname(resource_file)[1..-1])
349
- ext == 'adoc' ? 'text/plain' : %(image/#{ext})
350
- else
351
- 'text/plain'
352
- end
353
- session.print %(HTTP/1.1 200 OK\r\nContent-Type: #{mimetype}\r\n\r\n)
354
- File.open resource_file, 'rb' do |fd|
355
- until fd.eof? do
356
- buffer = fd.read 256
357
- session.write buffer
358
- end
359
- end
360
- else
361
- session.print %(HTTP/1.1 404 File Not Found\r\nContent-Type: text/plain\r\n\r\n)
362
- session.print %(404 - Resource not found.\n)
363
- end
364
- session.close
365
- end
366
- end
367
- begin
368
- yield
369
- ensure
370
- begin
371
- server.shutdown
372
- # "Errno::ENOTCONN: Socket is not connected' is reported on some platforms; call #close instead of #shutdown
373
- rescue Errno::ENOTCONN
374
- server.close
375
- end
376
- t.exit
377
- end
378
- end
379
- end
380
-
381
- ###
382
- #
383
- # Context goodness provided by @citrusbyte's contest.
384
- # See https://github.com/citrusbyte/contest
385
- #
386
- ###
387
-
388
- # Contest adds +teardown+, +test+ and +context+ as class methods, and the
389
- # instance methods +setup+ and +teardown+ now iterate on the corresponding
390
- # blocks. Note that all setup and teardown blocks must be defined with the
391
- # block syntax. Adding setup or teardown instance methods defeats the purpose
392
- # of this library.
393
- class Minitest::Test
394
- def self.setup(&block)
395
- define_method :setup do
396
- super(&block)
397
- instance_eval(&block)
398
- end
399
- end
400
-
401
- def self.teardown(&block)
402
- define_method :teardown do
403
- instance_eval(&block)
404
- super(&block)
405
- end
406
- end
407
-
408
- def self.context(*name, &block)
409
- subclass = Class.new(self)
410
- remove_tests(subclass)
411
- subclass.class_eval(&block) if block_given?
412
- const_set(context_name(name.join(" ")), subclass)
413
- end
414
-
415
- def self.test(name, &block)
416
- define_method(test_name(name), &block)
417
- end
418
-
419
- class << self
420
- alias_method :should, :test
421
- alias_method :describe, :context
422
- end
423
-
424
- private
425
-
426
- def self.context_name(name)
427
- "Test#{sanitize_name(name).gsub(/(^| )(\w)/) { $2.upcase }}".to_sym
428
- end
429
-
430
- def self.test_name(name)
431
- "test_#{sanitize_name(name).gsub(/\s+/,'_')}".to_sym
432
- end
433
-
434
- def self.sanitize_name(name)
435
- name.gsub(/\W+/, ' ').strip
436
- end
437
-
438
- def self.remove_tests(subclass)
439
- subclass.public_instance_methods.grep(/^test_/).each do |meth|
440
- subclass.send(:undef_method, meth.to_sym)
441
- end
442
- end
443
- end
444
-
445
- def context(*name, &block)
446
- Minitest::Test.context(name, &block)
447
- end