bitclust-core 1.7.0 → 1.8.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/data/bitclust/template/class-index +0 -1
- data/data/bitclust/template.epub/class +5 -5
- data/data/bitclust/template.epub/class-index +0 -1
- data/data/bitclust/template.epub/contents +7 -4
- data/data/bitclust/template.epub/layout +4 -4
- data/data/bitclust/template.offline/class-index +0 -1
- data/lib/bitclust/generators/epub.rb +69 -5
- data/lib/bitclust/irb.rb +14 -8
- data/lib/bitclust/markdown_bridge.rb +11 -6
- data/lib/bitclust/markdown_tree.rb +118 -11
- data/lib/bitclust/methoddatabase.rb +17 -4
- data/lib/bitclust/nameutils.rb +13 -0
- data/lib/bitclust/preprocessor.rb +0 -36
- data/lib/bitclust/remote.rb +405 -0
- data/lib/bitclust/runner.rb +5 -10
- data/lib/bitclust/screen.rb +2 -1
- data/lib/bitclust/searcher.rb +43 -24
- data/lib/bitclust/subcommands/chm_command.rb +1 -1
- data/lib/bitclust/subcommands/epub_command.rb +2 -2
- data/lib/bitclust/subcommands/extract_command.rb +7 -0
- data/lib/bitclust/subcommands/htmlfile_command.rb +7 -0
- data/lib/bitclust/subcommands/methods_command.rb +5 -28
- data/lib/bitclust/subcommands/query_command.rb +1 -0
- data/lib/bitclust/subcommands/server_command.rb +21 -10
- data/lib/bitclust/subcommands/setup_command.rb +28 -10
- data/lib/bitclust/syntax_highlighter.rb +65 -4
- data/lib/bitclust/user_dirs.rb +62 -0
- data/lib/bitclust/version.rb +1 -1
- data/test/test_chm_command.rb +22 -0
- data/test/test_epub_command.rb +60 -0
- data/test/test_epub_generator.rb +330 -0
- data/test/test_extract_command.rb +45 -0
- data/test/test_irb_plugin.rb +100 -6
- data/test/test_markdown_bridge.rb +35 -0
- data/test/test_markdown_tree.rb +144 -0
- data/test/test_mdparser.rb +39 -0
- data/test/test_methods_command.rb +32 -0
- data/test/test_opensearchdescription_screen.rb +39 -0
- data/test/test_query_command.rb +30 -0
- data/test/test_remote.rb +374 -0
- data/test/test_runner.rb +61 -1
- data/test/test_searcher.rb +63 -0
- data/test/test_server_command.rb +41 -0
- data/test/test_setup_command.rb +143 -0
- data/test/test_syntax_highlighter.rb +124 -0
- data/test/test_user_dirs.rb +62 -0
- metadata +37 -2
- data/lib/bitclust/ridatabase.rb +0 -359
data/test/test_runner.rb
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
require 'bitclust'
|
|
2
2
|
require 'bitclust/runner'
|
|
3
|
+
require 'bitclust/user_dirs'
|
|
4
|
+
require 'tmpdir'
|
|
5
|
+
require 'fileutils'
|
|
3
6
|
|
|
4
7
|
class TestRunner < Test::Unit::TestCase
|
|
5
8
|
def setup
|
|
@@ -116,7 +119,10 @@ class TestRunner < Test::Unit::TestCase
|
|
|
116
119
|
original_stderr = $stderr
|
|
117
120
|
$stderr = StringIO.new
|
|
118
121
|
assert_raise(SystemExit) { @runner.run(["init"]) }
|
|
119
|
-
|
|
122
|
+
message = $stderr.string
|
|
123
|
+
assert_include(message, "--database (-d)")
|
|
124
|
+
assert_include(message, "bitclust setup")
|
|
125
|
+
assert_include(message, BitClust::UserDirs.config_candidates.join(' or '))
|
|
120
126
|
ensure
|
|
121
127
|
$stderr = original_stderr
|
|
122
128
|
end
|
|
@@ -146,3 +152,57 @@ class TestRunner < Test::Unit::TestCase
|
|
|
146
152
|
end
|
|
147
153
|
end
|
|
148
154
|
end
|
|
155
|
+
|
|
156
|
+
# Runner#load_config が UserDirs 経由で設定ファイルを読むこと(実ファイルで検証)。
|
|
157
|
+
#
|
|
158
|
+
# テストリスト:
|
|
159
|
+
# [x] XDG の場所(~/.config/bitclust/config)にあればそれを読む
|
|
160
|
+
# [x] 従来の場所(~/.bitclust/config)にあればそれを読む
|
|
161
|
+
# [x] どちらも無ければ nil
|
|
162
|
+
class TestRunnerLoadConfig < Test::Unit::TestCase
|
|
163
|
+
ENV_KEYS = %w[HOME XDG_CONFIG_HOME XDG_DATA_HOME XDG_CACHE_HOME
|
|
164
|
+
REFE2_SERVER BITCLUST_SERVER REFE2_DATADIR BITCLUST_DATADIR].freeze
|
|
165
|
+
|
|
166
|
+
def setup
|
|
167
|
+
@saved = ENV_KEYS.to_h {|k| [k, ENV[k]] }
|
|
168
|
+
@home = Dir.mktmpdir
|
|
169
|
+
ENV['HOME'] = @home
|
|
170
|
+
(ENV_KEYS - %w[HOME]).each {|k| ENV.delete(k) }
|
|
171
|
+
@runner = BitClust::Runner.new
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def teardown
|
|
175
|
+
@saved.each {|k, v| v ? ENV[k] = v : ENV.delete(k) }
|
|
176
|
+
FileUtils.rm_rf(@home)
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def write_config(path, prefix, version)
|
|
180
|
+
FileUtils.mkdir_p(File.dirname(path))
|
|
181
|
+
File.write(path, { :default_version => version, :database_prefix => prefix }.to_yaml)
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def test_load_config_from_xdg_location
|
|
185
|
+
write_config(File.join(@home, '.config', 'bitclust', 'config'), '/xdg/db', '4.0')
|
|
186
|
+
config = @runner.load_config
|
|
187
|
+
assert_equal('/xdg/db', config[:database_prefix])
|
|
188
|
+
assert_equal('4.0', config[:default_version])
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def test_load_config_from_legacy_location
|
|
192
|
+
write_config(File.join(@home, '.bitclust', 'config'), '/legacy/db', '3.4')
|
|
193
|
+
config = @runner.load_config
|
|
194
|
+
assert_equal('/legacy/db', config[:database_prefix])
|
|
195
|
+
assert_equal('3.4', config[:default_version])
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def test_load_config_prefers_xdg_over_legacy
|
|
199
|
+
write_config(File.join(@home, '.bitclust', 'config'), '/legacy/db', '3.4')
|
|
200
|
+
write_config(File.join(@home, '.config', 'bitclust', 'config'), '/xdg/db', '4.0')
|
|
201
|
+
config = @runner.load_config
|
|
202
|
+
assert_equal('/xdg/db', config[:database_prefix])
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def test_load_config_nil_without_any_config_file
|
|
206
|
+
assert_nil(@runner.load_config)
|
|
207
|
+
end
|
|
208
|
+
end
|
data/test/test_searcher.rb
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
require "test/unit"
|
|
2
2
|
require "bitclust"
|
|
3
3
|
require "bitclust/searcher"
|
|
4
|
+
require "bitclust/user_dirs"
|
|
4
5
|
require "fileutils"
|
|
5
6
|
require "tmpdir"
|
|
7
|
+
require "yaml"
|
|
6
8
|
|
|
7
9
|
class TestTerminalView < Test::Unit::TestCase
|
|
8
10
|
include BitClust
|
|
@@ -151,3 +153,64 @@ class TestSearcherModuleFunctionQuery < Test::Unit::TestCase
|
|
|
151
153
|
assert_equal ["Foo", ".", "b?"], parse("Foo.b?")
|
|
152
154
|
end
|
|
153
155
|
end
|
|
156
|
+
|
|
157
|
+
# refe/bitclust search が、環境変数指定が無いとき設定ファイル(UserDirs)
|
|
158
|
+
# 経由で DB を見つけること。XDG の場所→従来の ~/.bitclust の順
|
|
159
|
+
class TestSearcherDefaultDbpath < Test::Unit::TestCase
|
|
160
|
+
include BitClust
|
|
161
|
+
|
|
162
|
+
ENV_KEYS = %w[HOME XDG_CONFIG_HOME XDG_DATA_HOME XDG_CACHE_HOME
|
|
163
|
+
REFE2_SERVER BITCLUST_SERVER REFE2_DATADIR BITCLUST_DATADIR].freeze
|
|
164
|
+
|
|
165
|
+
def setup
|
|
166
|
+
@saved = ENV_KEYS.to_h {|k| [k, ENV[k]] }
|
|
167
|
+
@home = Dir.mktmpdir
|
|
168
|
+
ENV['HOME'] = @home
|
|
169
|
+
(ENV_KEYS - %w[HOME]).each {|k| ENV.delete(k) }
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def teardown
|
|
173
|
+
@saved.each {|k, v| v ? ENV[k] = v : ENV.delete(k) }
|
|
174
|
+
FileUtils.rm_rf(@home)
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def write_config(path, prefix)
|
|
178
|
+
FileUtils.mkdir_p(File.dirname(path))
|
|
179
|
+
File.write(path, { :default_version => '9.9', :database_prefix => prefix }.to_yaml)
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def test_default_dbpath_via_xdg_config
|
|
183
|
+
prefix = File.join(@home, 'data', 'bitclust', 'db')
|
|
184
|
+
MethodDatabase.new("#{prefix}-9.9").init
|
|
185
|
+
write_config(File.join(@home, '.config', 'bitclust', 'config'), prefix)
|
|
186
|
+
searcher = Searcher.new
|
|
187
|
+
assert_equal("#{prefix}-9.9", searcher.send(:default_dbpath))
|
|
188
|
+
assert_true(searcher.local_database?)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def test_default_dbpath_via_legacy_config
|
|
192
|
+
prefix = File.join(@home, '.bitclust', 'db')
|
|
193
|
+
MethodDatabase.new("#{prefix}-9.9").init
|
|
194
|
+
write_config(File.join(@home, '.bitclust', 'config'), prefix)
|
|
195
|
+
searcher = Searcher.new
|
|
196
|
+
assert_equal("#{prefix}-9.9", searcher.send(:default_dbpath))
|
|
197
|
+
assert_true(searcher.local_database?)
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def test_default_dbpath_prefers_xdg_over_legacy
|
|
201
|
+
legacy_prefix = File.join(@home, '.bitclust', 'db')
|
|
202
|
+
MethodDatabase.new("#{legacy_prefix}-9.9").init
|
|
203
|
+
write_config(File.join(@home, '.bitclust', 'config'), legacy_prefix)
|
|
204
|
+
xdg_prefix = File.join(@home, 'data', 'bitclust', 'db')
|
|
205
|
+
MethodDatabase.new("#{xdg_prefix}-9.9").init
|
|
206
|
+
write_config(File.join(@home, '.config', 'bitclust', 'config'), xdg_prefix)
|
|
207
|
+
searcher = Searcher.new
|
|
208
|
+
assert_equal("#{xdg_prefix}-9.9", searcher.send(:default_dbpath))
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def test_default_dbpath_nil_without_config
|
|
212
|
+
searcher = Searcher.new
|
|
213
|
+
assert_nil(searcher.send(:default_dbpath))
|
|
214
|
+
assert_false(searcher.local_database?)
|
|
215
|
+
end
|
|
216
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require 'test/unit'
|
|
2
|
+
require 'stringio'
|
|
3
|
+
require 'bitclust'
|
|
4
|
+
require 'bitclust/subcommands/server_command'
|
|
5
|
+
|
|
6
|
+
class TestServerCommand < Test::Unit::TestCase
|
|
7
|
+
def build(argv)
|
|
8
|
+
cmd = BitClust::Subcommands::ServerCommand.new
|
|
9
|
+
cmd.parse(argv)
|
|
10
|
+
cmd
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def test_does_not_require_global_database
|
|
14
|
+
assert_false BitClust::Subcommands::ServerCommand.new.needs_database?
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def test_parse_accepts_short_option
|
|
18
|
+
cmd = build(['--baseurl=', '-d', '/tmp/db-x'])
|
|
19
|
+
assert_equal '/tmp/db-x', cmd.__send__(:resolve_dbpath, {:prefix => nil, :capi => false})
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def test_parse_accepts_long_option
|
|
23
|
+
cmd = build(['--baseurl=', '--database=/tmp/db-y'])
|
|
24
|
+
assert_equal '/tmp/db-y', cmd.__send__(:resolve_dbpath, {:prefix => '/tmp/global', :capi => false})
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def test_global_database_is_used_as_fallback
|
|
28
|
+
cmd = build(['--baseurl='])
|
|
29
|
+
assert_equal '/tmp/global', cmd.__send__(:resolve_dbpath, {:prefix => '/tmp/global', :capi => false})
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def test_missing_database_aborts_with_guidance
|
|
33
|
+
cmd = build(['--baseurl='])
|
|
34
|
+
err = StringIO.new
|
|
35
|
+
orig, $stderr = $stderr, err
|
|
36
|
+
assert_raise(SystemExit) { cmd.__send__(:resolve_dbpath, {:prefix => nil, :capi => false}) }
|
|
37
|
+
assert_match(/--database/, err.string)
|
|
38
|
+
ensure
|
|
39
|
+
$stderr = orig
|
|
40
|
+
end
|
|
41
|
+
end
|
data/test/test_setup_command.rb
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
require 'test/unit'
|
|
3
3
|
require 'bitclust'
|
|
4
4
|
require 'bitclust/subcommands/setup_command'
|
|
5
|
+
require 'bitclust/user_dirs'
|
|
6
|
+
require 'tmpdir'
|
|
7
|
+
require 'fileutils'
|
|
8
|
+
require 'yaml'
|
|
5
9
|
|
|
6
10
|
# setup サブコマンドの既定バージョン。
|
|
7
11
|
#
|
|
@@ -19,3 +23,142 @@ class TestSetupCommand < Test::Unit::TestCase
|
|
|
19
23
|
end
|
|
20
24
|
end
|
|
21
25
|
end
|
|
26
|
+
|
|
27
|
+
# setup サブコマンドが選ぶ、設定・DB・doctree checkout の置き場所。
|
|
28
|
+
#
|
|
29
|
+
# テストリスト:
|
|
30
|
+
# [x] 何も無ければ XDG の場所(~/.config/bitclust, ~/.local/share/bitclust)を使う
|
|
31
|
+
# [x] 従来の ~/.bitclust/config だけあれば、そのレイアウトを維持する
|
|
32
|
+
# [x] 両方あれば XDG を使う
|
|
33
|
+
class TestSetupCommandLayout < Test::Unit::TestCase
|
|
34
|
+
ENV_KEYS = %w[HOME XDG_CONFIG_HOME XDG_DATA_HOME XDG_CACHE_HOME].freeze
|
|
35
|
+
|
|
36
|
+
def setup
|
|
37
|
+
@saved = ENV_KEYS.to_h {|k| [k, ENV[k]] }
|
|
38
|
+
@home = Dir.mktmpdir
|
|
39
|
+
ENV['HOME'] = @home
|
|
40
|
+
(ENV_KEYS - %w[HOME]).each {|k| ENV.delete(k) }
|
|
41
|
+
@cmd = BitClust::Subcommands::SetupCommand.new
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def teardown
|
|
45
|
+
@saved.each {|k, v| v ? ENV[k] = v : ENV.delete(k) }
|
|
46
|
+
FileUtils.rm_rf(@home)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def touch_config(path)
|
|
50
|
+
FileUtils.mkdir_p(File.dirname(path))
|
|
51
|
+
FileUtils.touch(path)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def test_layout_uses_xdg_when_nothing_exists
|
|
55
|
+
config_path, database_prefix, rubydoc_dir = @cmd.send(:layout)
|
|
56
|
+
assert_equal(File.join(@home, '.config', 'bitclust', 'config'), config_path.to_s)
|
|
57
|
+
assert_equal(File.join(@home, '.local', 'share', 'bitclust', 'db'), database_prefix)
|
|
58
|
+
assert_equal(File.join(@home, '.local', 'share', 'bitclust', 'rubydoc'), rubydoc_dir.to_s)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def test_layout_keeps_legacy_when_only_legacy_config_exists
|
|
62
|
+
touch_config(File.join(@home, '.bitclust', 'config'))
|
|
63
|
+
config_path, database_prefix, rubydoc_dir = @cmd.send(:layout)
|
|
64
|
+
assert_equal(File.join(@home, '.bitclust', 'config'), config_path.to_s)
|
|
65
|
+
assert_equal(File.join(@home, '.bitclust', 'db'), database_prefix)
|
|
66
|
+
assert_equal(File.join(@home, '.bitclust', 'rubydoc'), rubydoc_dir.to_s)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def test_layout_uses_xdg_when_both_exist
|
|
70
|
+
touch_config(File.join(@home, '.bitclust', 'config'))
|
|
71
|
+
touch_config(File.join(@home, '.config', 'bitclust', 'config'))
|
|
72
|
+
config_path, database_prefix, _rubydoc_dir = @cmd.send(:layout)
|
|
73
|
+
assert_equal(File.join(@home, '.config', 'bitclust', 'config'), config_path.to_s)
|
|
74
|
+
assert_equal(File.join(@home, '.local', 'share', 'bitclust', 'db'), database_prefix)
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# setup --prepare が layout の選択どおりに設定ファイルを書くこと
|
|
79
|
+
# (checkout はネットワークに出るのでスタブする)
|
|
80
|
+
class TestSetupCommandPrepare < Test::Unit::TestCase
|
|
81
|
+
ENV_KEYS = %w[HOME XDG_CONFIG_HOME XDG_DATA_HOME XDG_CACHE_HOME].freeze
|
|
82
|
+
|
|
83
|
+
def setup
|
|
84
|
+
@saved = ENV_KEYS.to_h {|k| [k, ENV[k]] }
|
|
85
|
+
@home = Dir.mktmpdir
|
|
86
|
+
ENV['HOME'] = @home
|
|
87
|
+
(ENV_KEYS - %w[HOME]).each {|k| ENV.delete(k) }
|
|
88
|
+
@cmd = BitClust::Subcommands::SetupCommand.new
|
|
89
|
+
stub(@cmd).checkout {|_dir| nil }
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def teardown
|
|
93
|
+
@saved.each {|k, v| v ? ENV[k] = v : ENV.delete(k) }
|
|
94
|
+
FileUtils.rm_rf(@home)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def test_prepare_writes_config_under_xdg_config_home
|
|
98
|
+
@cmd.send(:prepare)
|
|
99
|
+
config_path = File.join(@home, '.config', 'bitclust', 'config')
|
|
100
|
+
assert_true(File.exist?(config_path))
|
|
101
|
+
config = YAML.load_file(config_path)
|
|
102
|
+
assert_equal(File.join(@home, '.local', 'share', 'bitclust', 'db'), config[:database_prefix])
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def test_prepare_keeps_legacy_layout_when_legacy_config_exists
|
|
106
|
+
legacy_config = File.join(@home, '.bitclust', 'config')
|
|
107
|
+
FileUtils.mkdir_p(File.dirname(legacy_config))
|
|
108
|
+
versions = @cmd.instance_variable_get(:@versions)
|
|
109
|
+
File.write(legacy_config, {
|
|
110
|
+
:database_prefix => File.join(@home, '.bitclust', 'db'),
|
|
111
|
+
:encoding => 'utf-8',
|
|
112
|
+
:versions => versions,
|
|
113
|
+
:default_version => versions.max,
|
|
114
|
+
:mdtree => File.join(@home, '.bitclust', 'rubydoc', 'manual', 'api'),
|
|
115
|
+
:capi_mdtree => File.join(@home, '.bitclust', 'rubydoc', 'manual', 'capi'),
|
|
116
|
+
:baseurl => 'http://localhost:10080',
|
|
117
|
+
:port => '10080',
|
|
118
|
+
:pid_file => '/tmp/bitclust.pid',
|
|
119
|
+
}.to_yaml)
|
|
120
|
+
@cmd.send(:prepare)
|
|
121
|
+
assert_false(File.exist?(File.join(@home, '.config', 'bitclust', 'config')))
|
|
122
|
+
config = YAML.load_file(legacy_config)
|
|
123
|
+
assert_equal(File.join(@home, '.bitclust', 'db'), config[:database_prefix])
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# setup --purge が新旧すべての置き場所を消すこと
|
|
128
|
+
class TestSetupCommandPurge < Test::Unit::TestCase
|
|
129
|
+
ENV_KEYS = %w[HOME XDG_CONFIG_HOME XDG_DATA_HOME XDG_CACHE_HOME].freeze
|
|
130
|
+
|
|
131
|
+
def setup
|
|
132
|
+
@saved = ENV_KEYS.to_h {|k| [k, ENV[k]] }
|
|
133
|
+
@home = Dir.mktmpdir
|
|
134
|
+
ENV['HOME'] = @home
|
|
135
|
+
(ENV_KEYS - %w[HOME]).each {|k| ENV.delete(k) }
|
|
136
|
+
@cmd = BitClust::Subcommands::SetupCommand.new
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def teardown
|
|
140
|
+
@saved.each {|k, v| v ? ENV[k] = v : ENV.delete(k) }
|
|
141
|
+
FileUtils.rm_rf(@home)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def test_purge_removes_legacy_xdg_config_data_and_cache_dirs
|
|
145
|
+
dirs = [
|
|
146
|
+
File.join(@home, '.bitclust'),
|
|
147
|
+
File.join(@home, '.config', 'bitclust'),
|
|
148
|
+
File.join(@home, '.local', 'share', 'bitclust'),
|
|
149
|
+
File.join(@home, '.cache', 'bitclust'),
|
|
150
|
+
]
|
|
151
|
+
dirs.each {|dir| FileUtils.mkdir_p(dir) }
|
|
152
|
+
out, _err = capture_output do
|
|
153
|
+
assert_raise(SystemExit) { @cmd.send(:purge) }
|
|
154
|
+
end
|
|
155
|
+
dirs.each do |dir|
|
|
156
|
+
assert_false(File.exist?(dir), dir)
|
|
157
|
+
assert_include(out, dir)
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def test_purge_is_fine_when_nothing_exists
|
|
162
|
+
assert_raise(SystemExit) { capture_output { @cmd.send(:purge) } }
|
|
163
|
+
end
|
|
164
|
+
end
|
|
@@ -123,6 +123,98 @@ class TestSyntaxHighlighter < Test::Unit::TestCase
|
|
|
123
123
|
assert_equal(expected, highlight(source))
|
|
124
124
|
end
|
|
125
125
|
|
|
126
|
+
sub_test_case "symbol span" do
|
|
127
|
+
test 'ivar symbol' do
|
|
128
|
+
source = "x = :@records\n"
|
|
129
|
+
expected = "x <span class=\"o\">=</span> <span class=\"ss\">:@records</span>\n"
|
|
130
|
+
assert_equal(expected, highlight(source))
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
test 'cvar symbol' do
|
|
134
|
+
source = "x = :@@cv\n"
|
|
135
|
+
expected = "x <span class=\"o\">=</span> <span class=\"ss\">:@@cv</span>\n"
|
|
136
|
+
assert_equal(expected, highlight(source))
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
test 'gvar symbol' do
|
|
140
|
+
source = "x = :$stdout\n"
|
|
141
|
+
expected = "x <span class=\"o\">=</span> <span class=\"ss\">:$stdout</span>\n"
|
|
142
|
+
assert_equal(expected, highlight(source))
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
test 'operator symbols' do
|
|
146
|
+
source = <<~END
|
|
147
|
+
a = :+
|
|
148
|
+
b = :<<
|
|
149
|
+
c = :[]
|
|
150
|
+
d = :[]=
|
|
151
|
+
e = :<=>
|
|
152
|
+
f = :!
|
|
153
|
+
END
|
|
154
|
+
expected = <<~END
|
|
155
|
+
a <span class="o">=</span> <span class="ss">:+</span>
|
|
156
|
+
b <span class="o">=</span> <span class="ss">:<<</span>
|
|
157
|
+
c <span class="o">=</span> <span class="ss">:[]</span>
|
|
158
|
+
d <span class="o">=</span> <span class="ss">:[]=</span>
|
|
159
|
+
e <span class="o">=</span> <span class="ss">:<=></span>
|
|
160
|
+
f <span class="o">=</span> <span class="ss">:!</span>
|
|
161
|
+
END
|
|
162
|
+
assert_equal(expected, highlight(source))
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
test '%s dynamic symbol literal' do
|
|
166
|
+
source = "x = %s!sym!\n"
|
|
167
|
+
expected = "x <span class=\"o\">=</span> <span class=\"ss\">%s!sym!</span>\n"
|
|
168
|
+
assert_equal(expected, highlight(source))
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
test 'double-quoted dynamic symbol' do
|
|
172
|
+
source = "x = :\"dyn\"\n"
|
|
173
|
+
expected = "x <span class=\"o\">=</span> <span class=\"ss\">:"dyn"</span>\n"
|
|
174
|
+
assert_equal(expected, highlight(source))
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
test 'well-formedness of mixed symbol spans' do
|
|
178
|
+
source = <<~END
|
|
179
|
+
x = :@records
|
|
180
|
+
y = :@@cv
|
|
181
|
+
z = :$stdout
|
|
182
|
+
a = :+
|
|
183
|
+
b = :<<
|
|
184
|
+
c = :[]
|
|
185
|
+
s = %s!sym!
|
|
186
|
+
d = :"dyn"
|
|
187
|
+
END
|
|
188
|
+
result = highlight(source)
|
|
189
|
+
assert_equal(result.scan('<span').size, result.scan('</span>').size)
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
test 'symbol does not leak the stack into later tokens' do
|
|
193
|
+
source = <<~END
|
|
194
|
+
x = :@records
|
|
195
|
+
def foo
|
|
196
|
+
end
|
|
197
|
+
END
|
|
198
|
+
baseline = highlight("def foo\nend\n")
|
|
199
|
+
result = highlight(source)
|
|
200
|
+
assert(
|
|
201
|
+
result.end_with?(baseline),
|
|
202
|
+
"expected result to end with unaffected `def foo/end` rendering:\n" \
|
|
203
|
+
" baseline: #{baseline.inspect}\n" \
|
|
204
|
+
" result: #{result.inspect}"
|
|
205
|
+
)
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
test 'label is not treated as a symbol' do
|
|
209
|
+
source = "h = { a: 1 }\nfoo(:x, k: 2)\n"
|
|
210
|
+
result = highlight(source)
|
|
211
|
+
assert_equal(result.scan('<span').size, result.scan('</span>').size)
|
|
212
|
+
assert_match(%r{<span class="ss">a:</span>}, result)
|
|
213
|
+
assert_match(%r{<span class="ss">k:</span>}, result)
|
|
214
|
+
assert_match(%r{<span class="ss">:x</span>}, result)
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
126
218
|
test 'one liner module' do
|
|
127
219
|
source = <<~END
|
|
128
220
|
module Foo; end
|
|
@@ -142,4 +234,36 @@ class TestSyntaxHighlighter < Test::Unit::TestCase
|
|
|
142
234
|
END
|
|
143
235
|
assert_equal(expected, highlight(source))
|
|
144
236
|
end
|
|
237
|
+
|
|
238
|
+
sub_test_case "heredoc argument and quoted label" do
|
|
239
|
+
def assert_balanced(html)
|
|
240
|
+
assert_equal html.scan(/<span\b/).size, html.scan(%r{</span>}).size, html
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
test 'identifier after a heredoc argument is rendered normally' do
|
|
244
|
+
html = highlight("method(arg1, <<LABEL, arg2)\n x\nLABEL\n")
|
|
245
|
+
assert_include(html, ', arg2<span class="p">)</span>')
|
|
246
|
+
assert_balanced(html)
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
test 'block argument after a heredoc argument' do
|
|
250
|
+
html = highlight("ERB.new(<<~'END_PRODUCT', eoutvar: \"@product\").result b\n x\nEND_PRODUCT\n")
|
|
251
|
+
assert_balanced(html)
|
|
252
|
+
assert_not_include(html, '<span class="no">b')
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
test 'quoted symbol keys close the string span' do
|
|
256
|
+
html = highlight(%q({ "a":"A", 'b':"B" }) + "\n")
|
|
257
|
+
assert_balanced(html)
|
|
258
|
+
assert_include(html, %q(<span class="s1">'b':</span>))
|
|
259
|
+
assert_include(html, %q(<span class="s2">a</span><span class="s2">":</span>))
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
test 'quoted symbol key does not leak the stack' do
|
|
263
|
+
with = highlight(%q({ "a":"A" }) + "\ndef foo\nend\n")
|
|
264
|
+
without = highlight("def foo\nend\n")
|
|
265
|
+
assert_include(with, without.lines[0].chomp)
|
|
266
|
+
assert_balanced(with)
|
|
267
|
+
end
|
|
268
|
+
end
|
|
145
269
|
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require 'test/unit'
|
|
3
|
+
require 'tmpdir'
|
|
4
|
+
require 'fileutils'
|
|
5
|
+
require 'bitclust/user_dirs'
|
|
6
|
+
|
|
7
|
+
# 設定・DB・キャッシュの置き場所(XDG 準拠+従来の ~/.bitclust fallback)。
|
|
8
|
+
#
|
|
9
|
+
# テストリスト:
|
|
10
|
+
# [x] XDG_* 未設定なら ~/.config ~/.local/share ~/.cache の下の bitclust/
|
|
11
|
+
# [x] XDG_* が絶対パスならそれを使う。相対パスは無視して既定に戻る
|
|
12
|
+
# [x] config_file は XDG → ~/.bitclust の順で存在するものを返す。無ければ nil
|
|
13
|
+
# [x] load_config は設定ファイルの YAML を返す。無ければ nil
|
|
14
|
+
class TestUserDirs < Test::Unit::TestCase
|
|
15
|
+
KEYS = %w[HOME XDG_CONFIG_HOME XDG_DATA_HOME XDG_CACHE_HOME].freeze
|
|
16
|
+
|
|
17
|
+
def setup
|
|
18
|
+
@saved = KEYS.to_h {|k| [k, ENV[k]] }
|
|
19
|
+
@home = Dir.mktmpdir
|
|
20
|
+
ENV['HOME'] = @home
|
|
21
|
+
%w[XDG_CONFIG_HOME XDG_DATA_HOME XDG_CACHE_HOME].each {|k| ENV.delete(k) }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def teardown
|
|
25
|
+
@saved.each {|k, v| v ? ENV[k] = v : ENV.delete(k) }
|
|
26
|
+
FileUtils.rm_rf(@home)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def test_defaults_under_home
|
|
30
|
+
assert_equal(File.join(@home, '.config', 'bitclust'), BitClust::UserDirs.config_home.to_s)
|
|
31
|
+
assert_equal(File.join(@home, '.local', 'share', 'bitclust'), BitClust::UserDirs.data_home.to_s)
|
|
32
|
+
assert_equal(File.join(@home, '.cache', 'bitclust'), BitClust::UserDirs.cache_home.to_s)
|
|
33
|
+
assert_equal(File.join(@home, '.bitclust'), BitClust::UserDirs.legacy_dir.to_s)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def test_xdg_environment_variables
|
|
37
|
+
ENV['XDG_CONFIG_HOME'] = File.join(@home, 'cfg')
|
|
38
|
+
ENV['XDG_DATA_HOME'] = File.join(@home, 'data')
|
|
39
|
+
ENV['XDG_CACHE_HOME'] = 'relative/cache'
|
|
40
|
+
assert_equal(File.join(@home, 'cfg', 'bitclust'), BitClust::UserDirs.config_home.to_s)
|
|
41
|
+
assert_equal(File.join(@home, 'data', 'bitclust'), BitClust::UserDirs.data_home.to_s)
|
|
42
|
+
assert_equal(File.join(@home, '.cache', 'bitclust'), BitClust::UserDirs.cache_home.to_s)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def test_config_file_prefers_xdg_then_legacy
|
|
46
|
+
assert_nil(BitClust::UserDirs.config_file)
|
|
47
|
+
legacy = File.join(@home, '.bitclust', 'config')
|
|
48
|
+
FileUtils.mkdir_p(File.dirname(legacy))
|
|
49
|
+
File.write(legacy, { default_version: '3.4', database_prefix: '/legacy/db' }.to_yaml)
|
|
50
|
+
assert_equal(legacy, BitClust::UserDirs.config_file.to_s)
|
|
51
|
+
assert_equal('/legacy/db', BitClust::UserDirs.load_config[:database_prefix])
|
|
52
|
+
xdg = File.join(@home, '.config', 'bitclust', 'config')
|
|
53
|
+
FileUtils.mkdir_p(File.dirname(xdg))
|
|
54
|
+
File.write(xdg, { default_version: '4.0', database_prefix: '/xdg/db' }.to_yaml)
|
|
55
|
+
assert_equal(xdg, BitClust::UserDirs.config_file.to_s)
|
|
56
|
+
assert_equal('/xdg/db', BitClust::UserDirs.load_config[:database_prefix])
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def test_load_config_without_file
|
|
60
|
+
assert_nil(BitClust::UserDirs.load_config)
|
|
61
|
+
end
|
|
62
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: bitclust-core
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.8.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- https://github.com/rurema
|
|
@@ -51,6 +51,20 @@ dependencies:
|
|
|
51
51
|
- - ">="
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
53
|
version: '0'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: rexml
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '0'
|
|
61
|
+
type: :development
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - ">="
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '0'
|
|
54
68
|
- !ruby/object:Gem::Dependency
|
|
55
69
|
name: rack
|
|
56
70
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -278,8 +292,8 @@ files:
|
|
|
278
292
|
- lib/bitclust/rdcompiler.rb
|
|
279
293
|
- lib/bitclust/refsdatabase.rb
|
|
280
294
|
- lib/bitclust/reloadable_request_handler.rb
|
|
295
|
+
- lib/bitclust/remote.rb
|
|
281
296
|
- lib/bitclust/requesthandler.rb
|
|
282
|
-
- lib/bitclust/ridatabase.rb
|
|
283
297
|
- lib/bitclust/rrd_to_markdown.rb
|
|
284
298
|
- lib/bitclust/rrdparser.rb
|
|
285
299
|
- lib/bitclust/runner.rb
|
|
@@ -313,6 +327,7 @@ files:
|
|
|
313
327
|
- lib/bitclust/subcommands/update_command.rb
|
|
314
328
|
- lib/bitclust/syntax_highlighter.rb
|
|
315
329
|
- lib/bitclust/textutils.rb
|
|
330
|
+
- lib/bitclust/user_dirs.rb
|
|
316
331
|
- lib/bitclust/version.rb
|
|
317
332
|
- lib/bitclust/version_badges.rb
|
|
318
333
|
- lib/bitclust/whole_file_gate.rb
|
|
@@ -320,12 +335,16 @@ files:
|
|
|
320
335
|
- test/test_app.rb
|
|
321
336
|
- test/test_bitclust.rb
|
|
322
337
|
- test/test_capi_converter.rb
|
|
338
|
+
- test/test_chm_command.rb
|
|
323
339
|
- test/test_class_screen.rb
|
|
324
340
|
- test/test_copy_doc_md.rb
|
|
325
341
|
- test/test_doc_converter.rb
|
|
326
342
|
- test/test_entity_splitter.rb
|
|
327
343
|
- test/test_entry.rb
|
|
328
344
|
- test/test_eol_warning.rb
|
|
345
|
+
- test/test_epub_command.rb
|
|
346
|
+
- test/test_epub_generator.rb
|
|
347
|
+
- test/test_extract_command.rb
|
|
329
348
|
- test/test_functiondatabase.rb
|
|
330
349
|
- test/test_functionreferenceparser.rb
|
|
331
350
|
- test/test_include_graph.rb
|
|
@@ -345,15 +364,19 @@ files:
|
|
|
345
364
|
- test/test_method_since_calculator.rb
|
|
346
365
|
- test/test_methoddatabase.rb
|
|
347
366
|
- test/test_methodentry.rb
|
|
367
|
+
- test/test_methods_command.rb
|
|
348
368
|
- test/test_methodsignature.rb
|
|
349
369
|
- test/test_methodsince_command.rb
|
|
350
370
|
- test/test_nameutils.rb
|
|
371
|
+
- test/test_opensearchdescription_screen.rb
|
|
351
372
|
- test/test_preprocessor.rb
|
|
373
|
+
- test/test_query_command.rb
|
|
352
374
|
- test/test_rbs_overload_matcher.rb
|
|
353
375
|
- test/test_rbs_sig_importer.rb
|
|
354
376
|
- test/test_rbssig_command.rb
|
|
355
377
|
- test/test_rdcompiler.rb
|
|
356
378
|
- test/test_refsdatabase.rb
|
|
379
|
+
- test/test_remote.rb
|
|
357
380
|
- test/test_rrd_to_markdown.rb
|
|
358
381
|
- test/test_rrdparser.rb
|
|
359
382
|
- test/test_run_ruby_wasm.rb
|
|
@@ -363,10 +386,12 @@ files:
|
|
|
363
386
|
- test/test_search_screen.rb
|
|
364
387
|
- test/test_searcher.rb
|
|
365
388
|
- test/test_searchpage_command.rb
|
|
389
|
+
- test/test_server_command.rb
|
|
366
390
|
- test/test_setup_command.rb
|
|
367
391
|
- test/test_simplesearcher.rb
|
|
368
392
|
- test/test_statichtml_command.rb
|
|
369
393
|
- test/test_syntax_highlighter.rb
|
|
394
|
+
- test/test_user_dirs.rb
|
|
370
395
|
- test/test_whole_file_gate.rb
|
|
371
396
|
- theme/default/images/external.png
|
|
372
397
|
- theme/default/js/NOTICE
|
|
@@ -418,12 +443,16 @@ test_files:
|
|
|
418
443
|
- test/test_app.rb
|
|
419
444
|
- test/test_bitclust.rb
|
|
420
445
|
- test/test_capi_converter.rb
|
|
446
|
+
- test/test_chm_command.rb
|
|
421
447
|
- test/test_class_screen.rb
|
|
422
448
|
- test/test_copy_doc_md.rb
|
|
423
449
|
- test/test_doc_converter.rb
|
|
424
450
|
- test/test_entity_splitter.rb
|
|
425
451
|
- test/test_entry.rb
|
|
426
452
|
- test/test_eol_warning.rb
|
|
453
|
+
- test/test_epub_command.rb
|
|
454
|
+
- test/test_epub_generator.rb
|
|
455
|
+
- test/test_extract_command.rb
|
|
427
456
|
- test/test_functiondatabase.rb
|
|
428
457
|
- test/test_functionreferenceparser.rb
|
|
429
458
|
- test/test_include_graph.rb
|
|
@@ -443,15 +472,19 @@ test_files:
|
|
|
443
472
|
- test/test_method_since_calculator.rb
|
|
444
473
|
- test/test_methoddatabase.rb
|
|
445
474
|
- test/test_methodentry.rb
|
|
475
|
+
- test/test_methods_command.rb
|
|
446
476
|
- test/test_methodsignature.rb
|
|
447
477
|
- test/test_methodsince_command.rb
|
|
448
478
|
- test/test_nameutils.rb
|
|
479
|
+
- test/test_opensearchdescription_screen.rb
|
|
449
480
|
- test/test_preprocessor.rb
|
|
481
|
+
- test/test_query_command.rb
|
|
450
482
|
- test/test_rbs_overload_matcher.rb
|
|
451
483
|
- test/test_rbs_sig_importer.rb
|
|
452
484
|
- test/test_rbssig_command.rb
|
|
453
485
|
- test/test_rdcompiler.rb
|
|
454
486
|
- test/test_refsdatabase.rb
|
|
487
|
+
- test/test_remote.rb
|
|
455
488
|
- test/test_rrd_to_markdown.rb
|
|
456
489
|
- test/test_rrdparser.rb
|
|
457
490
|
- test/test_run_ruby_wasm.rb
|
|
@@ -461,8 +494,10 @@ test_files:
|
|
|
461
494
|
- test/test_search_screen.rb
|
|
462
495
|
- test/test_searcher.rb
|
|
463
496
|
- test/test_searchpage_command.rb
|
|
497
|
+
- test/test_server_command.rb
|
|
464
498
|
- test/test_setup_command.rb
|
|
465
499
|
- test/test_simplesearcher.rb
|
|
466
500
|
- test/test_statichtml_command.rb
|
|
467
501
|
- test/test_syntax_highlighter.rb
|
|
502
|
+
- test/test_user_dirs.rb
|
|
468
503
|
- test/test_whole_file_gate.rb
|