gemba 0.1.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 +7 -0
- data/THIRD_PARTY_NOTICES +113 -0
- data/assets/JetBrainsMonoNL-Regular.ttf +0 -0
- data/assets/ark-pixel-12px-monospaced-ja.ttf +0 -0
- data/bin/gemba +14 -0
- data/ext/gemba/extconf.rb +185 -0
- data/ext/gemba/gemba_ext.c +1051 -0
- data/ext/gemba/gemba_ext.h +15 -0
- data/gemba.gemspec +38 -0
- data/lib/gemba/child_window.rb +62 -0
- data/lib/gemba/cli.rb +384 -0
- data/lib/gemba/config.rb +621 -0
- data/lib/gemba/core.rb +121 -0
- data/lib/gemba/headless.rb +12 -0
- data/lib/gemba/headless_player.rb +206 -0
- data/lib/gemba/hotkey_map.rb +202 -0
- data/lib/gemba/input_mappings.rb +214 -0
- data/lib/gemba/locale.rb +92 -0
- data/lib/gemba/locales/en.yml +157 -0
- data/lib/gemba/locales/ja.yml +157 -0
- data/lib/gemba/method_coverage_service.rb +265 -0
- data/lib/gemba/overlay_renderer.rb +109 -0
- data/lib/gemba/player.rb +1515 -0
- data/lib/gemba/recorder.rb +156 -0
- data/lib/gemba/recorder_decoder.rb +325 -0
- data/lib/gemba/rom_info_window.rb +346 -0
- data/lib/gemba/rom_loader.rb +100 -0
- data/lib/gemba/runtime.rb +39 -0
- data/lib/gemba/save_state_manager.rb +155 -0
- data/lib/gemba/save_state_picker.rb +199 -0
- data/lib/gemba/settings_window.rb +1173 -0
- data/lib/gemba/tip_service.rb +133 -0
- data/lib/gemba/toast_overlay.rb +128 -0
- data/lib/gemba/version.rb +5 -0
- data/lib/gemba.rb +17 -0
- data/test/fixtures/test.gba +0 -0
- data/test/fixtures/test.sav +0 -0
- data/test/shared/screenshot_helper.rb +113 -0
- data/test/shared/simplecov_config.rb +59 -0
- data/test/shared/teek_test_worker.rb +388 -0
- data/test/shared/tk_test_helper.rb +354 -0
- data/test/support/input_mocks.rb +61 -0
- data/test/support/player_helpers.rb +77 -0
- data/test/test_cli.rb +281 -0
- data/test/test_config.rb +897 -0
- data/test/test_core.rb +401 -0
- data/test/test_gamepad_map.rb +116 -0
- data/test/test_headless_player.rb +205 -0
- data/test/test_helper.rb +19 -0
- data/test/test_hotkey_map.rb +396 -0
- data/test/test_keyboard_map.rb +108 -0
- data/test/test_locale.rb +159 -0
- data/test/test_mgba.rb +26 -0
- data/test/test_overlay_renderer.rb +199 -0
- data/test/test_player.rb +903 -0
- data/test/test_recorder.rb +180 -0
- data/test/test_rom_loader.rb +149 -0
- data/test/test_save_state_manager.rb +289 -0
- data/test/test_settings_hotkeys.rb +434 -0
- data/test/test_settings_window.rb +1039 -0
- data/test/test_tip_service.rb +138 -0
- data/test/test_toast_overlay.rb +216 -0
- data/test/test_virtual_keyboard.rb +39 -0
- data/test/test_xor_delta.rb +61 -0
- metadata +234 -0
data/test/test_cli.rb
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "minitest/autorun"
|
|
4
|
+
require "gemba"
|
|
5
|
+
require_relative "../lib/gemba/version"
|
|
6
|
+
require_relative "../lib/gemba/cli"
|
|
7
|
+
|
|
8
|
+
class TestCLI < Minitest::Test
|
|
9
|
+
def parse(args)
|
|
10
|
+
Gemba::CLI.parse(args)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# -- ROM argument --
|
|
14
|
+
|
|
15
|
+
def test_rom_path
|
|
16
|
+
opts = parse(["game.gba"])
|
|
17
|
+
assert_equal File.expand_path("game.gba"), opts[:rom]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def test_rom_path_expands_tilde
|
|
21
|
+
opts = parse(["~/game.gba"])
|
|
22
|
+
assert_equal File.join(Dir.home, "game.gba"), opts[:rom]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def test_no_rom
|
|
26
|
+
opts = parse([])
|
|
27
|
+
assert_nil opts[:rom]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# -- player flags --
|
|
31
|
+
|
|
32
|
+
def test_scale
|
|
33
|
+
opts = parse(["--scale", "2"])
|
|
34
|
+
assert_equal 2, opts[:scale]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def test_scale_short
|
|
38
|
+
opts = parse(["-s", "3"])
|
|
39
|
+
assert_equal 3, opts[:scale]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def test_scale_clamps_high
|
|
43
|
+
opts = parse(["--scale", "10"])
|
|
44
|
+
assert_equal 4, opts[:scale]
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def test_scale_clamps_low
|
|
48
|
+
opts = parse(["--scale", "0"])
|
|
49
|
+
assert_equal 1, opts[:scale]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def test_volume
|
|
53
|
+
opts = parse(["--volume", "50"])
|
|
54
|
+
assert_equal 50, opts[:volume]
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def test_volume_short
|
|
58
|
+
opts = parse(["-v", "75"])
|
|
59
|
+
assert_equal 75, opts[:volume]
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def test_volume_clamps
|
|
63
|
+
opts = parse(["--volume", "200"])
|
|
64
|
+
assert_equal 100, opts[:volume]
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def test_mute
|
|
68
|
+
opts = parse(["--mute"])
|
|
69
|
+
assert opts[:mute]
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def test_mute_short
|
|
73
|
+
opts = parse(["-m"])
|
|
74
|
+
assert opts[:mute]
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def test_no_sound
|
|
78
|
+
opts = parse(["--no-sound"])
|
|
79
|
+
assert_equal false, opts[:sound]
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def test_fullscreen
|
|
83
|
+
opts = parse(["--fullscreen"])
|
|
84
|
+
assert opts[:fullscreen]
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def test_fullscreen_short
|
|
88
|
+
opts = parse(["-f"])
|
|
89
|
+
assert opts[:fullscreen]
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def test_show_fps
|
|
93
|
+
opts = parse(["--show-fps"])
|
|
94
|
+
assert opts[:show_fps]
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def test_turbo_speed
|
|
98
|
+
opts = parse(["--turbo-speed", "3"])
|
|
99
|
+
assert_equal 3, opts[:turbo_speed]
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def test_turbo_speed_clamps
|
|
103
|
+
opts = parse(["--turbo-speed", "99"])
|
|
104
|
+
assert_equal 4, opts[:turbo_speed]
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def test_locale
|
|
108
|
+
opts = parse(["--locale", "ja"])
|
|
109
|
+
assert_equal "ja", opts[:locale]
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def test_version_flag
|
|
113
|
+
opts = parse(["--version"])
|
|
114
|
+
assert opts[:version]
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def test_help_flag
|
|
118
|
+
opts = parse(["--help"])
|
|
119
|
+
assert opts[:help]
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# -- combinations --
|
|
123
|
+
|
|
124
|
+
def test_flags_with_rom
|
|
125
|
+
opts = parse(["-s", "2", "--mute", "pokemon.gba"])
|
|
126
|
+
assert_equal 2, opts[:scale]
|
|
127
|
+
assert opts[:mute]
|
|
128
|
+
assert_equal File.expand_path("pokemon.gba"), opts[:rom]
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def test_rom_before_flags
|
|
132
|
+
opts = parse(["game.gba", "--scale", "4"])
|
|
133
|
+
assert_equal File.expand_path("game.gba"), opts[:rom]
|
|
134
|
+
assert_equal 4, opts[:scale]
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# -- parser included for help output --
|
|
138
|
+
|
|
139
|
+
def test_parser_present
|
|
140
|
+
opts = parse([])
|
|
141
|
+
assert_kind_of OptionParser, opts[:parser]
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def test_help_output_includes_banner
|
|
145
|
+
opts = parse([])
|
|
146
|
+
help = opts[:parser].to_s
|
|
147
|
+
assert_includes help, "Usage: gemba"
|
|
148
|
+
assert_includes help, "GBA emulator"
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def test_help_lists_subcommands
|
|
152
|
+
opts = parse([])
|
|
153
|
+
help = opts[:parser].to_s
|
|
154
|
+
assert_includes help, "record"
|
|
155
|
+
assert_includes help, "decode"
|
|
156
|
+
assert_includes help, "info"
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# -- apply --
|
|
160
|
+
|
|
161
|
+
class MockConfig
|
|
162
|
+
attr_accessor :scale, :volume, :muted, :show_fps, :turbo_speed, :locale
|
|
163
|
+
|
|
164
|
+
def initialize
|
|
165
|
+
@scale = 3
|
|
166
|
+
@volume = 100
|
|
167
|
+
@muted = false
|
|
168
|
+
@show_fps = false
|
|
169
|
+
@turbo_speed = 0
|
|
170
|
+
@locale = 'auto'
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def test_apply_overrides_config
|
|
175
|
+
config = MockConfig.new
|
|
176
|
+
Gemba::CLI.apply(config, { scale: 2, volume: 50, mute: true, show_fps: true })
|
|
177
|
+
assert_equal 2, config.scale
|
|
178
|
+
assert_equal 50, config.volume
|
|
179
|
+
assert config.muted
|
|
180
|
+
assert config.show_fps
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def test_apply_skips_unset_options
|
|
184
|
+
config = MockConfig.new
|
|
185
|
+
Gemba::CLI.apply(config, {})
|
|
186
|
+
assert_equal 3, config.scale
|
|
187
|
+
assert_equal 100, config.volume
|
|
188
|
+
refute config.muted
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def test_apply_locale
|
|
192
|
+
config = MockConfig.new
|
|
193
|
+
Gemba::CLI.apply(config, { locale: 'ja' })
|
|
194
|
+
assert_equal 'ja', config.locale
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def test_apply_turbo_speed
|
|
198
|
+
config = MockConfig.new
|
|
199
|
+
Gemba::CLI.apply(config, { turbo_speed: 3 })
|
|
200
|
+
assert_equal 3, config.turbo_speed
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
# -- subcommand dispatch --
|
|
204
|
+
|
|
205
|
+
def test_subcommands_constant
|
|
206
|
+
assert_includes Gemba::CLI::SUBCOMMANDS, 'record'
|
|
207
|
+
assert_includes Gemba::CLI::SUBCOMMANDS, 'decode'
|
|
208
|
+
assert_includes Gemba::CLI::SUBCOMMANDS, 'info'
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# -- record subcommand parsing --
|
|
212
|
+
|
|
213
|
+
def test_parse_record_frames_and_rom
|
|
214
|
+
opts = Gemba::CLI.parse_record(["--frames", "100", "game.gba"])
|
|
215
|
+
assert_equal 100, opts[:frames]
|
|
216
|
+
assert_equal File.expand_path("game.gba"), opts[:rom]
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def test_parse_record_output
|
|
220
|
+
opts = Gemba::CLI.parse_record(["-o", "out.grec", "--frames", "10", "game.gba"])
|
|
221
|
+
assert_equal "out.grec", opts[:output]
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def test_parse_record_help
|
|
225
|
+
opts = Gemba::CLI.parse_record(["--help"])
|
|
226
|
+
assert opts[:help]
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
# -- decode subcommand parsing --
|
|
230
|
+
|
|
231
|
+
def test_parse_decode_trec
|
|
232
|
+
opts = Gemba::CLI.parse_decode(["recording.grec"])
|
|
233
|
+
assert_equal "recording.grec", opts[:trec]
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
def test_parse_decode_output
|
|
237
|
+
opts = Gemba::CLI.parse_decode(["-o", "out.mkv", "recording.grec"])
|
|
238
|
+
assert_equal "out.mkv", opts[:output]
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def test_parse_decode_codecs
|
|
242
|
+
opts = Gemba::CLI.parse_decode(["--video-codec", "libx265", "--audio-codec", "opus", "r.grec"])
|
|
243
|
+
assert_equal "libx265", opts[:video_codec]
|
|
244
|
+
assert_equal "opus", opts[:audio_codec]
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
# -- misc --
|
|
248
|
+
|
|
249
|
+
def test_reset_config_flag
|
|
250
|
+
opts = parse(["--reset-config"])
|
|
251
|
+
assert opts[:reset_config]
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
def test_yes_flag
|
|
255
|
+
opts = parse(["-y"])
|
|
256
|
+
assert opts[:yes]
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
def test_frames
|
|
260
|
+
opts = parse(["--frames", "100", "game.gba"])
|
|
261
|
+
assert_equal 100, opts[:frames]
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
def test_frames_without_value_raises
|
|
265
|
+
assert_raises(OptionParser::MissingArgument) { parse(["--frames"]) }
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
def test_frames_without_rom_exits
|
|
269
|
+
assert_raises(SystemExit) do
|
|
270
|
+
Gemba::CLI.run(["--frames", "100"])
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
def test_unknown_flag_raises
|
|
275
|
+
assert_raises(OptionParser::InvalidOption) { parse(["--bogus"]) }
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
def test_missing_scale_value_raises
|
|
279
|
+
assert_raises(OptionParser::MissingArgument) { parse(["--scale"]) }
|
|
280
|
+
end
|
|
281
|
+
end
|