bitclust-core 1.3.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (152) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -0
  3. data/README.md +65 -0
  4. data/Rakefile +32 -0
  5. data/data/bitclust/catalog/ja_JP.UTF-8 +19 -1
  6. data/data/bitclust/searchpage/index.html +90 -0
  7. data/data/bitclust/template/class +69 -8
  8. data/data/bitclust/template/function +2 -2
  9. data/data/bitclust/template/layout +11 -3
  10. data/data/bitclust/template/method +2 -2
  11. data/data/bitclust/template/search +1 -1
  12. data/data/bitclust/template.epub/class +22 -1
  13. data/data/bitclust/template.epub/function +2 -2
  14. data/data/bitclust/template.epub/layout +1 -3
  15. data/data/bitclust/template.epub/method +2 -2
  16. data/data/bitclust/template.lillia/class +26 -5
  17. data/data/bitclust/template.lillia/layout +1 -3
  18. data/data/bitclust/template.lillia/method +2 -2
  19. data/data/bitclust/template.offline/class +48 -4
  20. data/data/bitclust/template.offline/function +2 -2
  21. data/data/bitclust/template.offline/layout +27 -3
  22. data/data/bitclust/template.offline/method +2 -2
  23. data/lib/bitclust/app.rb +16 -17
  24. data/lib/bitclust/capi_converter.rb +20 -0
  25. data/lib/bitclust/classentry.rb +67 -17
  26. data/lib/bitclust/compat.rb +2 -2
  27. data/lib/bitclust/completion.rb +58 -27
  28. data/lib/bitclust/crossrubyutils.rb +8 -5
  29. data/lib/bitclust/database.rb +28 -8
  30. data/lib/bitclust/doc_converter.rb +63 -0
  31. data/lib/bitclust/docentry.rb +1 -1
  32. data/lib/bitclust/entity_splitter.rb +221 -0
  33. data/lib/bitclust/entry.rb +47 -7
  34. data/lib/bitclust/functiondatabase.rb +13 -1
  35. data/lib/bitclust/functionentry.rb +5 -1
  36. data/lib/bitclust/functionreferenceparser.rb +4 -4
  37. data/lib/bitclust/generators/epub.rb +10 -3
  38. data/lib/bitclust/htmlutils.rb +1 -1
  39. data/lib/bitclust/include_graph.rb +375 -0
  40. data/lib/bitclust/include_pruner.rb +144 -0
  41. data/lib/bitclust/interface.rb +1 -1
  42. data/lib/bitclust/libraryentry.rb +8 -7
  43. data/lib/bitclust/lineinput.rb +7 -5
  44. data/lib/bitclust/link_checker.rb +179 -0
  45. data/lib/bitclust/markdown_bridge.rb +186 -0
  46. data/lib/bitclust/markdown_orchestrator.rb +267 -0
  47. data/lib/bitclust/markdown_to_rrd.rb +824 -0
  48. data/lib/bitclust/markdown_tree.rb +217 -0
  49. data/lib/bitclust/mdcompiler.rb +883 -0
  50. data/lib/bitclust/mdparser.rb +347 -0
  51. data/lib/bitclust/messagecatalog.rb +3 -3
  52. data/lib/bitclust/method_since_calculator.rb +117 -0
  53. data/lib/bitclust/methoddatabase.rb +124 -14
  54. data/lib/bitclust/methodentry.rb +125 -7
  55. data/lib/bitclust/methodid.rb +12 -11
  56. data/lib/bitclust/methodsignature.rb +10 -4
  57. data/lib/bitclust/nameutils.rb +41 -22
  58. data/lib/bitclust/preprocessor.rb +66 -29
  59. data/lib/bitclust/rdcompiler.rb +195 -95
  60. data/lib/bitclust/refsdatabase.rb +23 -8
  61. data/lib/bitclust/reloadable_request_handler.rb +72 -0
  62. data/lib/bitclust/requesthandler.rb +21 -16
  63. data/lib/bitclust/ridatabase.rb +10 -4
  64. data/lib/bitclust/rrd_to_markdown.rb +925 -0
  65. data/lib/bitclust/rrdparser.rb +196 -30
  66. data/lib/bitclust/runner.rb +17 -2
  67. data/lib/bitclust/screen.rb +80 -11
  68. data/lib/bitclust/search_index_generator.rb +288 -0
  69. data/lib/bitclust/searcher.rb +69 -20
  70. data/lib/bitclust/simplesearcher.rb +24 -12
  71. data/lib/bitclust/subcommand.rb +7 -1
  72. data/lib/bitclust/subcommands/ancestors_command.rb +9 -2
  73. data/lib/bitclust/subcommands/checklink_command.rb +54 -0
  74. data/lib/bitclust/subcommands/chm_command.rb +15 -7
  75. data/lib/bitclust/subcommands/classes_command.rb +5 -0
  76. data/lib/bitclust/subcommands/extract_command.rb +5 -0
  77. data/lib/bitclust/subcommands/htmlfile_command.rb +21 -7
  78. data/lib/bitclust/subcommands/init_command.rb +4 -1
  79. data/lib/bitclust/subcommands/list_command.rb +12 -4
  80. data/lib/bitclust/subcommands/lookup_command.rb +28 -9
  81. data/lib/bitclust/subcommands/methods_command.rb +10 -2
  82. data/lib/bitclust/subcommands/methodsince_command.rb +80 -0
  83. data/lib/bitclust/subcommands/preproc_command.rb +5 -0
  84. data/lib/bitclust/subcommands/property_command.rb +2 -1
  85. data/lib/bitclust/subcommands/searchpage_command.rb +102 -0
  86. data/lib/bitclust/subcommands/server_command.rb +10 -8
  87. data/lib/bitclust/subcommands/setup_command.rb +24 -10
  88. data/lib/bitclust/subcommands/statichtml_command.rb +129 -6
  89. data/lib/bitclust/subcommands/update_command.rb +110 -2
  90. data/lib/bitclust/syntax_highlighter.rb +48 -4
  91. data/lib/bitclust/textutils.rb +3 -3
  92. data/lib/bitclust/version.rb +1 -1
  93. data/lib/bitclust/version_badges.rb +90 -0
  94. data/lib/bitclust/whole_file_gate.rb +137 -0
  95. data/test/test_app.rb +269 -0
  96. data/test/test_bitclust.rb +2 -0
  97. data/test/test_capi_converter.rb +91 -0
  98. data/test/test_class_screen.rb +413 -0
  99. data/test/test_copy_doc_md.rb +53 -0
  100. data/test/test_doc_converter.rb +78 -0
  101. data/test/test_entity_splitter.rb +231 -0
  102. data/test/test_entry.rb +207 -2
  103. data/test/test_eol_warning.rb +43 -0
  104. data/test/test_functionreferenceparser.rb +11 -0
  105. data/test/test_include_graph.rb +640 -0
  106. data/test/test_include_pruner.rb +133 -0
  107. data/test/test_link_checker.rb +114 -0
  108. data/test/test_lookup_command.rb +135 -0
  109. data/test/test_markdown_bridge.rb +217 -0
  110. data/test/test_markdown_orchestrator.rb +478 -0
  111. data/test/test_markdown_to_rrd.rb +757 -0
  112. data/test/test_markdown_tree.rb +369 -0
  113. data/test/test_mdcompiler.rb +1276 -0
  114. data/test/test_mdparser.rb +538 -0
  115. data/test/test_method_screen.rb +166 -0
  116. data/test/test_method_since_calculator.rb +290 -0
  117. data/test/test_methoddatabase.rb +16 -0
  118. data/test/test_methodentry.rb +328 -0
  119. data/test/test_methodsignature.rb +3 -1
  120. data/test/test_methodsince_command.rb +168 -0
  121. data/test/test_nameutils.rb +22 -0
  122. data/test/test_preprocessor.rb +215 -0
  123. data/test/test_rdcompiler.rb +401 -30
  124. data/test/test_refsdatabase.rb +32 -0
  125. data/test/test_rrd_to_markdown.rb +968 -0
  126. data/test/test_rrdparser.rb +295 -2
  127. data/test/test_run_ruby_wasm.rb +54 -0
  128. data/test/test_run_worker_prelude.rb +83 -0
  129. data/test/test_runner.rb +51 -0
  130. data/test/test_search_index_generator.rb +513 -0
  131. data/test/test_search_screen.rb +48 -0
  132. data/test/test_searcher.rb +132 -0
  133. data/test/test_searchpage_command.rb +167 -0
  134. data/test/test_simplesearcher.rb +28 -0
  135. data/test/test_statichtml_command.rb +204 -0
  136. data/test/test_syntax_highlighter.rb +60 -0
  137. data/test/test_whole_file_gate.rb +175 -0
  138. data/theme/default/js/NOTICE +42 -0
  139. data/theme/default/js/run-worker.js +111 -0
  140. data/theme/default/js/run.js +350 -0
  141. data/theme/default/js/search_controller.js +134 -0
  142. data/theme/default/js/search_init.js +176 -0
  143. data/theme/default/js/search_navigation.js +110 -0
  144. data/theme/default/js/search_page.js +202 -0
  145. data/theme/default/js/search_ranker.js +244 -0
  146. data/theme/default/script.js +91 -18
  147. data/theme/default/search.css +149 -0
  148. data/theme/default/style.css +193 -21
  149. data/theme/default/syntax-highlight.css +8 -0
  150. data/theme/lillia/style.css +45 -1
  151. metadata +161 -20
  152. data/README +0 -32
