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.
- checksums.yaml +4 -4
- data/Gemfile +3 -0
- data/README.md +65 -0
- data/Rakefile +32 -0
- data/data/bitclust/catalog/ja_JP.UTF-8 +19 -1
- data/data/bitclust/searchpage/index.html +90 -0
- data/data/bitclust/template/class +69 -8
- data/data/bitclust/template/function +2 -2
- data/data/bitclust/template/layout +11 -3
- data/data/bitclust/template/method +2 -2
- data/data/bitclust/template/search +1 -1
- data/data/bitclust/template.epub/class +22 -1
- data/data/bitclust/template.epub/function +2 -2
- data/data/bitclust/template.epub/layout +1 -3
- data/data/bitclust/template.epub/method +2 -2
- data/data/bitclust/template.lillia/class +26 -5
- data/data/bitclust/template.lillia/layout +1 -3
- data/data/bitclust/template.lillia/method +2 -2
- data/data/bitclust/template.offline/class +48 -4
- data/data/bitclust/template.offline/function +2 -2
- data/data/bitclust/template.offline/layout +27 -3
- data/data/bitclust/template.offline/method +2 -2
- data/lib/bitclust/app.rb +16 -17
- data/lib/bitclust/capi_converter.rb +20 -0
- data/lib/bitclust/classentry.rb +67 -17
- data/lib/bitclust/compat.rb +2 -2
- data/lib/bitclust/completion.rb +58 -27
- data/lib/bitclust/crossrubyutils.rb +8 -5
- data/lib/bitclust/database.rb +28 -8
- data/lib/bitclust/doc_converter.rb +63 -0
- data/lib/bitclust/docentry.rb +1 -1
- data/lib/bitclust/entity_splitter.rb +221 -0
- data/lib/bitclust/entry.rb +47 -7
- data/lib/bitclust/functiondatabase.rb +13 -1
- data/lib/bitclust/functionentry.rb +5 -1
- data/lib/bitclust/functionreferenceparser.rb +4 -4
- data/lib/bitclust/generators/epub.rb +10 -3
- data/lib/bitclust/htmlutils.rb +1 -1
- data/lib/bitclust/include_graph.rb +375 -0
- data/lib/bitclust/include_pruner.rb +144 -0
- data/lib/bitclust/interface.rb +1 -1
- data/lib/bitclust/libraryentry.rb +8 -7
- data/lib/bitclust/lineinput.rb +7 -5
- data/lib/bitclust/link_checker.rb +179 -0
- data/lib/bitclust/markdown_bridge.rb +186 -0
- data/lib/bitclust/markdown_orchestrator.rb +267 -0
- data/lib/bitclust/markdown_to_rrd.rb +824 -0
- data/lib/bitclust/markdown_tree.rb +217 -0
- data/lib/bitclust/mdcompiler.rb +883 -0
- data/lib/bitclust/mdparser.rb +347 -0
- data/lib/bitclust/messagecatalog.rb +3 -3
- data/lib/bitclust/method_since_calculator.rb +117 -0
- data/lib/bitclust/methoddatabase.rb +124 -14
- data/lib/bitclust/methodentry.rb +125 -7
- data/lib/bitclust/methodid.rb +12 -11
- data/lib/bitclust/methodsignature.rb +10 -4
- data/lib/bitclust/nameutils.rb +41 -22
- data/lib/bitclust/preprocessor.rb +66 -29
- data/lib/bitclust/rdcompiler.rb +195 -95
- data/lib/bitclust/refsdatabase.rb +23 -8
- data/lib/bitclust/reloadable_request_handler.rb +72 -0
- data/lib/bitclust/requesthandler.rb +21 -16
- data/lib/bitclust/ridatabase.rb +10 -4
- data/lib/bitclust/rrd_to_markdown.rb +925 -0
- data/lib/bitclust/rrdparser.rb +196 -30
- data/lib/bitclust/runner.rb +17 -2
- data/lib/bitclust/screen.rb +80 -11
- data/lib/bitclust/search_index_generator.rb +288 -0
- data/lib/bitclust/searcher.rb +69 -20
- data/lib/bitclust/simplesearcher.rb +24 -12
- data/lib/bitclust/subcommand.rb +7 -1
- data/lib/bitclust/subcommands/ancestors_command.rb +9 -2
- data/lib/bitclust/subcommands/checklink_command.rb +54 -0
- data/lib/bitclust/subcommands/chm_command.rb +15 -7
- data/lib/bitclust/subcommands/classes_command.rb +5 -0
- data/lib/bitclust/subcommands/extract_command.rb +5 -0
- data/lib/bitclust/subcommands/htmlfile_command.rb +21 -7
- data/lib/bitclust/subcommands/init_command.rb +4 -1
- data/lib/bitclust/subcommands/list_command.rb +12 -4
- data/lib/bitclust/subcommands/lookup_command.rb +28 -9
- data/lib/bitclust/subcommands/methods_command.rb +10 -2
- data/lib/bitclust/subcommands/methodsince_command.rb +80 -0
- data/lib/bitclust/subcommands/preproc_command.rb +5 -0
- data/lib/bitclust/subcommands/property_command.rb +2 -1
- data/lib/bitclust/subcommands/searchpage_command.rb +102 -0
- data/lib/bitclust/subcommands/server_command.rb +10 -8
- data/lib/bitclust/subcommands/setup_command.rb +24 -10
- data/lib/bitclust/subcommands/statichtml_command.rb +129 -6
- data/lib/bitclust/subcommands/update_command.rb +110 -2
- data/lib/bitclust/syntax_highlighter.rb +48 -4
- data/lib/bitclust/textutils.rb +3 -3
- data/lib/bitclust/version.rb +1 -1
- data/lib/bitclust/version_badges.rb +90 -0
- data/lib/bitclust/whole_file_gate.rb +137 -0
- data/test/test_app.rb +269 -0
- data/test/test_bitclust.rb +2 -0
- data/test/test_capi_converter.rb +91 -0
- data/test/test_class_screen.rb +413 -0
- data/test/test_copy_doc_md.rb +53 -0
- data/test/test_doc_converter.rb +78 -0
- data/test/test_entity_splitter.rb +231 -0
- data/test/test_entry.rb +207 -2
- data/test/test_eol_warning.rb +43 -0
- data/test/test_functionreferenceparser.rb +11 -0
- data/test/test_include_graph.rb +640 -0
- data/test/test_include_pruner.rb +133 -0
- data/test/test_link_checker.rb +114 -0
- data/test/test_lookup_command.rb +135 -0
- data/test/test_markdown_bridge.rb +217 -0
- data/test/test_markdown_orchestrator.rb +478 -0
- data/test/test_markdown_to_rrd.rb +757 -0
- data/test/test_markdown_tree.rb +369 -0
- data/test/test_mdcompiler.rb +1276 -0
- data/test/test_mdparser.rb +538 -0
- data/test/test_method_screen.rb +166 -0
- data/test/test_method_since_calculator.rb +290 -0
- data/test/test_methoddatabase.rb +16 -0
- data/test/test_methodentry.rb +328 -0
- data/test/test_methodsignature.rb +3 -1
- data/test/test_methodsince_command.rb +168 -0
- data/test/test_nameutils.rb +22 -0
- data/test/test_preprocessor.rb +215 -0
- data/test/test_rdcompiler.rb +401 -30
- data/test/test_refsdatabase.rb +32 -0
- data/test/test_rrd_to_markdown.rb +968 -0
- data/test/test_rrdparser.rb +295 -2
- data/test/test_run_ruby_wasm.rb +54 -0
- data/test/test_run_worker_prelude.rb +83 -0
- data/test/test_runner.rb +51 -0
- data/test/test_search_index_generator.rb +513 -0
- data/test/test_search_screen.rb +48 -0
- data/test/test_searcher.rb +132 -0
- data/test/test_searchpage_command.rb +167 -0
- data/test/test_simplesearcher.rb +28 -0
- data/test/test_statichtml_command.rb +204 -0
- data/test/test_syntax_highlighter.rb +60 -0
- data/test/test_whole_file_gate.rb +175 -0
- data/theme/default/js/NOTICE +42 -0
- data/theme/default/js/run-worker.js +111 -0
- data/theme/default/js/run.js +350 -0
- data/theme/default/js/search_controller.js +134 -0
- data/theme/default/js/search_init.js +176 -0
- data/theme/default/js/search_navigation.js +110 -0
- data/theme/default/js/search_page.js +202 -0
- data/theme/default/js/search_ranker.js +244 -0
- data/theme/default/script.js +91 -18
- data/theme/default/search.css +149 -0
- data/theme/default/style.css +193 -21
- data/theme/default/syntax-highlight.css +8 -0
- data/theme/lillia/style.css +45 -1
- metadata +161 -20
- data/README +0 -32
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
require 'test/unit'
|
|
2
|
+
require 'bitclust'
|
|
3
|
+
require 'bitclust/screen'
|
|
4
|
+
require 'tmpdir'
|
|
5
|
+
require 'fileutils'
|
|
6
|
+
|
|
7
|
+
class TestClassScreen < Test::Unit::TestCase
|
|
8
|
+
SRC = <<'HERE'
|
|
9
|
+
= class Base < Object
|
|
10
|
+
base class
|
|
11
|
+
== Class Methods
|
|
12
|
+
--- base_class_method
|
|
13
|
+
base class method
|
|
14
|
+
--- shared_name
|
|
15
|
+
shared name
|
|
16
|
+
--- hidden_class_method
|
|
17
|
+
hidden class method
|
|
18
|
+
== Instance Methods
|
|
19
|
+
--- base_instance_method
|
|
20
|
+
base instance method
|
|
21
|
+
= module Mixin
|
|
22
|
+
mixin module
|
|
23
|
+
== Class Methods
|
|
24
|
+
--- mixin_class_method
|
|
25
|
+
mixin class method
|
|
26
|
+
== Instance Methods
|
|
27
|
+
--- mixin_instance_method
|
|
28
|
+
mixin instance method
|
|
29
|
+
= class Sub < Base
|
|
30
|
+
include Mixin
|
|
31
|
+
sub class
|
|
32
|
+
== Class Methods
|
|
33
|
+
--- sub_class_method
|
|
34
|
+
sub class method
|
|
35
|
+
--- hidden_class_method
|
|
36
|
+
{: undef}
|
|
37
|
+
== Instance Methods
|
|
38
|
+
--- shared_name
|
|
39
|
+
{: undef}
|
|
40
|
+
|
|
41
|
+
--- explanatory_method
|
|
42
|
+
{: nomethod}
|
|
43
|
+
説明のために記載しているメソッドです。
|
|
44
|
+
|
|
45
|
+
= redefine Sub
|
|
46
|
+
== Instance Methods
|
|
47
|
+
--- redefined_instance_method
|
|
48
|
+
redefined instance method
|
|
49
|
+
HERE
|
|
50
|
+
|
|
51
|
+
def setup
|
|
52
|
+
@lib, = BitClust::RRDParser.parse(SRC, 'testlib')
|
|
53
|
+
datadir = File.expand_path('../data/bitclust', __dir__)
|
|
54
|
+
manager = BitClust::ScreenManager.new(
|
|
55
|
+
:templatedir => "#{datadir}/template.offline",
|
|
56
|
+
:catalogdir => "#{datadir}/catalog",
|
|
57
|
+
:encoding => 'utf-8',
|
|
58
|
+
:default_encoding => 'utf-8',
|
|
59
|
+
:base_url => '',
|
|
60
|
+
:target_version => '3.4'
|
|
61
|
+
)
|
|
62
|
+
db = BitClust::MethodDatabase.dummy('version' => '3.4')
|
|
63
|
+
@html = manager.class_screen(@lib.fetch_class('Sub'), :database => db).body
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def test_ancestor_singleton_methods_are_displayed
|
|
67
|
+
assert_include(@html, 'Baseから継承している特異メソッド')
|
|
68
|
+
assert_include(@html, 'base_class_method')
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def test_module_singleton_methods_are_not_inherited
|
|
72
|
+
# A class does not inherit singleton methods from included modules.
|
|
73
|
+
assert_not_include(@html, 'Mixinから継承している特異メソッド')
|
|
74
|
+
assert_not_include(@html, 'mixin_class_method')
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def test_undefined_singleton_method_is_hidden
|
|
78
|
+
assert_not_include(@html, 'hidden_class_method')
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def test_nomethod_method_is_listed_in_its_own_section
|
|
82
|
+
assert_include(@html, '説明のための未定義メソッド')
|
|
83
|
+
assert_include(@html, 'explanatory_method')
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def test_nomethod_metadata_is_not_rendered_as_unknown
|
|
87
|
+
assert_not_include(@html, 'UNKNOWN_META_INFO')
|
|
88
|
+
assert_not_include(@html, '{:')
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def test_undefined_instance_method_does_not_hide_singleton_method
|
|
92
|
+
# Sub undefs the *instance* method shared_name; the inherited singleton
|
|
93
|
+
# method of the same name must still be listed.
|
|
94
|
+
assert_include(@html, 'shared_name')
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def test_ancestor_instance_methods_include_modules
|
|
98
|
+
assert_include(@html, 'Baseから継承しているメソッド')
|
|
99
|
+
assert_include(@html, 'base_instance_method')
|
|
100
|
+
assert_include(@html, 'Mixinから継承しているメソッド')
|
|
101
|
+
assert_include(@html, 'mixin_instance_method')
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def test_redefined_method_is_listed_in_its_own_section
|
|
105
|
+
assert_include(@html, '再定義されたメソッド')
|
|
106
|
+
assert_include(@html, 'redefined_instance_method')
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def test_class_without_dynamic_include_does_not_show_dynamic_include_section
|
|
110
|
+
# Regression guard: classes that never use dynamic include must render
|
|
111
|
+
# exactly as before (no new headline, no leftover markers).
|
|
112
|
+
assert_not_include(@html, '動的includeで追加されるメソッド')
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
class TestClassScreenDynamicInclude < Test::Unit::TestCase
|
|
117
|
+
SRC = <<'HERE'
|
|
118
|
+
= module JsonMixin
|
|
119
|
+
json mixin module
|
|
120
|
+
== Instance Methods
|
|
121
|
+
--- to_json
|
|
122
|
+
to json
|
|
123
|
+
== Private Instance Methods
|
|
124
|
+
--- hidden_json_helper
|
|
125
|
+
hidden json helper
|
|
126
|
+
= class Host < Object
|
|
127
|
+
host class
|
|
128
|
+
== Instance Methods
|
|
129
|
+
--- host_method
|
|
130
|
+
host method
|
|
131
|
+
= reopen Host
|
|
132
|
+
include JsonMixin
|
|
133
|
+
HERE
|
|
134
|
+
|
|
135
|
+
def setup
|
|
136
|
+
@lib, = BitClust::RRDParser.parse(SRC, 'jsonlib')
|
|
137
|
+
datadir = File.expand_path('../data/bitclust', __dir__)
|
|
138
|
+
manager = BitClust::ScreenManager.new(
|
|
139
|
+
:templatedir => "#{datadir}/template.offline",
|
|
140
|
+
:catalogdir => "#{datadir}/catalog",
|
|
141
|
+
:encoding => 'utf-8',
|
|
142
|
+
:default_encoding => 'utf-8',
|
|
143
|
+
:base_url => '',
|
|
144
|
+
:target_version => '3.4'
|
|
145
|
+
)
|
|
146
|
+
db = BitClust::MethodDatabase.dummy('version' => '3.4')
|
|
147
|
+
@html = manager.class_screen(@lib.fetch_class('Host'), :database => db).body
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def test_dynamically_included_method_is_listed_with_attribution
|
|
151
|
+
assert_include(@html, '動的includeで追加されるメソッド')
|
|
152
|
+
assert_include(@html, 'to_json')
|
|
153
|
+
assert_include(@html, 'JsonMixin')
|
|
154
|
+
assert_include(@html, '(by jsonlib)')
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def test_ancestors_are_not_affected_by_dynamic_include
|
|
158
|
+
assert_not_include(@lib.fetch_class('Host').ancestors.map(&:name), 'JsonMixin')
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def test_private_instance_method_of_dynamically_included_module_is_hidden
|
|
162
|
+
assert_not_include(@html, 'hidden_json_helper')
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
class TestClassScreenAddedMethods < Test::Unit::TestCase
|
|
167
|
+
SRC = <<'HERE'
|
|
168
|
+
= class Target < Object
|
|
169
|
+
target class
|
|
170
|
+
== Instance Methods
|
|
171
|
+
--- own_method
|
|
172
|
+
own method
|
|
173
|
+
= reopen Target
|
|
174
|
+
== Instance Methods
|
|
175
|
+
--- added_by_reopen
|
|
176
|
+
added by reopen
|
|
177
|
+
HERE
|
|
178
|
+
|
|
179
|
+
def setup
|
|
180
|
+
@lib, = BitClust::RRDParser.parse(SRC, 'extlib')
|
|
181
|
+
datadir = File.expand_path('../data/bitclust', __dir__)
|
|
182
|
+
@manager = BitClust::ScreenManager.new(
|
|
183
|
+
:templatedir => "#{datadir}/template.offline",
|
|
184
|
+
:catalogdir => "#{datadir}/catalog",
|
|
185
|
+
:encoding => 'utf-8',
|
|
186
|
+
:default_encoding => 'utf-8',
|
|
187
|
+
:base_url => '',
|
|
188
|
+
:target_version => '3.4'
|
|
189
|
+
)
|
|
190
|
+
db = BitClust::MethodDatabase.dummy('version' => '3.4')
|
|
191
|
+
@html = @manager.class_screen(@lib.fetch_class('Target'), :database => db).body
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# reopen 本文に直接定義されたメソッド(kind = :added)が
|
|
195
|
+
# statichtml 用テンプレートの目次に出ること
|
|
196
|
+
def test_added_methods_are_listed_in_offline_index
|
|
197
|
+
assert_include(@html, '追加されるメソッド')
|
|
198
|
+
assert_include(@html, 'added_by_reopen')
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def test_class_without_added_methods_has_no_added_heading
|
|
202
|
+
plain, = BitClust::RRDParser.parse(<<'PLAIN', 'extlib')
|
|
203
|
+
= class Plain < Object
|
|
204
|
+
plain class
|
|
205
|
+
== Instance Methods
|
|
206
|
+
--- plain_method
|
|
207
|
+
plain method
|
|
208
|
+
PLAIN
|
|
209
|
+
db = BitClust::MethodDatabase.dummy('version' => '3.4')
|
|
210
|
+
html = @manager.class_screen(plain.fetch_class('Plain'), :database => db).body
|
|
211
|
+
assert_not_include(html, '追加されるメソッド')
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
# bitclust#132 P3: since/until バージョンバッジが class ページ(template.offline、
|
|
216
|
+
# 各メソッドをインライン(compile_method 経由)で描画する側)にも出ることの確認
|
|
217
|
+
class TestClassScreenVersionBadges < Test::Unit::TestCase
|
|
218
|
+
SRC = <<'HERE'
|
|
219
|
+
= class Target < Object
|
|
220
|
+
target class
|
|
221
|
+
== Instance Methods
|
|
222
|
+
--- own_method
|
|
223
|
+
own method
|
|
224
|
+
HERE
|
|
225
|
+
|
|
226
|
+
def setup
|
|
227
|
+
@lib, = BitClust::RRDParser.parse(SRC, 'extlib')
|
|
228
|
+
datadir = File.expand_path('../data/bitclust', __dir__)
|
|
229
|
+
@manager = BitClust::ScreenManager.new(
|
|
230
|
+
:templatedir => "#{datadir}/template.offline",
|
|
231
|
+
:catalogdir => "#{datadir}/catalog",
|
|
232
|
+
:encoding => 'utf-8',
|
|
233
|
+
:default_encoding => 'utf-8',
|
|
234
|
+
:base_url => '',
|
|
235
|
+
:target_version => '3.4'
|
|
236
|
+
)
|
|
237
|
+
@db = BitClust::MethodDatabase.dummy('version' => '3.4')
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def test_since_badge_is_rendered_in_inlined_entry
|
|
241
|
+
entry = @lib.fetch_class('Target').fetch_method(BitClust::MethodSpec.parse('Target#own_method'))
|
|
242
|
+
entry.fill_since('own_method', '3.2')
|
|
243
|
+
html = @manager.class_screen(@lib.fetch_class('Target'), :database => @db).body
|
|
244
|
+
assert_include(html, '<span class="method-since-badge">Ruby 3.2 から</span>')
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
# bitclust#132 P3: default(サーバー動的配信用)テンプレートは compiler を経由せず
|
|
249
|
+
# 独自に署名行を描画するので、別名(alias)ごとの署名行にそれぞれ対応する
|
|
250
|
+
# バッジが付く(一様化はしない)ことを個別に確認する。
|
|
251
|
+
#
|
|
252
|
+
# この template/class は @entry.inherited_method_specs を呼び、これは
|
|
253
|
+
# ClassEntry#_index 経由でディスク上の永続化された索引ファイルを読む。
|
|
254
|
+
# 他のテストのような RRDParser.parse + MethodDatabase.dummy のインメモリ
|
|
255
|
+
# 組では索引が存在せず ENOENT になるので、ここだけは init/update で実際に
|
|
256
|
+
# ディスクへコミットした本物の MethodDatabase を使う
|
|
257
|
+
class TestClassScreenDefaultTemplateVersionBadges < Test::Unit::TestCase
|
|
258
|
+
SRC = <<'HERE'
|
|
259
|
+
= class Target < Object
|
|
260
|
+
target class
|
|
261
|
+
== Instance Methods
|
|
262
|
+
--- alias_one
|
|
263
|
+
--- alias_two
|
|
264
|
+
shared body
|
|
265
|
+
HERE
|
|
266
|
+
|
|
267
|
+
def setup
|
|
268
|
+
@datadir = File.expand_path('../data/bitclust', __dir__)
|
|
269
|
+
@dbdir = Dir.mktmpdir('bitclust-version-badges-db')
|
|
270
|
+
srcdir = Dir.mktmpdir('bitclust-version-badges-src')
|
|
271
|
+
src_path = File.join(srcdir, 'testlib.rd')
|
|
272
|
+
File.write(src_path, SRC)
|
|
273
|
+
|
|
274
|
+
@db = BitClust::MethodDatabase.new(@dbdir)
|
|
275
|
+
@db.init
|
|
276
|
+
@db.transaction do
|
|
277
|
+
@db.propset('version', '3.4')
|
|
278
|
+
@db.propset('encoding', 'utf-8')
|
|
279
|
+
end
|
|
280
|
+
@db.transaction do
|
|
281
|
+
@db.update_by_file(src_path, 'testlib')
|
|
282
|
+
end
|
|
283
|
+
FileUtils.rm_r(srcdir, :force => true)
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
def teardown
|
|
287
|
+
FileUtils.rm_r(@dbdir, :force => true)
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
def test_per_signature_badges_attach_to_their_own_alias_line
|
|
291
|
+
entry = @db.get_method(BitClust::MethodSpec.parse('Target#alias_one'))
|
|
292
|
+
entry.fill_since('alias_one', '3.0')
|
|
293
|
+
entry.fill_until('alias_two', '4.0')
|
|
294
|
+
|
|
295
|
+
manager = BitClust::ScreenManager.new(
|
|
296
|
+
:templatedir => "#{@datadir}/template",
|
|
297
|
+
:catalogdir => "#{@datadir}/catalog",
|
|
298
|
+
:encoding => 'utf-8',
|
|
299
|
+
:default_encoding => 'utf-8',
|
|
300
|
+
:base_url => '',
|
|
301
|
+
:target_version => '3.4'
|
|
302
|
+
)
|
|
303
|
+
# Screen#run_template は互換 ERB を self.class にキャッシュするので、同一
|
|
304
|
+
# プロセス内の他のテスト(template.offline を使う ClassScreen)と
|
|
305
|
+
# templatedir が混線しないよう、この検証専用のサブクラスを介して描画する
|
|
306
|
+
# (テストファイル上部のコメント、および test_method_screen.rb の同種の
|
|
307
|
+
# 注記を参照。ClassScreen 本体には触れない)
|
|
308
|
+
screen_class = Class.new(BitClust::ClassScreen)
|
|
309
|
+
html = manager.send(:new_screen, screen_class, @db.get_class('Target'), :database => @db).body
|
|
310
|
+
|
|
311
|
+
since_badge = '<span class="method-since-badge">Ruby 3.0 から</span>'
|
|
312
|
+
until_badge = '<span class="method-until-badge">Ruby 4.0 で削除</span>'
|
|
313
|
+
assert_include(html, since_badge)
|
|
314
|
+
assert_include(html, until_badge)
|
|
315
|
+
|
|
316
|
+
alias_one_pos = html.index('<code>alias_one</code>')
|
|
317
|
+
alias_two_pos = html.index('<code>alias_two</code>')
|
|
318
|
+
since_pos = html.index(since_badge)
|
|
319
|
+
until_pos = html.index(until_badge)
|
|
320
|
+
assert(alias_one_pos && alias_two_pos && since_pos && until_pos,
|
|
321
|
+
'expected both signature lines and both badges to be present')
|
|
322
|
+
# since は alias_one の行に付き、alias_two の行より前に来る
|
|
323
|
+
assert(alias_one_pos < since_pos && since_pos < alias_two_pos,
|
|
324
|
+
'the since badge must attach right after alias_one, not alias_two')
|
|
325
|
+
# until は alias_two の行に付き、alias_two より後に来る
|
|
326
|
+
assert(alias_two_pos < until_pos,
|
|
327
|
+
'the until badge must attach after alias_two')
|
|
328
|
+
end
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
# bitclust#250: Ruby 4.0 以降のドキュメントでは module function の表記を
|
|
332
|
+
# 独自の「.#」から「?.」に変える(表示のみ、識別子は変えない)。
|
|
333
|
+
#
|
|
334
|
+
# data/bitclust/template/class の「継承しているメソッド」一覧は
|
|
335
|
+
# @entry.inherited_method_specs(MethodSpec、@db を持たない値オブジェクト)を
|
|
336
|
+
# 直接文字列化する数少ない箇所なので、上の TestClassScreenDefaultTemplateVersionBadges
|
|
337
|
+
# と同じ理由で実ディスク DB を使う
|
|
338
|
+
class TestClassScreenModuleFunctionDisplay < Test::Unit::TestCase
|
|
339
|
+
SRC = <<'HERE'
|
|
340
|
+
= module Mixin
|
|
341
|
+
mixin module
|
|
342
|
+
== Module Functions
|
|
343
|
+
--- mf
|
|
344
|
+
mixin module function
|
|
345
|
+
= class Host < Object
|
|
346
|
+
include Mixin
|
|
347
|
+
host class
|
|
348
|
+
== Instance Methods
|
|
349
|
+
--- own_method
|
|
350
|
+
own method
|
|
351
|
+
HERE
|
|
352
|
+
|
|
353
|
+
def render(version)
|
|
354
|
+
datadir = File.expand_path('../data/bitclust', __dir__)
|
|
355
|
+
dbdir = Dir.mktmpdir('bitclust-module-function-display-db')
|
|
356
|
+
srcdir = Dir.mktmpdir('bitclust-module-function-display-src')
|
|
357
|
+
begin
|
|
358
|
+
src_path = File.join(srcdir, 'testlib.rd')
|
|
359
|
+
File.write(src_path, SRC)
|
|
360
|
+
|
|
361
|
+
db = BitClust::MethodDatabase.new(dbdir)
|
|
362
|
+
db.init
|
|
363
|
+
db.transaction do
|
|
364
|
+
db.propset('version', version)
|
|
365
|
+
db.propset('encoding', 'utf-8')
|
|
366
|
+
end
|
|
367
|
+
db.transaction do
|
|
368
|
+
db.update_by_file(src_path, 'testlib')
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
manager = BitClust::ScreenManager.new(
|
|
372
|
+
:templatedir => "#{datadir}/template",
|
|
373
|
+
:catalogdir => "#{datadir}/catalog",
|
|
374
|
+
:encoding => 'utf-8',
|
|
375
|
+
:default_encoding => 'utf-8',
|
|
376
|
+
:base_url => '',
|
|
377
|
+
:target_version => version
|
|
378
|
+
)
|
|
379
|
+
# See TestClassScreenDefaultTemplateVersionBadges above for the general
|
|
380
|
+
# background: Screen#run_template caches the compiled ERB body on the
|
|
381
|
+
# *class*, keyed only by method name. A plain anonymous subclass is not
|
|
382
|
+
# sufficient isolation here, though: if BitClust::ClassScreen itself
|
|
383
|
+
# was already compiled for a different templatedir (offline) by some
|
|
384
|
+
# other test earlier in this same process -- order-dependent, since
|
|
385
|
+
# TestClassScreen above uses BitClust::ClassScreen directly, with no
|
|
386
|
+
# subclass -- then `respond_to?(:class_template)` is already true via
|
|
387
|
+
# *inheritance*, and the subclass would silently reuse that stale
|
|
388
|
+
# compiled method instead of compiling its own. So compile directly
|
|
389
|
+
# onto screen_class ourselves, before Screen#run_template ever gets a
|
|
390
|
+
# chance to check: our own method then always wins by normal Ruby
|
|
391
|
+
# method resolution, regardless of what BitClust::ClassScreen has.
|
|
392
|
+
screen_class = Class.new(BitClust::ClassScreen)
|
|
393
|
+
repo = BitClust::TemplateRepository.new("#{datadir}/template")
|
|
394
|
+
ERB.new(repo.load('class')).def_method(screen_class, 'class_template', 'class.erb')
|
|
395
|
+
manager.send(:new_screen, screen_class, db.get_class('Host'), :database => db).body
|
|
396
|
+
ensure
|
|
397
|
+
FileUtils.rm_r(srcdir, :force => true)
|
|
398
|
+
FileUtils.rm_r(dbdir, :force => true)
|
|
399
|
+
end
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
def test_inherited_module_function_shows_dot_hash_before_4_0
|
|
403
|
+
html = render('3.4')
|
|
404
|
+
assert_include(html, '.#mf')
|
|
405
|
+
assert_not_include(html, '?.mf')
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
def test_inherited_module_function_switches_to_question_dot_at_4_0
|
|
409
|
+
html = render('4.0')
|
|
410
|
+
assert_include(html, '?.mf')
|
|
411
|
+
assert_not_include(html, '.#mf')
|
|
412
|
+
end
|
|
413
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'test/unit'
|
|
4
|
+
require 'tmpdir'
|
|
5
|
+
require 'fileutils'
|
|
6
|
+
require 'bitclust'
|
|
7
|
+
require 'bitclust/methoddatabase'
|
|
8
|
+
|
|
9
|
+
# copy_doc_md: manual/doc 配下の md をファイル存在で doc ページとして登録する。
|
|
10
|
+
# front matter の since/until でページ自体をバージョンで出し分けられることを
|
|
11
|
+
# 確認する(ライブラリ側と同じ意味論)。
|
|
12
|
+
class TestCopyDocMd < Test::Unit::TestCase
|
|
13
|
+
def docs_for(version)
|
|
14
|
+
Dir.mktmpdir do |dir|
|
|
15
|
+
FileUtils.mkdir_p(File.join(dir, 'manual', 'api'))
|
|
16
|
+
FileUtils.mkdir_p(File.join(dir, 'manual', 'doc', 'spec'))
|
|
17
|
+
File.write(File.join(dir, 'manual', 'doc', 'spec', 'gated.md'),
|
|
18
|
+
"---\nuntil: \"3.2\"\n---\n# ゲート付きページ\n\n本文。\n")
|
|
19
|
+
File.write(File.join(dir, 'manual', 'doc', 'spec', 'since.md'),
|
|
20
|
+
"---\nsince: \"3.3\"\n---\n# 新機能ページ\n\n本文。\n")
|
|
21
|
+
File.write(File.join(dir, 'manual', 'doc', 'spec', 'normal.md'),
|
|
22
|
+
"# 通常ページ\n\n本文。\n")
|
|
23
|
+
|
|
24
|
+
prefix = File.join(dir, 'db')
|
|
25
|
+
db = BitClust::MethodDatabase.new(prefix)
|
|
26
|
+
db.init
|
|
27
|
+
db.transaction do
|
|
28
|
+
db.propset('version', version)
|
|
29
|
+
db.propset('encoding', 'utf-8')
|
|
30
|
+
end
|
|
31
|
+
db.transaction do
|
|
32
|
+
db.instance_variable_set(:@md_root, File.join(dir, 'manual', 'api'))
|
|
33
|
+
db.__send__(:copy_doc_md)
|
|
34
|
+
end
|
|
35
|
+
db2 = BitClust::MethodDatabase.new(prefix)
|
|
36
|
+
return db2.docs.each_with_object({}) { |d, h| h[d.id] = d.title }
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def test_until_gate_before_threshold
|
|
41
|
+
docs = docs_for('3.0')
|
|
42
|
+
assert_equal 'ゲート付きページ', docs['spec.gated'] # until: 3.2 → 3.0 は表示
|
|
43
|
+
assert_nil docs['spec.since'] # since: 3.3 → 3.0 は非表示
|
|
44
|
+
assert_equal '通常ページ', docs['spec.normal']
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def test_until_gate_after_threshold
|
|
48
|
+
docs = docs_for('3.4')
|
|
49
|
+
assert_nil docs['spec.gated'] # until: 3.2 → 3.4 は非表示
|
|
50
|
+
assert_equal '新機能ページ', docs['spec.since'] # since: 3.3 → 3.4 は表示
|
|
51
|
+
assert_equal '通常ページ', docs['spec.normal']
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'test/unit'
|
|
4
|
+
|
|
5
|
+
require 'bitclust/doc_converter'
|
|
6
|
+
require 'bitclust/markdown_to_rrd'
|
|
7
|
+
|
|
8
|
+
# DocConverter: refm/doc(散文ページ)の md 変換。
|
|
9
|
+
# クロスファイル情報が無いので reduce(正規化)+ 単一ファイル変換のみ。
|
|
10
|
+
#
|
|
11
|
+
# reduce の正規化(意味を変えない表記ゆれを md→rd 再生成形に合わせる):
|
|
12
|
+
# [x] ラベル無し #@samplecode の末尾スペース除去(spec/variables.rd)
|
|
13
|
+
# [x] //} の末尾スペース除去(spec/pattern_matching.rd)
|
|
14
|
+
# [x] 定義リスト term の「: 」二重スペース → 「: 」(spec/safelevel.rd, symref.rd)
|
|
15
|
+
# [x] 行頭タブ → スペース(news/2_7_0.rd の散文1行のみ。コード例にタブは無い)
|
|
16
|
+
# [x] クロスツリー include を manual レイアウトへ(../api/src/X → ../api/X)
|
|
17
|
+
# [x] convert(rrd) は reduce 後の変換で、md→rd が reduce 結果を復元する
|
|
18
|
+
class TestDocConverter < Test::Unit::TestCase
|
|
19
|
+
def reduce(rrd)
|
|
20
|
+
BitClust::DocConverter.reduce(rrd)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def test_samplecode_trailing_space
|
|
24
|
+
assert_equal "\#@samplecode\ncode\n\#@end\n", reduce("\#@samplecode \ncode\n\#@end\n")
|
|
25
|
+
# ラベル付きは触らない
|
|
26
|
+
assert_equal "\#@samplecode 例\n", reduce("\#@samplecode 例\n")
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def test_emlist_close_trailing_space
|
|
30
|
+
assert_equal "//emlist{\ncode\n//}\n", reduce("//emlist{\ncode\n//} \n")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def test_dlist_term_double_space
|
|
34
|
+
assert_equal ": Object#taint\n", reduce(": Object#taint\n")
|
|
35
|
+
assert_equal ": !true\n", reduce(": !true\n")
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def test_anchored_heading_double_space
|
|
39
|
+
# spec/regexp.rd: ===[a:str] 特別な... (アンカー後の二重スペース)
|
|
40
|
+
assert_equal "===[a:str] 特別な文字列に対するマッチ\n",
|
|
41
|
+
reduce("===[a:str] 特別な文字列に対するマッチ\n")
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def test_leading_tab_to_space
|
|
45
|
+
assert_equal " x\n lazy になりました。\n", reduce(" x\n\tlazy になりました。\n")
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def test_cross_tree_include_rewritten_to_manual_layout
|
|
49
|
+
assert_equal "\#@include(../api/_builtin/pack-template)\n",
|
|
50
|
+
reduce("\#@include(../api/src/_builtin/pack-template)\n")
|
|
51
|
+
assert_equal "\#@include(../../api/_builtin/thread.inc)\n",
|
|
52
|
+
reduce("\#@include(../../api/src/_builtin/thread.inc)\n")
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def test_convert_roundtrips_to_reduced
|
|
56
|
+
rrd = "= タイトル\n\n本文。\n\n: term\n 説明。\n"
|
|
57
|
+
md = BitClust::DocConverter.convert(rrd)
|
|
58
|
+
assert_equal reduce(rrd), BitClust::MarkdownToRRD.convert(md)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def test_files_selects_pages_and_referenced_fragments
|
|
62
|
+
# 旧パイプライン(copy_doc)は **/*.rd だけをページとして読む。
|
|
63
|
+
# .rd 以外は include 参照される断片(spec/regexp19)のみ変換し、
|
|
64
|
+
# 参照されない死にファイル(news/1.8.0.rd-2)は凍結側に残す
|
|
65
|
+
require 'tmpdir'
|
|
66
|
+
require 'fileutils'
|
|
67
|
+
Dir.mktmpdir do |dir|
|
|
68
|
+
FileUtils.mkdir_p(File.join(dir, "spec"))
|
|
69
|
+
FileUtils.mkdir_p(File.join(dir, "news"))
|
|
70
|
+
File.write(File.join(dir, "spec/regexp.rd"), "= 正規表現\n\#@include(regexp19)\n")
|
|
71
|
+
File.write(File.join(dir, "spec/regexp19"), "断片。\n")
|
|
72
|
+
File.write(File.join(dir, "news/1.8.0.rd"), "= news\n")
|
|
73
|
+
File.write(File.join(dir, "news/1.8.0.rd-2"), "= 続き(孤児)\n")
|
|
74
|
+
assert_equal ["news/1.8.0.rd", "spec/regexp.rd", "spec/regexp19"],
|
|
75
|
+
BitClust::DocConverter.files(dir)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|