gemba 0.1.1 → 0.2.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/THIRD_PARTY_NOTICES +37 -2
- data/assets/placeholder_boxart.png +0 -0
- data/bin/gemba +2 -2
- data/ext/gemba/extconf.rb +23 -1
- data/ext/gemba/gemba_ext.c +436 -2
- data/ext/gemba/gemba_ext.h +2 -0
- data/gemba.gemspec +5 -3
- data/lib/gemba/achievements/achievement.rb +23 -0
- data/lib/gemba/achievements/backend.rb +186 -0
- data/lib/gemba/achievements/cache.rb +70 -0
- data/lib/gemba/achievements/credentials_presenter.rb +142 -0
- data/lib/gemba/achievements/fake_backend.rb +205 -0
- data/lib/gemba/achievements/null_backend.rb +11 -0
- data/lib/gemba/achievements/offline_backend.rb +168 -0
- data/lib/gemba/achievements/retro_achievements/backend.rb +453 -0
- data/lib/gemba/achievements/retro_achievements/cli_sync_requester.rb +64 -0
- data/lib/gemba/achievements/retro_achievements/ping_worker.rb +27 -0
- data/lib/gemba/achievements.rb +19 -0
- data/lib/gemba/achievements_window.rb +556 -0
- data/lib/gemba/app_controller.rb +1015 -0
- data/lib/gemba/bios.rb +54 -0
- data/lib/gemba/boxart_fetcher/libretro_backend.rb +39 -0
- data/lib/gemba/boxart_fetcher/null_backend.rb +12 -0
- data/lib/gemba/boxart_fetcher.rb +79 -0
- data/lib/gemba/bus_emitter.rb +13 -0
- data/lib/gemba/child_window.rb +24 -1
- data/lib/gemba/cli/commands/config_cmd.rb +83 -0
- data/lib/gemba/cli/commands/decode.rb +154 -0
- data/lib/gemba/cli/commands/patch.rb +78 -0
- data/lib/gemba/cli/commands/play.rb +78 -0
- data/lib/gemba/cli/commands/record.rb +114 -0
- data/lib/gemba/cli/commands/replay.rb +161 -0
- data/lib/gemba/cli/commands/retro_achievements.rb +213 -0
- data/lib/gemba/cli/commands/version.rb +22 -0
- data/lib/gemba/cli.rb +52 -364
- data/lib/gemba/config.rb +134 -1
- data/lib/gemba/data/gb_games.json +1 -0
- data/lib/gemba/data/gb_md5.json +1 -0
- data/lib/gemba/data/gba_games.json +1 -0
- data/lib/gemba/data/gba_md5.json +1 -0
- data/lib/gemba/data/gbc_games.json +1 -0
- data/lib/gemba/data/gbc_md5.json +1 -0
- data/lib/gemba/emulator_frame.rb +1060 -0
- data/lib/gemba/event_bus.rb +48 -0
- data/lib/gemba/frame_stack.rb +60 -0
- data/lib/gemba/game_index.rb +84 -0
- data/lib/gemba/game_picker_frame.rb +268 -0
- data/lib/gemba/gamepad_map.rb +103 -0
- data/lib/gemba/headless.rb +6 -5
- data/lib/gemba/headless_player.rb +33 -3
- data/lib/gemba/help_window.rb +61 -0
- data/lib/gemba/hotkey_map.rb +3 -1
- data/lib/gemba/input_recorder.rb +107 -0
- data/lib/gemba/input_replayer.rb +119 -0
- data/lib/gemba/keyboard_map.rb +90 -0
- data/lib/gemba/locales/en.yml +97 -5
- data/lib/gemba/locales/ja.yml +97 -5
- data/lib/gemba/main_window.rb +56 -0
- data/lib/gemba/modal_stack.rb +81 -0
- data/lib/gemba/patcher_window.rb +223 -0
- data/lib/gemba/platform/gb.rb +21 -0
- data/lib/gemba/platform/gba.rb +21 -0
- data/lib/gemba/platform/gbc.rb +23 -0
- data/lib/gemba/platform.rb +20 -0
- data/lib/gemba/platform_open.rb +19 -0
- data/lib/gemba/recorder.rb +4 -3
- data/lib/gemba/replay_player.rb +691 -0
- data/lib/gemba/rom_info.rb +57 -0
- data/lib/gemba/rom_info_window.rb +16 -3
- data/lib/gemba/rom_library.rb +106 -0
- data/lib/gemba/rom_overrides.rb +47 -0
- data/lib/gemba/rom_patcher/bps.rb +161 -0
- data/lib/gemba/rom_patcher/ips.rb +101 -0
- data/lib/gemba/rom_patcher/ups.rb +118 -0
- data/lib/gemba/rom_patcher.rb +109 -0
- data/lib/gemba/{rom_loader.rb → rom_resolver.rb} +7 -6
- data/lib/gemba/runtime.rb +59 -26
- data/lib/gemba/save_state_manager.rb +4 -7
- data/lib/gemba/save_state_picker.rb +17 -4
- data/lib/gemba/session_logger.rb +64 -0
- data/lib/gemba/settings/audio_tab.rb +77 -0
- data/lib/gemba/settings/gamepad_tab.rb +351 -0
- data/lib/gemba/settings/hotkeys_tab.rb +259 -0
- data/lib/gemba/settings/paths.rb +11 -0
- data/lib/gemba/settings/recording_tab.rb +83 -0
- data/lib/gemba/settings/save_states_tab.rb +91 -0
- data/lib/gemba/settings/system_tab.rb +362 -0
- data/lib/gemba/settings/video_tab.rb +318 -0
- data/lib/gemba/settings_window.rb +162 -1036
- data/lib/gemba/version.rb +1 -1
- data/lib/gemba/virtual_keyboard.rb +19 -0
- data/lib/gemba.rb +2 -12
- data/test/achievements_window/test_bulk_sync.rb +218 -0
- data/test/achievements_window/test_bus_events.rb +125 -0
- data/test/achievements_window/test_close_confirmation.rb +201 -0
- data/test/achievements_window/test_initial_state.rb +164 -0
- data/test/achievements_window/test_sorting.rb +227 -0
- data/test/achievements_window/test_tree_rendering.rb +133 -0
- data/test/fixtures/fake_bios.bin +0 -0
- data/test/fixtures/pong.gba +0 -0
- data/test/fixtures/test.gb +0 -0
- data/test/fixtures/test.gbc +0 -0
- data/test/fixtures/test_quicksave.ss +0 -0
- data/test/screenshots/no_focus.png +0 -0
- data/test/shared/teek_test_worker.rb +17 -1
- data/test/shared/tk_test_helper.rb +91 -4
- data/test/support/achievements_window_helpers.rb +18 -0
- data/test/support/fake_core.rb +25 -0
- data/test/support/fake_ra_runtime.rb +74 -0
- data/test/support/fake_requester.rb +68 -0
- data/test/support/player_helpers.rb +20 -5
- data/test/test_achievement.rb +32 -0
- data/test/{test_player.rb → test_app_controller.rb} +353 -85
- data/test/test_bios.rb +123 -0
- data/test/test_boxart_fetcher.rb +150 -0
- data/test/test_cli.rb +17 -265
- data/test/test_cli_config.rb +64 -0
- data/test/test_cli_decode.rb +97 -0
- data/test/test_cli_patch.rb +58 -0
- data/test/test_cli_play.rb +213 -0
- data/test/test_cli_ra.rb +175 -0
- data/test/test_cli_record.rb +69 -0
- data/test/test_cli_replay.rb +72 -0
- data/test/test_cli_sync_requester.rb +152 -0
- data/test/test_cli_version.rb +27 -0
- data/test/test_config.rb +2 -3
- data/test/test_config_ra.rb +69 -0
- data/test/test_core.rb +62 -1
- data/test/test_credentials_presenter.rb +192 -0
- data/test/test_event_bus.rb +100 -0
- data/test/test_fake_backend_achievements.rb +130 -0
- data/test/test_fake_backend_auth.rb +68 -0
- data/test/test_game_index.rb +77 -0
- data/test/test_game_picker_frame.rb +310 -0
- data/test/test_gamepad_map.rb +1 -3
- data/test/test_headless_player.rb +17 -3
- data/test/test_help_window.rb +82 -0
- data/test/test_hotkey_map.rb +22 -1
- data/test/test_input_recorder.rb +179 -0
- data/test/test_input_replay_determinism.rb +113 -0
- data/test/test_input_replayer.rb +162 -0
- data/test/test_keyboard_map.rb +1 -3
- data/test/test_libretro_backend.rb +41 -0
- data/test/test_locale.rb +1 -1
- data/test/test_logging.rb +123 -0
- data/test/test_null_backend.rb +42 -0
- data/test/test_offline_backend.rb +116 -0
- data/test/test_overlay_renderer.rb +1 -1
- data/test/test_platform.rb +149 -0
- data/test/test_ra_backend.rb +313 -0
- data/test/test_ra_backend_unlock_gate.rb +56 -0
- data/test/test_recorder.rb +0 -3
- data/test/test_replay_player.rb +316 -0
- data/test/test_rom_info.rb +149 -0
- data/test/test_rom_overrides.rb +86 -0
- data/test/test_rom_patcher.rb +382 -0
- data/test/{test_rom_loader.rb → test_rom_resolver.rb} +25 -26
- data/test/test_save_state_manager.rb +2 -4
- data/test/test_settings_audio.rb +107 -0
- data/test/test_settings_hotkeys.rb +83 -66
- data/test/test_settings_recording.rb +49 -0
- data/test/test_settings_save_states.rb +97 -0
- data/test/test_settings_system.rb +133 -0
- data/test/test_settings_video.rb +450 -0
- data/test/test_settings_window.rb +76 -507
- data/test/test_tip_service.rb +6 -6
- data/test/test_toast_overlay.rb +1 -1
- data/test/test_virtual_events.rb +156 -0
- data/test/test_virtual_keyboard.rb +1 -1
- data/vendor/rcheevos/CHANGELOG.md +495 -0
- data/vendor/rcheevos/LICENSE +21 -0
- data/vendor/rcheevos/Package.swift +33 -0
- data/vendor/rcheevos/README.md +67 -0
- data/vendor/rcheevos/include/module.modulemap +70 -0
- data/vendor/rcheevos/include/rc_api_editor.h +296 -0
- data/vendor/rcheevos/include/rc_api_info.h +280 -0
- data/vendor/rcheevos/include/rc_api_request.h +77 -0
- data/vendor/rcheevos/include/rc_api_runtime.h +417 -0
- data/vendor/rcheevos/include/rc_api_user.h +262 -0
- data/vendor/rcheevos/include/rc_client.h +877 -0
- data/vendor/rcheevos/include/rc_client_raintegration.h +101 -0
- data/vendor/rcheevos/include/rc_consoles.h +138 -0
- data/vendor/rcheevos/include/rc_error.h +59 -0
- data/vendor/rcheevos/include/rc_export.h +100 -0
- data/vendor/rcheevos/include/rc_hash.h +200 -0
- data/vendor/rcheevos/include/rc_runtime.h +148 -0
- data/vendor/rcheevos/include/rc_runtime_types.h +452 -0
- data/vendor/rcheevos/include/rc_util.h +51 -0
- data/vendor/rcheevos/include/rcheevos.h +8 -0
- data/vendor/rcheevos/src/rapi/rc_api_common.c +1379 -0
- data/vendor/rcheevos/src/rapi/rc_api_common.h +88 -0
- data/vendor/rcheevos/src/rapi/rc_api_editor.c +625 -0
- data/vendor/rcheevos/src/rapi/rc_api_info.c +587 -0
- data/vendor/rcheevos/src/rapi/rc_api_runtime.c +901 -0
- data/vendor/rcheevos/src/rapi/rc_api_user.c +483 -0
- data/vendor/rcheevos/src/rc_client.c +6941 -0
- data/vendor/rcheevos/src/rc_client_external.c +281 -0
- data/vendor/rcheevos/src/rc_client_external.h +177 -0
- data/vendor/rcheevos/src/rc_client_external_versions.h +171 -0
- data/vendor/rcheevos/src/rc_client_internal.h +409 -0
- data/vendor/rcheevos/src/rc_client_raintegration.c +566 -0
- data/vendor/rcheevos/src/rc_client_raintegration_internal.h +61 -0
- data/vendor/rcheevos/src/rc_client_types.natvis +396 -0
- data/vendor/rcheevos/src/rc_compat.c +251 -0
- data/vendor/rcheevos/src/rc_compat.h +121 -0
- data/vendor/rcheevos/src/rc_libretro.c +915 -0
- data/vendor/rcheevos/src/rc_libretro.h +98 -0
- data/vendor/rcheevos/src/rc_util.c +199 -0
- data/vendor/rcheevos/src/rc_version.c +11 -0
- data/vendor/rcheevos/src/rc_version.h +32 -0
- data/vendor/rcheevos/src/rcheevos/alloc.c +312 -0
- data/vendor/rcheevos/src/rcheevos/condition.c +754 -0
- data/vendor/rcheevos/src/rcheevos/condset.c +777 -0
- data/vendor/rcheevos/src/rcheevos/consoleinfo.c +1215 -0
- data/vendor/rcheevos/src/rcheevos/format.c +330 -0
- data/vendor/rcheevos/src/rcheevos/lboard.c +287 -0
- data/vendor/rcheevos/src/rcheevos/memref.c +805 -0
- data/vendor/rcheevos/src/rcheevos/operand.c +607 -0
- data/vendor/rcheevos/src/rcheevos/rc_internal.h +390 -0
- data/vendor/rcheevos/src/rcheevos/rc_runtime_types.natvis +541 -0
- data/vendor/rcheevos/src/rcheevos/rc_validate.c +1406 -0
- data/vendor/rcheevos/src/rcheevos/rc_validate.h +18 -0
- data/vendor/rcheevos/src/rcheevos/richpresence.c +922 -0
- data/vendor/rcheevos/src/rcheevos/runtime.c +852 -0
- data/vendor/rcheevos/src/rcheevos/runtime_progress.c +1073 -0
- data/vendor/rcheevos/src/rcheevos/trigger.c +344 -0
- data/vendor/rcheevos/src/rcheevos/value.c +935 -0
- data/vendor/rcheevos/src/rhash/aes.c +480 -0
- data/vendor/rcheevos/src/rhash/aes.h +49 -0
- data/vendor/rcheevos/src/rhash/cdreader.c +838 -0
- data/vendor/rcheevos/src/rhash/hash.c +1402 -0
- data/vendor/rcheevos/src/rhash/hash_disc.c +1340 -0
- data/vendor/rcheevos/src/rhash/hash_encrypted.c +566 -0
- data/vendor/rcheevos/src/rhash/hash_rom.c +426 -0
- data/vendor/rcheevos/src/rhash/hash_zip.c +460 -0
- data/vendor/rcheevos/src/rhash/md5.c +382 -0
- data/vendor/rcheevos/src/rhash/md5.h +91 -0
- data/vendor/rcheevos/src/rhash/rc_hash_internal.h +116 -0
- data/vendor/rcheevos/test/libretro.h +205 -0
- data/vendor/rcheevos/test/rapi/test_rc_api_common.c +941 -0
- data/vendor/rcheevos/test/rapi/test_rc_api_editor.c +931 -0
- data/vendor/rcheevos/test/rapi/test_rc_api_info.c +545 -0
- data/vendor/rcheevos/test/rapi/test_rc_api_runtime.c +2213 -0
- data/vendor/rcheevos/test/rapi/test_rc_api_user.c +998 -0
- data/vendor/rcheevos/test/rcheevos/mock_memory.h +32 -0
- data/vendor/rcheevos/test/rcheevos/test_condition.c +570 -0
- data/vendor/rcheevos/test/rcheevos/test_condset.c +5170 -0
- data/vendor/rcheevos/test/rcheevos/test_consoleinfo.c +203 -0
- data/vendor/rcheevos/test/rcheevos/test_format.c +112 -0
- data/vendor/rcheevos/test/rcheevos/test_lboard.c +746 -0
- data/vendor/rcheevos/test/rcheevos/test_memref.c +520 -0
- data/vendor/rcheevos/test/rcheevos/test_operand.c +692 -0
- data/vendor/rcheevos/test/rcheevos/test_rc_validate.c +502 -0
- data/vendor/rcheevos/test/rcheevos/test_richpresence.c +1564 -0
- data/vendor/rcheevos/test/rcheevos/test_runtime.c +1667 -0
- data/vendor/rcheevos/test/rcheevos/test_runtime_progress.c +1821 -0
- data/vendor/rcheevos/test/rcheevos/test_timing.c +166 -0
- data/vendor/rcheevos/test/rcheevos/test_trigger.c +2521 -0
- data/vendor/rcheevos/test/rcheevos/test_value.c +870 -0
- data/vendor/rcheevos/test/rcheevos-test.sln +46 -0
- data/vendor/rcheevos/test/rcheevos-test.vcxproj +239 -0
- data/vendor/rcheevos/test/rcheevos-test.vcxproj.filters +335 -0
- data/vendor/rcheevos/test/rhash/data.c +657 -0
- data/vendor/rcheevos/test/rhash/data.h +32 -0
- data/vendor/rcheevos/test/rhash/mock_filereader.c +236 -0
- data/vendor/rcheevos/test/rhash/mock_filereader.h +31 -0
- data/vendor/rcheevos/test/rhash/test_cdreader.c +920 -0
- data/vendor/rcheevos/test/rhash/test_hash.c +310 -0
- data/vendor/rcheevos/test/rhash/test_hash_disc.c +1450 -0
- data/vendor/rcheevos/test/rhash/test_hash_rom.c +899 -0
- data/vendor/rcheevos/test/rhash/test_hash_zip.c +551 -0
- data/vendor/rcheevos/test/test.c +113 -0
- data/vendor/rcheevos/test/test_framework.h +205 -0
- data/vendor/rcheevos/test/test_rc_client.c +10509 -0
- data/vendor/rcheevos/test/test_rc_client_external.c +2197 -0
- data/vendor/rcheevos/test/test_rc_client_raintegration.c +441 -0
- data/vendor/rcheevos/test/test_rc_libretro.c +952 -0
- data/vendor/rcheevos/test/test_types.natvis +9 -0
- data/vendor/rcheevos/validator/validator.c +658 -0
- data/vendor/rcheevos/validator/validator.vcxproj +152 -0
- data/vendor/rcheevos/validator/validator.vcxproj.filters +82 -0
- metadata +274 -11
- data/lib/gemba/input_mappings.rb +0 -214
- data/lib/gemba/player.rb +0 -1525
data/test/test_tip_service.rb
CHANGED
|
@@ -8,7 +8,7 @@ class TestTipService < Minitest::Test
|
|
|
8
8
|
|
|
9
9
|
def test_register_sets_underline_font
|
|
10
10
|
assert_tk_app("register sets underlined font") do
|
|
11
|
-
require "gemba/
|
|
11
|
+
require "gemba/headless"
|
|
12
12
|
tips = Gemba::TipService.new(app)
|
|
13
13
|
|
|
14
14
|
lbl = ".test_lbl"
|
|
@@ -27,7 +27,7 @@ class TestTipService < Minitest::Test
|
|
|
27
27
|
|
|
28
28
|
def test_show_creates_tooltip
|
|
29
29
|
assert_tk_app("show creates a tooltip toplevel") do
|
|
30
|
-
require "gemba/
|
|
30
|
+
require "gemba/headless"
|
|
31
31
|
tips = Gemba::TipService.new(app)
|
|
32
32
|
|
|
33
33
|
lbl = ".test_lbl"
|
|
@@ -47,7 +47,7 @@ class TestTipService < Minitest::Test
|
|
|
47
47
|
|
|
48
48
|
def test_hide_destroys_tooltip
|
|
49
49
|
assert_tk_app("hide destroys tooltip") do
|
|
50
|
-
require "gemba/
|
|
50
|
+
require "gemba/headless"
|
|
51
51
|
tips = Gemba::TipService.new(app)
|
|
52
52
|
|
|
53
53
|
lbl = ".test_lbl"
|
|
@@ -69,7 +69,7 @@ class TestTipService < Minitest::Test
|
|
|
69
69
|
|
|
70
70
|
def test_toggle_behavior
|
|
71
71
|
assert_tk_app("clicking same label toggles tooltip") do
|
|
72
|
-
require "gemba/
|
|
72
|
+
require "gemba/headless"
|
|
73
73
|
tips = Gemba::TipService.new(app)
|
|
74
74
|
|
|
75
75
|
lbl = ".test_lbl"
|
|
@@ -96,7 +96,7 @@ class TestTipService < Minitest::Test
|
|
|
96
96
|
|
|
97
97
|
def test_only_one_tooltip_at_a_time
|
|
98
98
|
assert_tk_app("showing a second tooltip hides the first") do
|
|
99
|
-
require "gemba/
|
|
99
|
+
require "gemba/headless"
|
|
100
100
|
tips = Gemba::TipService.new(app)
|
|
101
101
|
|
|
102
102
|
lbl1 = ".test_lbl1"
|
|
@@ -126,7 +126,7 @@ class TestTipService < Minitest::Test
|
|
|
126
126
|
|
|
127
127
|
def test_dismiss_ms_is_configurable
|
|
128
128
|
assert_tk_app("dismiss_ms is configurable") do
|
|
129
|
-
require "gemba/
|
|
129
|
+
require "gemba/headless"
|
|
130
130
|
tips = Gemba::TipService.new(app, dismiss_ms: 2000)
|
|
131
131
|
|
|
132
132
|
assert_equal 2000, tips.dismiss_ms
|
data/test/test_toast_overlay.rb
CHANGED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "minitest/autorun"
|
|
4
|
+
require_relative "shared/tk_test_helper"
|
|
5
|
+
require "gemba"
|
|
6
|
+
|
|
7
|
+
# Tests for the virtual event layer.
|
|
8
|
+
#
|
|
9
|
+
# Physical key → virtual event translation is one line per action; the
|
|
10
|
+
# interesting thing to test is that the virtual event bindings on '.'
|
|
11
|
+
# actually fire when triggered directly (no focus needed).
|
|
12
|
+
#
|
|
13
|
+
# assert_virtual_event_fires runs a subprocess that:
|
|
14
|
+
# 1. Appends {+lappend ::virt_fired EventName} to the binding on '.'
|
|
15
|
+
# 2. Generates the virtual event from an after(50) callback
|
|
16
|
+
# 3. In an after(0) reads ::virt_fired and prints EVENTNAME_FIRED
|
|
17
|
+
# 4. Quits via <<Quit>> (or player.running = false for no-ROM cases)
|
|
18
|
+
#
|
|
19
|
+
# <<Quit>> is special — its original binding stops the mainloop before
|
|
20
|
+
# after(0) can run, so it prints synchronously inside the appended binding.
|
|
21
|
+
class TestVirtualEvents < Minitest::Test
|
|
22
|
+
include TeekTestHelper
|
|
23
|
+
|
|
24
|
+
TEST_ROM = File.expand_path("fixtures/test.gba", __dir__)
|
|
25
|
+
|
|
26
|
+
# ── Key → action mapping (pure unit tests, no subprocess) ─────────────────
|
|
27
|
+
|
|
28
|
+
def test_default_quit_key_maps_to_quit_action
|
|
29
|
+
assert_equal :quit, Gemba::HotkeyMap.new(Gemba::Config.new).action_for('q')
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def test_default_quick_save_key_maps_to_quick_save_action
|
|
33
|
+
assert_equal :quick_save, Gemba::HotkeyMap.new(Gemba::Config.new).action_for('F5')
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def test_default_quick_load_key_maps_to_quick_load_action
|
|
37
|
+
assert_equal :quick_load, Gemba::HotkeyMap.new(Gemba::Config.new).action_for('F8')
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def test_default_record_key_maps_to_record_action
|
|
41
|
+
assert_equal :record, Gemba::HotkeyMap.new(Gemba::Config.new).action_for('F10')
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# ── Virtual event bindings (subprocess, no physical keypresses) ────────────
|
|
45
|
+
|
|
46
|
+
def test_quit_virtual_event_fires_binding
|
|
47
|
+
# <<Quit>> stops the mainloop before after(0) runs — print synchronously
|
|
48
|
+
# inside the appended binding instead.
|
|
49
|
+
code = <<~RUBY
|
|
50
|
+
require "gemba"
|
|
51
|
+
require "support/player_helpers"
|
|
52
|
+
|
|
53
|
+
player = Gemba::AppController.new("#{TEST_ROM}")
|
|
54
|
+
player.disable_confirmations!
|
|
55
|
+
app = player.app
|
|
56
|
+
|
|
57
|
+
poll_until_ready(player) do
|
|
58
|
+
app.tcl_eval('bind . <<Quit>> {+puts QUIT_FIRED; flush stdout}')
|
|
59
|
+
app.after(50) { app.command(:event, 'generate', '.', '<<Quit>>') }
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
player.run
|
|
63
|
+
RUBY
|
|
64
|
+
|
|
65
|
+
_, stdout, stderr, _ = tk_subprocess(code)
|
|
66
|
+
output = ["STDOUT:\n#{stdout}", "STDERR:\n#{stderr}"].reject { |s| s.end_with?("\n") }
|
|
67
|
+
assert_includes stdout, "QUIT_FIRED", "<<Quit>> binding did not fire\n#{output.join("\n")}"
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def test_quick_save_virtual_event_fires_binding
|
|
71
|
+
assert_virtual_event_fires('QuickSave',
|
|
72
|
+
setup_code: 'player.config.states_dir = Dir.mktmpdir("gemba-virt-test")',
|
|
73
|
+
cleanup_code: 'FileUtils.rm_rf(player.config.states_dir)')
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def test_quick_load_virtual_event_fires_binding
|
|
77
|
+
assert_virtual_event_fires('QuickLoad')
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def test_record_toggle_virtual_event_fires_binding
|
|
81
|
+
assert_virtual_event_fires('RecordToggle',
|
|
82
|
+
setup_code: 'player.config.recordings_dir = Dir.mktmpdir("gemba-virt-rec")',
|
|
83
|
+
cleanup_code: 'FileUtils.rm_rf(player.config.recordings_dir)')
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def test_toggle_help_window_virtual_event_fires_binding
|
|
87
|
+
assert_virtual_event_fires('ToggleHelpWindow', with_rom: false)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
private
|
|
91
|
+
|
|
92
|
+
# Verifies that generating <<EventName>> on '.' fires the binding.
|
|
93
|
+
# Uses lappend ::virt_fired as a Tcl side-channel — no physical keypresses.
|
|
94
|
+
#
|
|
95
|
+
# Options:
|
|
96
|
+
# with_rom: load TEST_ROM (default true; false for no-ROM app controller)
|
|
97
|
+
# setup_code: Ruby injected after player/app created, before poll_until_ready
|
|
98
|
+
# cleanup_code: Ruby injected in after(0) before quitting
|
|
99
|
+
def assert_virtual_event_fires(event_name, with_rom: true, setup_code: '', cleanup_code: '')
|
|
100
|
+
marker = "#{event_name.upcase.tr('-', '_')}_FIRED"
|
|
101
|
+
|
|
102
|
+
if with_rom
|
|
103
|
+
code = <<~RUBY
|
|
104
|
+
require "gemba"
|
|
105
|
+
require "support/player_helpers"
|
|
106
|
+
require "tmpdir"
|
|
107
|
+
require "fileutils"
|
|
108
|
+
|
|
109
|
+
player = Gemba::AppController.new("#{TEST_ROM}")
|
|
110
|
+
player.disable_confirmations!
|
|
111
|
+
app = player.app
|
|
112
|
+
#{setup_code}
|
|
113
|
+
|
|
114
|
+
poll_until_ready(player) do
|
|
115
|
+
app.tcl_eval('bind . <<#{event_name}>> {+lappend ::virt_fired #{event_name}}')
|
|
116
|
+
app.after(50) do
|
|
117
|
+
app.command(:event, 'generate', '.', '<<#{event_name}>>')
|
|
118
|
+
app.after(0) do
|
|
119
|
+
fired = app.tcl_eval('lsearch -exact $::virt_fired #{event_name}') rescue "-1"
|
|
120
|
+
puts fired.to_i >= 0 ? "#{marker}" : "NOT_FIRED"
|
|
121
|
+
#{cleanup_code}
|
|
122
|
+
app.command(:event, 'generate', '.', '<<Quit>>')
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
player.run
|
|
128
|
+
RUBY
|
|
129
|
+
else
|
|
130
|
+
code = <<~RUBY
|
|
131
|
+
require "gemba"
|
|
132
|
+
|
|
133
|
+
player = Gemba::AppController.new
|
|
134
|
+
app = player.app
|
|
135
|
+
#{setup_code}
|
|
136
|
+
|
|
137
|
+
app.tcl_eval('bind . <<#{event_name}>> {+lappend ::virt_fired #{event_name}}')
|
|
138
|
+
app.after(50) do
|
|
139
|
+
app.command(:event, 'generate', '.', '<<#{event_name}>>')
|
|
140
|
+
app.after(0) do
|
|
141
|
+
fired = app.tcl_eval('lsearch -exact $::virt_fired #{event_name}') rescue "-1"
|
|
142
|
+
puts fired.to_i >= 0 ? "#{marker}" : "NOT_FIRED"
|
|
143
|
+
#{cleanup_code}
|
|
144
|
+
player.running = false
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
player.run
|
|
149
|
+
RUBY
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
_, stdout, stderr, _ = tk_subprocess(code)
|
|
153
|
+
output = ["STDOUT:\n#{stdout}", "STDERR:\n#{stderr}"].reject { |s| s.end_with?("\n") }
|
|
154
|
+
assert_includes stdout, marker, "<<#{event_name}>> binding did not fire\n#{output.join("\n")}"
|
|
155
|
+
end
|
|
156
|
+
end
|