@@ -0,0 +1,168 @@
1
+ # frozen_string_literal: true
2
+ require 'test/unit'
3
+ require 'bitclust'
4
+ require 'bitclust/methoddatabase'
5
+ require 'bitclust/subcommands/methodsince_command'
6
+ require 'stringio'
7
+ require 'tmpdir'
8
+ require 'fileutils'
9
+
10
+ # methodsince サブコマンド(bitclust#132 P2)。
11
+ #
12
+ # テストリスト:
13
+ # [x] グローバル --database 不要(needs_database? が false)
14
+ # [x] --update が無いとエラー
15
+ # [x] ラダー DB を走査して --update 対象に since/until が書き込まれる
16
+ # (フロアのメソッドには付かず、ゲート付きメソッドには付く)
17
+ # [x] 統計行が "basename (version V): entries_updated=.. since_filled=..
18
+ # until_filled=.. floor_skipped=.." の形式で出力される
19
+ # [x] --update は複数指定でき、対象ごとに統計行が出力される
20
+ # [x] --update に無い位置引数の DB はラダーには参加するが書き込まれない
21
+ # [x] --dry-run は統計を表示するだけで実DBファイルには一切書き込まない
22
+ # [x] Runner に登録されている(bitclust methodsince として呼べる)
23
+ class TestMethodsinceCommand < Test::Unit::TestCase
24
+ def setup
25
+ @tmpdir = "methodsince_test_tmp"
26
+ FileUtils.rm_rf(@tmpdir)
27
+ @db10 = build_db('1.0', <<~'RD')
28
+ description
29
+
30
+ = class Foo < Object
31
+ == Instance Methods
32
+ --- old
33
+
34
+ 説明
35
+ RD
36
+ @db20 = build_db('2.0', <<~'RD')
37
+ description
38
+
39
+ = class Foo < Object
40
+ == Instance Methods
41
+ --- old
42
+
43
+ 説明
44
+
45
+ #@since 2.0
46
+ --- newone
47
+
48
+ 説明
49
+ #@end
50
+ RD
51
+ end
52
+
53
+ def teardown
54
+ FileUtils.rm_rf(@tmpdir)
55
+ end
56
+
57
+ def build_db(version, builtin_rd)
58
+ root = "#{@tmpdir}/tree-#{version}/refm/api/src"
59
+ FileUtils.mkdir_p("#{root}/_builtin")
60
+ File.write("#{root}/LIBRARIES", "_builtin\n")
61
+ File.write("#{root}/_builtin.rd", builtin_rd)
62
+ prefix = "#{@tmpdir}/db-#{version}"
63
+ db = BitClust::MethodDatabase.new(prefix)
64
+ db.init
65
+ db.transaction do
66
+ db.propset('version', version)
67
+ db.propset('encoding', 'utf-8')
68
+ end
69
+ db.transaction do
70
+ db.update_by_stdlibtree(root)
71
+ end
72
+ prefix
73
+ end
74
+
75
+ def run_command(argv)
76
+ cmd = BitClust::Subcommands::MethodsinceCommand.new
77
+ cmd.parse(argv)
78
+ out = StringIO.new
79
+ orig_stdout = $stdout
80
+ $stdout = out
81
+ begin
82
+ cmd.exec(argv, { prefix: nil, capi: false })
83
+ ensure
84
+ $stdout = orig_stdout
85
+ end
86
+ out.string
87
+ end
88
+
89
+ def find_entry(prefix, name)
90
+ db = BitClust::MethodDatabase.new(prefix)
91
+ db.get_class('Foo').entries.find {|m| m.name?(name) }
92
+ end
93
+
94
+ def test_needs_no_global_database_option
95
+ cmd = BitClust::Subcommands::MethodsinceCommand.new
96
+ assert_false cmd.needs_database?
97
+ end
98
+
99
+ def test_no_update_is_an_error
100
+ cmd = BitClust::Subcommands::MethodsinceCommand.new
101
+ argv = [@db10, @db20]
102
+ cmd.parse(argv)
103
+ assert_raise(SystemExit) do
104
+ capture_stderr { cmd.exec(argv, { prefix: nil, capi: false }) }
105
+ end
106
+ end
107
+
108
+ def test_fills_since_into_update_target
109
+ run_command([@db10, "--update=#{@db20}"])
110
+ assert_nil find_entry(@db20, 'old').since_of('old')
111
+ assert_equal '2.0', find_entry(@db20, 'newone').since_of('newone')
112
+ end
113
+
114
+ def test_prints_one_stats_line_per_target
115
+ out = run_command([@db10, "--update=#{@db20}"])
116
+ assert_match(
117
+ /\Adb-2\.0 \(version 2\.0\): entries_updated=\d+ since_filled=\d+ until_filled=\d+ floor_skipped=\d+\n\z/,
118
+ out)
119
+ end
120
+
121
+ def test_multiple_update_targets_each_get_a_stats_line
122
+ out = run_command(["--update=#{@db10}", "--update=#{@db20}"])
123
+ lines = out.lines
124
+ assert_equal 2, lines.size
125
+ assert_match(/\Adb-1\.0 /, lines[0])
126
+ assert_match(/\Adb-2\.0 /, lines[1])
127
+ end
128
+
129
+ def test_positional_ladder_db_is_not_written_to
130
+ before = File.read(property_file_path(@db10, 'old'))
131
+ run_command([@db10, "--update=#{@db20}"])
132
+ after = File.read(property_file_path(@db10, 'old'))
133
+ assert_equal before, after
134
+ end
135
+
136
+ def test_dry_run_leaves_real_database_untouched
137
+ run_command([@db10, "--update=#{@db20}", '--dry-run'])
138
+ assert_nil find_entry(@db20, 'newone').since_of('newone')
139
+ end
140
+
141
+ def test_dry_run_still_prints_computed_stats
142
+ out = run_command([@db10, "--update=#{@db20}", '--dry-run'])
143
+ assert_match(/since_filled=1\b/, out)
144
+ end
145
+
146
+ def test_registered_in_runner
147
+ require 'bitclust/runner'
148
+ runner = BitClust::Runner.new
149
+ runner.prepare
150
+ subcommands = runner.instance_variable_get(:@subcommands)
151
+ assert_kind_of(BitClust::Subcommands::MethodsinceCommand, subcommands['methodsince'])
152
+ end
153
+
154
+ private
155
+
156
+ def property_file_path(prefix, name)
157
+ id = BitClust::NameUtils.build_method_id('_builtin', 'Foo', :instance_method, name)
158
+ File.join(prefix, BitClust::NameUtils.encodeid("method/#{id}"))
159
+ end
160
+
161
+ def capture_stderr
162
+ orig = $stderr
163
+ $stderr = StringIO.new
164
+ yield
165
+ ensure
166
+ $stderr = orig
167
+ end
168
+ end
@@ -306,6 +306,28 @@ class TestNameUtils < Test::Unit::TestCase
306
306
  assert_equal(expected, typemark2char(target))
307
307
  end
308
308
 
309
+ # bitclust#250: Ruby 4.0 以降のドキュメントでは module function の表記を
310
+ # 独自の「.#」から「?.」に変える。表示だけの変換であり、識別子(typemark
311
+ # そのもの・typemark2char 等)は一切変えないので、対象は '.#' のみ。
312
+ # バージョン比較は文字列比較ではなく Gem::Version で行う(例: "10.0" を
313
+ # 文字列比較すると "4.0" より小さく見えてしまう)。
314
+ data("module function before 4.0 stays as-is" => ['.#', '.#', '3.4'],
315
+ "module function at exactly 4.0 switches" => ['?.', '.#', '4.0'],
316
+ "module function after 4.0 switches" => ['?.', '.#', '4.1'],
317
+ "module function 4.0.0 counts as 4.0" => ['?.', '.#', '4.0.0'],
318
+ "module function double-digit major (10.0)" => ['?.', '.#', '10.0'],
319
+ "module function just under 4.0 stays as-is" => ['.#', '.#', '3.99'],
320
+ "module function with nil version stays as-is" => ['.#', '.#', nil],
321
+ "module function with empty version stays" => ['.#', '.#', ''],
322
+ "singleton method mark is never rewritten" => ['.', '.', '4.0'],
323
+ "instance method mark is never rewritten" => ['#', '#', '4.0'],
324
+ "constant mark is never rewritten" => ['::', '::', '4.0'],
325
+ "special variable mark is never rewritten" => ['$', '$', '4.0'])
326
+ def test_display_typemark(data)
327
+ expected, mark, version = data
328
+ assert_equal(expected, display_typemark(mark, version))
329
+ end
330
+
309
331
  data("s" => [".", "s"],
310
332
  "i" => ["#", "i"],
311
333
  "m" => [".#", "m"],
@@ -1,6 +1,7 @@
1
1
  require 'test/unit'
2
2
  require 'bitclust/preprocessor'
3
3
  require 'stringio'
4
+ require 'tmpdir'
4
5
 
5
6
  class TestPreprocessor < Test::Unit::TestCase
6
7
  include BitClust
@@ -313,4 +314,218 @@ HERE
313
314
  assert_equal(expected, ret.join)
314
315
  end
315
316
  end
317
+
318
+ # bitclust#285: GitHub が #@since 等をユーザー mention として解釈してしまう
319
+ # 問題への対応で、@ を含まない新 prefix #% を導入する。旧 #@ も凍結タグの
320
+ # 旧ソース再取込のため引き続き受け付ける(両対応)
321
+ sub_test_case("percent prefix (#285)") do
322
+
323
+ def test_percent_eval_cond
324
+ params = { 'version' => '1.8.7' }
325
+
326
+ [
327
+ ['#%if( version > "1.8.0")', true ],
328
+ ['#%if( version < "1.8.0")', false],
329
+ ['#%since 1.8.0', true ],
330
+ ['#%since 1.8.7', true ],
331
+ ['#%until 1.8.7', false],
332
+ ['#%until 1.9.0', true ],
333
+ ].each{|cond, expected_result|
334
+ s = <<HERE
335
+ #{cond}
336
+ a
337
+ #%else
338
+ b
339
+ #%end
340
+ HERE
341
+ ret = Preprocessor.wrap(StringIO.new(s), params).to_a
342
+ if expected_result
343
+ assert_equal(["a\n"], ret)
344
+ else
345
+ assert_equal(["b\n"], ret)
346
+ end
347
+ }
348
+ end
349
+
350
+ def test_percent_comment
351
+ params = { 'version' => '1.8.7' }
352
+ src = <<HERE
353
+ a
354
+ #%# preprocessor comment
355
+ b
356
+ HERE
357
+ ret = Preprocessor.wrap(StringIO.new(src), params).to_a
358
+ assert_equal(["a\n", "b\n"], ret)
359
+ end
360
+
361
+ def test_percent_todo_normalized
362
+ params = { 'version' => '1.8.7' }
363
+ src = <<HERE
364
+ --- puts(str) -> String
365
+ #%todo
366
+ description
367
+ HERE
368
+ expected = <<HERE
369
+ --- puts(str) -> String
370
+ @todo
371
+ description
372
+ HERE
373
+ ret = Preprocessor.wrap(StringIO.new(src), params).to_a
374
+ assert_equal(expected, ret.join)
375
+ end
376
+
377
+ def test_percent_samplecode
378
+ params = { 'version' => '1.9.2' }
379
+ src = <<HERE
380
+ #%samplecode description
381
+ puts("xxx")
382
+ #%since 1.9.2
383
+ puts("zzz")
384
+ #%end
385
+ #%end
386
+ HERE
387
+ expected = <<HERE
388
+ //emlist[description][ruby]{
389
+ puts("xxx")
390
+ puts("zzz")
391
+ //}
392
+ HERE
393
+ ret = Preprocessor.wrap(StringIO.new(src), params).to_a
394
+ assert_equal(expected, ret.join)
395
+ end
396
+
397
+ def test_mixed_prefixes
398
+ # 移行期は同一ファイル内で新旧 prefix が混在しうる
399
+ params = { 'version' => '2.0.0' }
400
+ src = <<HERE
401
+ #%since 1.9.3
402
+ a
403
+ \#@since 2.4.0
404
+ b
405
+ #%end
406
+ \#@end
407
+ c
408
+ HERE
409
+ expected = <<HERE
410
+ a
411
+ c
412
+ HERE
413
+ ret = Preprocessor.wrap(StringIO.new(src), params).to_a
414
+ assert_equal(expected, ret.join)
415
+ end
416
+
417
+ def test_percent_unknown_directive
418
+ params = { 'version' => '1.8.7' }
419
+ src = <<HERE
420
+ #%nosuch
421
+ HERE
422
+ assert_raise(BitClust::ParseError) do
423
+ Preprocessor.wrap(StringIO.new(src), params).to_a
424
+ end
425
+ end
426
+
427
+ def test_percent_include
428
+ Dir.mktmpdir do |dir|
429
+ File.write("#{dir}/inc.rd", "included\n")
430
+ File.write("#{dir}/main.rd", <<~HERE)
431
+ before
432
+ #%include(inc.rd)
433
+ after
434
+ HERE
435
+ ret = Preprocessor.process("#{dir}/main.rd", { 'version' => '1.8.7' })
436
+ assert_equal("before\nincluded\nafter\n", ret.join)
437
+ end
438
+ end
439
+
440
+ def test_at_include_still_works
441
+ Dir.mktmpdir do |dir|
442
+ File.write("#{dir}/inc.rd", "included\n")
443
+ File.write("#{dir}/main.rd", <<~HERE)
444
+ before
445
+ \#@include(inc.rd)
446
+ after
447
+ HERE
448
+ ret = Preprocessor.process("#{dir}/main.rd", { 'version' => '1.8.7' })
449
+ assert_equal("before\nincluded\nafter\n", ret.join)
450
+ end
451
+ end
452
+ end
453
+
454
+ # bitclust#285: 版範囲の省略記法 #%version A...B(半開区間 [A, B))。
455
+ # Ruby の終端排他 Range リテラルに合わせて3点ドット。
456
+ # A... は A 以上(#%since 相当)、...B は B 未満(#%until 相当)
457
+ sub_test_case("version range (#285)") do
458
+
459
+ def process(src, version)
460
+ Preprocessor.wrap(StringIO.new(src), { 'version' => version }).to_a.join
461
+ end
462
+
463
+ def gated(cond)
464
+ <<HERE
465
+ #{cond}
466
+ in
467
+ #%else
468
+ out
469
+ #%end
470
+ HERE
471
+ end
472
+
473
+ def test_bounded_range
474
+ src = gated('#%version 3.1...3.4')
475
+ assert_equal "out\n", process(src, '3.0')
476
+ assert_equal "in\n", process(src, '3.1') # 始端は含む
477
+ assert_equal "in\n", process(src, '3.2')
478
+ assert_equal "out\n", process(src, '3.4') # 終端は含まない
479
+ assert_equal "out\n", process(src, '4.0')
480
+ end
481
+
482
+ def test_endless_range
483
+ src = gated('#%version 3.1...')
484
+ assert_equal "out\n", process(src, '3.0')
485
+ assert_equal "in\n", process(src, '3.1')
486
+ assert_equal "in\n", process(src, '4.1')
487
+ end
488
+
489
+ def test_beginless_range
490
+ src = gated('#%version ...3.1')
491
+ assert_equal "in\n", process(src, '3.0')
492
+ assert_equal "out\n", process(src, '3.1')
493
+ end
494
+
495
+ def test_quoted_versions
496
+ src = gated('#%version "3.1"..."3.4"')
497
+ assert_equal "in\n", process(src, '3.1')
498
+ assert_equal "out\n", process(src, '3.4')
499
+ end
500
+
501
+ def test_old_prefix
502
+ src = gated("\#@version 3.1...3.4")
503
+ assert_equal "in\n", process(src, '3.2')
504
+ end
505
+
506
+ def test_nesting_with_since
507
+ src = <<HERE
508
+ #%version 3.1...4.0
509
+ #%since 3.3
510
+ both
511
+ #%end
512
+ #%end
513
+ HERE
514
+ assert_equal "both\n", process(src, '3.3')
515
+ assert_equal "", process(src, '3.2')
516
+ assert_equal "", process(src, '4.0')
517
+ end
518
+
519
+ def test_two_dot_range_is_error
520
+ # .. (終端を含む Range)は誤解を招くため受け付けない(#285)
521
+ assert_raise(BitClust::ParseError) { process(gated('#%version 3.1..3.4'), '3.2') }
522
+ end
523
+
524
+ def test_malformed_ranges_are_error
525
+ assert_raise(BitClust::ParseError) { process(gated('#%version'), '3.2') }
526
+ assert_raise(BitClust::ParseError) { process(gated('#%version ...'), '3.2') }
527
+ assert_raise(BitClust::ParseError) { process(gated('#%version 3.1....3.4'), '3.2') }
528
+ assert_raise(BitClust::ParseError) { process(gated('#%version 3.1...3.4...4.0'), '3.2') }
529
+ end
530
+ end
316
531
  end