Replace the broken test suite with working GdUnit4 tests

The previous tests never compiled: they used GUT's assert functions,
Godot 3 APIs and reassigned autoload functions, so no test ran.

- 90 tests: unit tests for the playlist, songs, player scoring, time
  formatting, search and the server client, plus integration tests
  that run MainWindow and SyncWindow against a fake server
- Keybind tests check that Alt+<number> and Ctrl+Alt+<number> keep
  following the player rows while players are added and removed
- run_tests.sh finds Godot and runs the suite headless (~10 seconds)
- CI runs the tests before the build job in gitea-build.yaml; the
  separate test.yml used a GitHub action that does not exist
- GdUnit4 is committed instead of ignored, since the project enables
  it, and .gitea/ is no longer ignored
- Exported builds leave out tests/ and addons/gdUnit4/
This commit is contained in:
Sansan committed 2026-10-06 08:32:56 +02:00
1 parent 56e9fe66d3
commit c985a6ce5b
559 files changed
+32474 -2100

No files matched your search

-26
View File
@@ -1,26 +0,0 @@
class_name BasicTest
extends GdUnitTestSuite
func test_true_is_true():
assert_true(true)
func test_false_is_false():
assert_false(false)
func test_one_equals_one():
assert_eq(1, 1)
func test_arrays_work():
var arr = [1, 2, 3]
assert_eq(arr.size(), 3)
assert_eq(arr[0], 1)
func test_dictionaries_work():
var dict = {"key": "value", "number": 42}
assert_eq(dict["key"], "value")
assert_eq(dict["number"], 42)
-357
View File
@@ -1,357 +0,0 @@
class_name MainWindowTest
extends GdUnitTestSuite
func test_next_button_pressed_connects_to_play_next_song():
var main_window = MainWindow.new()
var mock_next_button = mock(Button)
main_window.next_button = mock_next_button
# Connect the signal
main_window._ready()
# Simulate button press
mock_next_button.emit_signal("pressed")
# Verify the connection was made (play_next_song should be callable)
assert_true(main_window.is_connected("next_button", "pressed", main_window, "play_next_song"))
func test_show_answer_button_pressed_connects_to_handler():
var main_window = MainWindow.new()
var mock_show_answer_button = mock(Button)
main_window.show_answer_button = mock_show_answer_button
main_window._ready()
assert_true(main_window.is_connected("show_answer_button", "pressed", main_window, "show_answer_pressed"))
func test_search_button_pressed_connects_to_show_search():
var main_window = MainWindow.new()
var mock_search_button = mock(Button)
main_window.search_button = mock_search_button
main_window._ready()
assert_true(main_window.is_connected("search_button", "pressed", main_window, "show_search"))
func test_sync_button_pressed_connects_to_sync_soundtracks():
var main_window = MainWindow.new()
var mock_sync_button = mock(Button)
main_window.sync_button = mock_sync_button
main_window._ready()
assert_true(main_window.is_connected("sync_button", "pressed", main_window, "sync_soundtracks"))
func test_sound_test_button_pressed_connects_to_get_sound_test_song():
var main_window = MainWindow.new()
var mock_sound_test_button = mock(Button)
var mock_music_player = mock(MusicPlayer)
main_window.sound_test_button = mock_sound_test_button
main_window.music_player_container = mock_music_player
main_window._ready()
assert_true(main_window.is_connected("sound_test_button", "pressed", mock_music_player, "get_sound_test_song"))
func test_settings_button_pressed_connects_to_show_settings():
var main_window = MainWindow.new()
var mock_settings_button = mock(Button)
main_window.settings_button = mock_settings_button
main_window._ready()
assert_true(main_window.is_connected("settings_button", "pressed", main_window, "show_settings"))
func test_reset_playlist_button_pressed_connects_to_reset_playlist():
var main_window = MainWindow.new()
var mock_reset_button = mock(Button)
main_window.reset_playlist_button = mock_reset_button
main_window._ready()
assert_true(main_window.is_connected("reset_playlist_button", "pressed", main_window, "reset_playlist"))
func test_reset_points_button_pressed_connects_to_reset_points():
var main_window = MainWindow.new()
var mock_reset_points_button = mock(Button)
main_window.reset_points_button = mock_reset_points_button
main_window._ready()
assert_true(main_window.is_connected("reset_points_button", "pressed", main_window, "reset_points"))
func test_add_players_button_toggles_visibility():
var main_window = MainWindow.new()
var mock_add_players_button = mock(TextureButton)
var mock_container = mock(HBoxContainer)
main_window.add_players_button = mock_add_players_button
main_window.add_player_container = mock_container
Settings.edit_players = false
mock_container.visible = false
main_window.add_players()
assert_true(Settings.edit_players)
assert_true(mock_container.visible)
main_window.add_players()
assert_false(Settings.edit_players)
assert_false(mock_container.visible)
func test_add_player_adds_to_array():
var main_window = MainWindow.new()
Settings.player_array.clear()
Settings.edit_players = true
var initial_count = Settings.player_array.size()
main_window.new_player_name_field = mock(TextEdit)
main_window.new_player_name_field.text = "Test Player"
main_window.add_player()
assert_eq(Settings.player_array.size(), initial_count + 1)
assert_eq(Settings.player_array[-1].player_name, "Test Player")
func test_add_player_does_not_add_empty_name():
var main_window = MainWindow.new()
Settings.player_array.clear()
Settings.edit_players = true
main_window.new_player_name_field = mock(TextEdit)
main_window.new_player_name_field.text = ""
var initial_count = Settings.player_array.size()
main_window.add_player()
assert_eq(Settings.player_array.size(), initial_count)
func test_add_player_does_not_exceed_max():
var main_window = MainWindow.new()
Settings.player_array.clear()
Settings.edit_players = true
# Fill up to max
for i in range(Settings.MAX_NUMBER_OF_PLAYERS):
var player_obj = PlayerObject.new("Player %d" % i, i)
Settings.player_array.append(player_obj)
main_window.new_player_name_field = mock(TextEdit)
main_window.new_player_name_field.text = "Extra Player"
var initial_count = Settings.player_array.size()
main_window.add_player()
assert_eq(Settings.player_array.size(), initial_count)
func test_show_search_toggles_visibility():
var main_window = MainWindow.new()
var mock_search_view = mock(Control)
main_window.search_view = mock_search_view
mock_search_view.visible = false
main_window.show_search()
assert_true(mock_search_view.visible)
main_window.show_search()
assert_false(mock_search_view.visible)
func test_show_settings_makes_window_visible():
var main_window = MainWindow.new()
var mock_settings_window = mock(Control)
main_window.settings_window = mock_settings_window
mock_settings_window.visible = false
main_window.show_settings()
assert_true(mock_settings_window.visible)
func test_show_qr_calls_show_window():
var main_window = MainWindow.new()
var mock_qr_window = mock(Control)
main_window.qr_window = mock_qr_window
main_window.show_qr()
# Verify show_window was called (mock should track this)
assert_true(mock_qr_window.show_window.was_called())
func test_show_about_makes_window_visible():
var main_window = MainWindow.new()
var mock_about_window = mock(Control)
main_window.about_window = mock_about_window
mock_about_window.visible = false
main_window.show_about()
assert_true(mock_about_window.visible)
func test_get_statistics_shows_popup():
var main_window = MainWindow.new()
var mock_popup = mock(PopupPanel)
var mock_label = mock(Label)
main_window.statistic_popup = mock_popup
main_window.statistic_label = mock_label
main_window.get_statistics()
assert_true(mock_popup.visible)
func test_sync_soundtracks_starts_sync():
var main_window = MainWindow.new()
var mock_sync_window = mock(Control)
main_window.sync_window = mock_sync_window
main_window.sync_soundtracks()
assert_true(mock_sync_window.start_sync.was_called())
func test_reset_playlist_clears_and_refetches():
var main_window = MainWindow.new()
# Mock Settings.make_request2
var original_make_request = Settings.make_request2
var reset_called = false
Settings.make_request2 = func(address: String, func_name: Callable, expect_data: bool) -> void:
if address == "/music/reset":
reset_called = true
func_name.call()
elif address == "/music/list":
func_name.call([])
elif address == "/music/rand":
func_name.call(PackedByteArray())
Playlist.clear_song_list()
Playlist.add_to_playlist(TestHelpers.create_test_song_object(1))
main_window.reset_playlist()
assert_true(reset_called)
Settings.make_request2 = original_make_request
func test_reset_points_resets_all_players():
var main_window = MainWindow.new()
Settings.player_array.clear()
var player1 = PlayerObject.new("Player 1", 0)
var player2 = PlayerObject.new("Player 2", 1)
player1.player_score = 5
player2.player_score = 10
Settings.player_array.append(player1)
Settings.player_array.append(player2)
main_window.reset_points()
assert_eq(player1.player_score, 0)
assert_eq(player2.player_score, 0)
func test_play_next_song_increments_and_plays():
var main_window = MainWindow.new()
var mock_music_player = mock(MusicPlayer)
main_window.music_player_container = mock_music_player
Playlist.clear_song_list()
Playlist.add_to_playlist(TestHelpers.create_test_song_object(1))
Playlist.add_to_playlist(TestHelpers.create_test_song_object(2))
Playlist.latest_played_song = 0
Playlist.first_song_played = true
main_window.play_next_song()
assert_eq(Playlist.latest_played_song, 1)
assert_true(mock_music_player.play_song_object.was_called_with([1]))
func test_song_object_clicked_handles_left_click():
var main_window = MainWindow.new()
var mock_music_player = mock(MusicPlayer)
main_window.music_player_container = mock_music_player
Playlist.clear_song_list()
var song = TestHelpers.create_test_song_object(1)
Playlist.add_to_playlist(song)
var mock_event = mock(InputEventMouseButton)
mock_event.pressed = true
mock_event.button_index = MOUSE_BUTTON_LEFT
main_window.song_object_clicked(mock_event, 0)
assert_true(mock_music_player.play_song_object.was_called_with([0]))
func test_song_object_clicked_downloads_if_not_available():
var main_window = MainWindow.new()
var mock_music_player = mock(MusicPlayer)
main_window.music_player_container = mock_music_player
Playlist.clear_song_list()
var song = TestHelpers.create_test_song_object(1)
song.song = null # No song loaded
Playlist.add_to_playlist(song)
var mock_event = mock(InputEventMouseButton)
mock_event.pressed = true
mock_event.button_index = MOUSE_BUTTON_LEFT
# Mock Settings.make_request2 for download
var original_make_request = Settings.make_request2
var download_called = false
Settings.make_request2 = func(address: String, func_name: Callable, expect_data: bool) -> void:
if address.begins_with("/music?song="):
download_called = true
var test_stream = TestHelpers.create_mock_audio_stream()
func_name.call(test_stream.get_data())
main_window.song_object_clicked(mock_event, 0)
assert_true(download_called)
Settings.make_request2 = original_make_request
-158
View File
@@ -1,158 +0,0 @@
class_name MusicPlayerTest
extends GdUnitTestSuite
func test_play_or_pause_toggles_play_state():
var music_player = MusicPlayer.new()
var mock_audio = mock(AudioStreamPlayer)
var mock_play_button = mock(TextureButton)
music_player.audio_player = mock_audio
music_player.play_button = mock_play_button
music_player.play_icon = load("res://icons/play_icon_light.svg")
music_player.pause_icon = load("res://icons/pause_icon_light.svg")
# Initial state - paused
mock_audio.stream_paused = true
music_player.song_finished = false
# First call should play
music_player.play_or_pause()
assert_false(mock_audio.stream_paused)
assert_eq(mock_play_button.texture_normal, music_player.pause_icon)
# Second call should pause
music_player.play_or_pause()
assert_true(mock_audio.stream_paused)
assert_eq(mock_play_button.texture_normal, music_player.play_icon)
func test_restart_resets_playback():
var music_player = MusicPlayer.new()
var mock_audio = mock(AudioStreamPlayer)
var mock_slider = mock(HSlider)
music_player.audio_player = mock_audio
music_player.progress_slider = mock_slider
mock_audio.stream_paused = false
mock_slider.value = 50.0
music_player.song_finished = true
music_player.restart()
assert_true(mock_audio.stop.was_called())
assert_false(mock_audio.stream_paused)
assert_false(music_player.song_finished)
assert_eq(mock_slider.value, 0)
assert_true(mock_audio.play.was_called())
func test_pause_sets_correct_state():
var music_player = MusicPlayer.new()
var mock_audio = mock(AudioStreamPlayer)
var mock_play_button = mock(TextureButton)
music_player.audio_player = mock_audio
music_player.play_button = mock_play_button
music_player.play_icon = load("res://icons/play_icon_light.svg")
mock_audio.stream_paused = false
music_player.pause()
assert_true(mock_audio.stream_paused)
assert_eq(mock_play_button.texture_normal, music_player.play_icon)
func test_format_time_correctly_formats_seconds():
var music_player = MusicPlayer.new()
assert_eq(music_player.format_time(65.0), "01:05")
assert_eq(music_player.format_time(0.0), "00:00")
assert_eq(music_player.format_time(3661.0), "61:01")
func test_format_text_hides_info_when_configured():
var music_player = MusicPlayer.new()
# Test with hide_beginning and hide_length
Settings.hide_beginning = true
Settings.hide_length = true
Settings.hide_for_seconds = 5.0
assert_eq(music_player.format_text(3.0, 100.0), "??:?? / ??:??")
Settings.hide_beginning = false
Settings.hide_length = true
assert_eq(music_player.format_text(10.0, 100.0), "00:10 / ??:??")
Settings.hide_beginning = true
Settings.hide_length = false
assert_eq(music_player.format_text(3.0, 100.0), "??:?? / 01:40")
Settings.hide_beginning = false
Settings.hide_length = false
assert_eq(music_player.format_text(10.0, 100.0), "00:10 / 01:40")
# Reset
Settings.hide_beginning = false
Settings.hide_length = false
func test_on_drag_started_sets_is_changing():
var music_player = MusicPlayer.new()
assert_false(music_player.is_changing)
music_player._on_drag_started()
assert_true(music_player.is_changing)
func test_on_drag_ended_updates_position():
var music_player = MusicPlayer.new()
var mock_audio = mock(AudioStreamPlayer)
var mock_slider = mock(HSlider)
music_player.audio_player = mock_audio
music_player.progress_slider = mock_slider
mock_slider.value = 30.0
music_player.is_changing = true
music_player._on_drag_ended(true)
assert_false(music_player.is_changing)
assert_true(mock_audio.seek.was_called_with([30.0]))
assert_eq(music_player.playback_position, 30.0)
func test_seek_updates_slider_and_position():
var music_player = MusicPlayer.new()
var mock_audio = mock(AudioStreamPlayer)
var mock_slider = mock(HSlider)
music_player.audio_player = mock_audio
music_player.progress_slider = mock_slider
mock_slider.value = 10.0
music_player.seek(5.0)
assert_eq(mock_slider.value, 15.0)
assert_true(mock_audio.seek.was_called_with([15.0]))
assert_eq(music_player.playback_position, 15.0)
func test_change_volume_updates_slider():
var music_player = MusicPlayer.new()
var mock_slider = mock(HSlider)
music_player.volume_slider = mock_slider
mock_slider.value = 0.5
music_player.change_volume(0.1)
assert_eq(mock_slider.value, 0.6)
assert_true(mock_slider.change_volume.was_called_with([0.6]))
+68
View File
@@ -0,0 +1,68 @@
extends GdUnitTestSuite
var _music_player: MusicPlayer
var _hide_beginning: bool
var _hide_length: bool
var _hide_for_seconds: float
func before_test() -> void:
_music_player = auto_free(MusicPlayer.new())
_hide_beginning = Settings.hide_beginning
_hide_length = Settings.hide_length
_hide_for_seconds = Settings.hide_for_seconds
Settings.hide_beginning = false
Settings.hide_length = false
Settings.hide_for_seconds = 5.0
func after_test() -> void:
Settings.hide_beginning = _hide_beginning
Settings.hide_length = _hide_length
Settings.hide_for_seconds = _hide_for_seconds
func test_format_time() -> void:
assert_str(_music_player.format_time(0.0)).is_equal("00:00")
assert_str(_music_player.format_time(65.0)).is_equal("01:05")
assert_str(_music_player.format_time(3661.0)).is_equal("61:01")
func test_format_time_rounds_up_into_next_minute() -> void:
assert_str(_music_player.format_time(59.6)).is_equal("01:00")
func test_format_text_shows_position_and_length() -> void:
assert_str(_music_player.format_text(10.0, 100.0)).is_equal("00:10 / 01:40")
func test_format_text_hides_length() -> void:
Settings.hide_length = true
assert_str(_music_player.format_text(10.0, 100.0)).is_equal("00:10 / ??:??")
func test_format_text_hides_position_at_start() -> void:
Settings.hide_beginning = true
assert_str(_music_player.format_text(3.0, 100.0)).is_equal("??:?? / 01:40")
func test_format_text_shows_position_after_hidden_start() -> void:
Settings.hide_beginning = true
assert_str(_music_player.format_text(5.0, 100.0)).is_equal("00:05 / 01:40")
func test_format_text_hides_everything_at_start() -> void:
Settings.hide_beginning = true
Settings.hide_length = true
assert_str(_music_player.format_text(3.0, 100.0)).is_equal("??:?? / ??:??")
func test_format_text_keeps_length_hidden_after_hidden_start() -> void:
Settings.hide_beginning = true
Settings.hide_length = true
assert_str(_music_player.format_text(5.0, 100.0)).is_equal("00:05 / ??:??")
+1
View File
@@ -0,0 +1 @@
uid://xoskre03iorg
+113
View File
@@ -0,0 +1,113 @@
extends GdUnitTestSuite
var _server: FakeHttpTransport
func before_test() -> void:
_server = FakeHttpTransport.new().install()
func after_test() -> void:
_server.uninstall()
func test_fetch_song_list_passes_parsed_json() -> void:
var songs: Array = [{"SongNo": 0, "Soundtrack": "Chrono Trigger", "Song": "Corridors of Time"}]
_server.respond_json("/music/list", songs)
var received: Array = []
MusicServerClient.fetch_song_list(func(data: Array) -> void: received.append_array(data))
assert_int(received.size()).is_equal(1)
assert_int(int(received[0].SongNo)).is_equal(0)
assert_str(received[0].Soundtrack).is_equal("Chrono Trigger")
func test_fetch_random_song_uses_normal_endpoint() -> void:
MusicServerClient.fetch_random_song(false, func(_body: PackedByteArray) -> void: pass)
assert_array(_server.requested_paths).contains_exactly(["/music/rand"])
func test_fetch_random_song_uses_low_played_endpoint() -> void:
MusicServerClient.fetch_random_song(true, func(_body: PackedByteArray) -> void: pass)
assert_array(_server.requested_paths).contains_exactly(["/music/rand/low"])
func test_fetch_song_passes_raw_bytes() -> void:
var mp3: PackedByteArray = PackedByteArray([0x49, 0x44, 0x33])
_server.respond_bytes("/music?song=4", mp3)
var received: Array[PackedByteArray] = []
MusicServerClient.fetch_song(4, func(body: PackedByteArray) -> void: received.append(body))
assert_array(received).contains_exactly([mp3])
func test_failed_request_does_not_call_back() -> void:
_server.respond_json("/music/list", [], 500)
var called: Array[bool] = [false]
MusicServerClient.fetch_song_list(func(_data: Variant) -> void: called[0] = true)
assert_bool(called[0]).is_false()
func test_invalid_json_does_not_call_back() -> void:
_server.respond_bytes("/music/info", "not json".to_utf8_buffer())
var called: Array[bool] = [false]
MusicServerClient.fetch_song_info(func(_data: Variant) -> void: called[0] = true)
assert_bool(called[0]).is_false()
func test_send_calls_back_without_arguments() -> void:
_server.respond_bytes("/music/reset", PackedByteArray())
var called: Array[bool] = [false]
MusicServerClient.reset_playlist(func() -> void: called[0] = true)
assert_bool(called[0]).is_true()
func test_mark_song_played_sends_put() -> void:
_server.respond_bytes("/music/played?song=3", PackedByteArray())
MusicServerClient.mark_song_played(3)
assert_array(_server.requested_paths).contains_exactly(["/music/played?song=3"])
assert_array(_server.requested_methods).contains_exactly([HTTPClient.METHOD_PUT])
func test_character_name_is_url_encoded() -> void:
MusicServerClient.fetch_character_image("Paper Mario.png", func(_body: PackedByteArray) -> void: pass)
assert_array(_server.requested_paths).contains_exactly(["/character?name=Paper%20Mario.png"])
func test_requests_go_to_selected_server() -> void:
var previous_path: String = Settings.default_path
Settings.default_path = "http://localhost:8080"
var requested_urls: Array[String] = []
var recording_transport: HttpTransport = _RecordingTransport.new(requested_urls)
MusicServerClient.transport = recording_transport
MusicServerClient.fetch_song_info(func(_data: Variant) -> void: pass)
Settings.default_path = previous_path
assert_array(requested_urls).contains_exactly(["http://localhost:8080/music/info"])
class _RecordingTransport:
extends HttpTransport
var _urls: Array[String]
func _init(urls: Array[String]) -> void:
super(null)
_urls = urls
func request(url: String, _method: int, _on_complete: Callable) -> void:
_urls.append(url)
@@ -0,0 +1 @@
uid://3grferwg0j7g
+119
View File
@@ -0,0 +1,119 @@
extends GdUnitTestSuite
var _winning_score: int
var _player: PlayerObject
func before_test() -> void:
_winning_score = Settings.winning_score
Settings.winning_score = 3
_player = PlayerObject.new("Crono")
func after_test() -> void:
Settings.winning_score = _winning_score
func test_first_point_triggers_first_point_signal() -> void:
monitor_signals(_player, false)
_player.add_point()
assert_int(_player.player_score).is_equal(1)
await assert_signal(_player).is_emitted("first_point_triggerd")
await assert_signal(_player).is_emitted("player_point_given")
func test_one_point_from_winning_triggers_match_point() -> void:
_player.add_point()
monitor_signals(_player, false)
_player.add_point()
await assert_signal(_player).is_emitted("match_point_triggerd")
func test_reaching_winning_score_triggers_winner() -> void:
_player.add_point()
_player.add_point()
monitor_signals(_player, false)
_player.add_point()
assert_int(_player.player_score).is_equal(3)
await assert_signal(_player).is_emitted("winner_triggerd")
func test_score_does_not_go_past_winning_score() -> void:
for i: int in 3:
_player.add_point()
monitor_signals(_player, false)
_player.add_point()
assert_int(_player.player_score).is_equal(3)
await assert_signal(_player).wait_until(50).is_not_emitted("player_point_given")
func test_ordinary_point_plays_point_sound() -> void:
Settings.winning_score = 10
_player.add_point()
monitor_signals(_player, false)
_player.add_point()
await assert_signal(_player).is_emitted("point_given_sound")
func test_minus_point_lowers_score() -> void:
_player.add_point()
monitor_signals(_player, false)
_player.minus_point()
assert_int(_player.player_score).is_equal(0)
await assert_signal(_player).is_emitted("player_point_taken")
func test_score_does_not_go_below_zero() -> void:
monitor_signals(_player, false)
_player.minus_point()
assert_int(_player.player_score).is_equal(0)
await assert_signal(_player).wait_until(50).is_not_emitted("player_point_taken")
func test_dropping_back_to_zero_allows_first_point_again() -> void:
_player.add_point()
_player.minus_point()
monitor_signals(_player, false)
_player.add_point()
await assert_signal(_player).is_emitted("first_point_triggerd")
func test_reset_points() -> void:
_player.add_point()
_player.add_point()
_player.reset_points()
assert_int(_player.player_score).is_equal(0)
assert_bool(_player.is_first_point).is_true()
func test_id_is_a_uuid() -> void:
var uuid_pattern: RegEx = RegEx.create_from_string(
"^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$")
assert_object(uuid_pattern.search(_player.id)).is_not_null()
func test_every_player_gets_a_different_id() -> void:
var ids: Dictionary = {}
for i: int in 100:
ids[PlayerObject.new("Player %d" % i).id] = true
assert_int(ids.size()).is_equal(100)
+1
View File
@@ -0,0 +1 @@
uid://cq4vprpa1epya
+160 -149
View File
@@ -1,173 +1,184 @@
class_name PlaylistTest
extends GdUnitTestSuite
func test_add_to_playlist_increases_size():
Playlist.clear_song_list()
var initial_size = Playlist.song_object_array.size()
var song_obj = TestHelpers.create_test_song_object()
Playlist.add_to_playlist(song_obj)
assert_eq(Playlist.song_object_array.size(), initial_size + 1)
var _server: FakeHttpTransport
var _add_to_stats: bool
var _is_debug: bool
func test_get_next_song_returns_correct_song():
Playlist.clear_song_list()
var song1 = TestHelpers.create_test_song_object(1, "Soundtrack 1", "Song 1")
var song2 = TestHelpers.create_test_song_object(2, "Soundtrack 2", "Song 2")
Playlist.add_to_playlist(song1)
Playlist.add_to_playlist(song2)
Playlist.latest_played_song = 0
var next_song = Playlist.get_next_song()
assert_eq(next_song, song1)
func before_test() -> void:
_server = FakeHttpTransport.new().install()
_add_to_stats = Settings.add_to_stats
_is_debug = Settings.is_debug
Settings.add_to_stats = false
Settings.is_debug = false
Playlist.reset_playlist()
Playlist.number_of_tracks_to_preload = 1
func test_set_latest_played_song_increments():
Playlist.clear_song_list()
var song1 = TestHelpers.create_test_song_object(1)
var song2 = TestHelpers.create_test_song_object(2)
Playlist.add_to_playlist(song1)
Playlist.add_to_playlist(song2)
Playlist.latest_played_song = 0
Playlist.set_latest_played_song()
assert_eq(Playlist.latest_played_song, 1)
func after_test() -> void:
Playlist.reset_playlist()
Settings.add_to_stats = _add_to_stats
Settings.is_debug = _is_debug
_server.uninstall()
func test_set_latest_played_song_does_not_exceed_bounds():
Playlist.clear_song_list()
var song1 = TestHelpers.create_test_song_object(1)
Playlist.add_to_playlist(song1)
Playlist.latest_played_song = 0
Playlist.set_latest_played_song()
Playlist.set_latest_played_song()
assert_eq(Playlist.latest_played_song, 0)
func _add_songs(count: int) -> Array[SongObject]:
var songs: Array[SongObject] = []
for i: int in count:
var song: SongObject = SongObject.new()
song.song_number = i
song.soundtrack_title = "Soundtrack %d" % i
song.song_title = "Song %d" % i
Playlist.add_to_playlist(song)
songs.append(song)
return songs
func test_get_preloaded_songs_returns_correct_count():
Playlist.clear_song_list()
var song1 = TestHelpers.create_test_song_object(1)
var song2 = TestHelpers.create_test_song_object(2)
var song3 = TestHelpers.create_test_song_object(3)
song1.has_played = true
song2.has_played = false
song3.has_played = false
Playlist.add_to_playlist(song1)
Playlist.add_to_playlist(song2)
Playlist.add_to_playlist(song3)
assert_eq(Playlist.get_preloaded_songs(), 2)
func test_set_latest_played_song_advances() -> void:
_add_songs(3)
Playlist.set_latest_played_song()
assert_int(Playlist.latest_played_song).is_equal(1)
func test_should_preload_more_songs():
Playlist.clear_song_list()
Playlist.number_of_tracks_to_preload = 2
var song1 = TestHelpers.create_test_song_object(1)
var song2 = TestHelpers.create_test_song_object(2)
song1.has_played = true
song2.has_played = false
Playlist.add_to_playlist(song1)
Playlist.add_to_playlist(song2)
assert_true(Playlist.should_preload_more_songs())
var song3 = TestHelpers.create_test_song_object(3)
Playlist.add_to_playlist(song3)
assert_false(Playlist.should_preload_more_songs())
func test_set_latest_played_song_stops_at_last_song() -> void:
_add_songs(2)
Playlist.set_latest_played_song()
Playlist.set_latest_played_song()
Playlist.set_latest_played_song()
assert_int(Playlist.latest_played_song).is_equal(1)
func test_song_is_answered_sets_flag():
Playlist.clear_song_list()
var song = TestHelpers.create_test_song_object(1)
Playlist.add_to_playlist(song)
Playlist.currently_playing_song = 0
assert_false(song.is_answered)
Playlist.song_is_answered()
assert_true(song.is_answered)
func test_get_next_song_returns_latest_played() -> void:
var songs: Array[SongObject] = _add_songs(3)
Playlist.latest_played_song = 2
assert_object(Playlist.get_next_song()).is_same(songs[2])
func test_add_point_to_song():
Playlist.clear_song_list()
var song = TestHelpers.create_test_song_object(1)
Playlist.add_to_playlist(song)
Playlist.currently_playing_song = 0
Playlist.add_point(0)
assert_true(song.players_given_point.has(0))
func test_update_last_played_song_points_past_existing_songs() -> void:
_add_songs(4)
Playlist.update_last_played_song()
assert_int(Playlist.latest_played_song).is_equal(4)
func test_remove_point_from_song():
Playlist.clear_song_list()
var song = TestHelpers.create_test_song_object(1)
Playlist.add_to_playlist(song)
Playlist.currently_playing_song = 0
Playlist.add_point(0)
Playlist.remove_point(0)
assert_false(song.players_given_point.has(0))
func test_preloaded_songs_counts_unplayed_songs() -> void:
var songs: Array[SongObject] = _add_songs(3)
songs[0].has_played = true
assert_int(Playlist.get_preloaded_songs()).is_equal(2)
func test_get_song_returns_correct_stream():
Playlist.clear_song_list()
var expected_stream = TestHelpers.create_mock_audio_stream()
var song = TestHelpers.create_test_song_object(1)
song.song = expected_stream
Playlist.add_to_playlist(song)
var retrieved_stream = Playlist.get_song(0)
assert_eq(retrieved_stream, expected_stream)
func test_should_preload_more_songs_when_below_target() -> void:
var songs: Array[SongObject] = _add_songs(1)
songs[0].has_played = true
assert_bool(Playlist.should_preload_more_songs()).is_true()
func test_reset_playlist_clears_all():
Playlist.clear_song_list()
var song = TestHelpers.create_test_song_object(1)
Playlist.add_to_playlist(song)
Playlist.latest_played_song = 1
Playlist.currently_playing_song = 0
Playlist.reset_playlist()
assert_eq(Playlist.song_object_array.size(), 0)
assert_eq(Playlist.latest_played_song, 0)
assert_eq(Playlist.currently_playing_song, -1)
func test_should_not_preload_more_songs_when_target_reached() -> void:
_add_songs(1)
assert_bool(Playlist.should_preload_more_songs()).is_false()
func test_clear_song_list_removes_all():
Playlist.clear_song_list()
Playlist.add_to_playlist(TestHelpers.create_test_song_object(1))
Playlist.add_to_playlist(TestHelpers.create_test_song_object(2))
Playlist.clear_song_list()
assert_eq(Playlist.song_object_array.size(), 0)
func test_get_playlist_hides_unplayed_songs() -> void:
var songs: Array[SongObject] = _add_songs(3)
songs[0].has_played = true
assert_array(Playlist.get_playlist()).contains_exactly([songs[0]])
func test_get_playlist_shows_everything_in_debug() -> void:
Settings.is_debug = true
var songs: Array[SongObject] = _add_songs(2)
assert_array(Playlist.get_playlist()).contains_exactly(songs)
func test_song_is_answered_marks_song() -> void:
var songs: Array[SongObject] = _add_songs(2)
Playlist.song_is_answered(1)
assert_bool(songs[1].is_answered).is_true()
assert_bool(songs[0].is_answered).is_false()
func test_song_is_answered_reports_to_stats_when_enabled() -> void:
Settings.add_to_stats = true
_add_songs(2)
Playlist.song_is_answered(1)
assert_array(_server.requested_paths).contains_exactly(["/music/played?song=1"])
func test_song_is_answered_does_not_report_when_stats_disabled() -> void:
_add_songs(2)
Playlist.song_is_answered(1)
assert_array(_server.requested_paths).is_empty()
func test_points_are_recorded_on_current_song() -> void:
var songs: Array[SongObject] = _add_songs(2)
Playlist.set_currently_playing_song(1)
Playlist.add_point("lucca-id")
Playlist.add_point("crono-id")
assert_array(songs[1].players_given_point).contains_exactly(["lucca-id", "crono-id"])
assert_array(songs[0].players_given_point).is_empty()
func test_remove_point_from_current_song() -> void:
var songs: Array[SongObject] = _add_songs(1)
Playlist.set_currently_playing_song(0)
Playlist.add_point("crono-id")
Playlist.add_point("marle-id")
Playlist.remove_point("crono-id")
assert_array(songs[0].players_given_point).contains_exactly(["marle-id"])
func test_remove_player_removes_only_that_players_points() -> void:
var songs: Array[SongObject] = _add_songs(2)
songs[0].players_given_point.assign(["crono-id", "marle-id"])
songs[1].players_given_point.assign(["crono-id"])
Playlist.remove_player_from_list("marle-id")
assert_array(songs[0].players_given_point).contains_exactly(["crono-id"])
assert_array(songs[1].players_given_point).contains_exactly(["crono-id"])
func test_reset_playlist_clears_songs_and_position() -> void:
_add_songs(3)
Playlist.latest_played_song = 2
Playlist.set_currently_playing_song(1)
Playlist.reset_playlist()
assert_array(Playlist.song_object_array).is_empty()
assert_int(Playlist.latest_played_song).is_equal(0)
assert_int(Playlist.currently_playing_song).is_equal(-1)
func test_current_titles_are_hidden_until_answered() -> void:
var songs: Array[SongObject] = _add_songs(1)
Playlist.set_currently_playing_song(0)
assert_str(Playlist.get_current_soundtrack_title()).is_equal("????????")
songs[0].is_answered = true
assert_str(Playlist.get_current_soundtrack_title()).is_equal("Soundtrack 0")
assert_str(Playlist.get_current_song_title()).is_equal("Song 0")
+1
View File
@@ -0,0 +1 @@
uid://c2ibkc7bd60cx
+62
View File
@@ -0,0 +1,62 @@
extends GdUnitTestSuite
const SearchWindowScript: GDScript = preload("res://SearchWindow.gd")
var _search: Control
func before_test() -> void:
_search = auto_free(SearchWindowScript.new())
_search.set_soundtracks([
"Chrono Trigger",
"Final Fantasy VI",
"Mario & Luigi: Superstar Saga",
"Pokémon Red",
"Q*bert",
"Super Mario 64",
"The Legend of Zelda: A Link to the Past",
])
func test_plain_text_matches_case_insensitively() -> void:
assert_array(_search.find_matches("chrono")).contains_exactly(["Chrono Trigger"])
func test_contains_matches_come_before_letter_order_matches() -> void:
var matches: Array[String] = _search.find_matches("mario")
assert_array(matches).contains_exactly([
"Mario & Luigi: Superstar Saga",
"Super Mario 64",
])
func test_ignores_spaces() -> void:
assert_array(_search.find_matches("finalfantasy")).contains_exactly(["Final Fantasy VI"])
func test_and_matches_ampersand() -> void:
assert_array(_search.find_matches("mario and luigi")).contains(["Mario & Luigi: Superstar Saga"])
func test_accented_letters_match_plain_letters() -> void:
assert_array(_search.find_matches("pokemon")).contains_exactly(["Pokémon Red"])
func test_letters_in_order_match_abbreviations() -> void:
assert_array(_search.find_matches("lozlttp")).contains_exactly([
"The Legend of Zelda: A Link to the Past",
])
func test_regex_characters_are_matched_literally() -> void:
assert_array(_search.find_matches("q*b")).contains_exactly(["Q*bert"])
func test_no_matches() -> void:
assert_array(_search.find_matches("metroid")).is_empty()
func test_clean_term() -> void:
assert_str(_search.clean_term("Rock 'n Roll Racing")).is_equal("rockandrollracing")
assert_str(_search.clean_term("Ys I & II")).is_equal("ysiandii")
+1
View File
@@ -0,0 +1 @@
uid://p8ygq52abebj
-94
View File
@@ -1,94 +0,0 @@
class_name SettingsTest
extends GdUnitTestSuite
func test_make_request2_calls_callback_on_success():
var callback_called = false
var received_data = null
var callback = func(data):
callback_called = true
received_data = data
# Mock the HTTP request behavior
var original_make_request = Settings.make_request2
Settings.make_request2 = func(address: String, func_name: Callable, expect_data: bool) -> void:
if expect_data:
func_name.call([{"SongNo": 1, "Soundtrack": "Test", "Song": "Test Song"}])
else:
func_name.call()
Settings.make_request2("/music/list", callback, true)
assert_true(callback_called)
assert_eq(received_data[0].SongNo, 1)
# Restore original
Settings.make_request2 = original_make_request
func test_make_request2_handles_error_response():
var error_called = false
var callback = func(data):
# This shouldn't be called for error responses
pass
# Mock error response
var original_make_request = Settings.make_request2
Settings.make_request2 = func(address: String, func_name: Callable, expect_data: bool) -> void:
# Simulate error by not calling the callback
pass
Settings.make_request2("/music/error", callback, true)
# Restore and verify callback wasn't called with data
Settings.make_request2 = original_make_request
assert_false(error_called)
func test_make_request3_does_not_expect_data():
var callback_called = false
var callback = func():
callback_called = true
var original_make_request = Settings.make_request3
Settings.make_request3 = func(address: String) -> void:
callback.call()
Settings.make_request3("/music/reset")
assert_true(callback_called)
Settings.make_request3 = original_make_request
func test_delete_children_removes_all():
var node = Node.new()
var child1 = Node.new()
var child2 = Node.new()
node.add_child(child1)
node.add_child(child2)
assert_eq(node.get_child_count(), 2)
Settings.delete_children(node)
assert_eq(node.get_child_count(), 0)
func test_delete_player_children_removes_all():
var node = Node.new()
var player1 = Player.new()
var player2 = Player.new()
node.add_child(player1)
node.add_child(player2)
assert_eq(node.get_child_count(), 2)
Settings.delete_player_children(node)
assert_eq(node.get_child_count(), 0)
+60
View File
@@ -0,0 +1,60 @@
extends GdUnitTestSuite
var _is_debug: bool
var _song: SongObject
func before_test() -> void:
_is_debug = Settings.is_debug
Settings.is_debug = false
_song = SongObject.new()
_song.song_number = 4
_song.soundtrack_title = "Final Fantasy VI"
_song.song_title = "Dancing Mad"
func after_test() -> void:
Settings.is_debug = _is_debug
func test_titles_are_hidden_until_answered() -> void:
assert_str(_song.get_soundtrack_title()).is_equal("????????")
assert_str(_song.get_song_title()).is_equal("??????")
assert_str(_song.get_song_info()).is_equal("??? - ???")
func test_titles_are_shown_once_answered() -> void:
_song.is_answered = true
assert_str(_song.get_soundtrack_title()).is_equal("Final Fantasy VI")
assert_str(_song.get_song_title()).is_equal("Dancing Mad")
assert_str(_song.get_song_info()).is_equal("5. Final Fantasy VI - Dancing Mad")
func test_debug_info_shows_unanswered_songs() -> void:
Settings.is_debug = true
assert_str(_song.get_song_info()).is_equal(
"5. Final Fantasy VI - Dancing Mad | played: false | answered: false")
func test_points_are_kept_in_the_order_given() -> void:
_song.add_point("marle-id")
_song.add_point("crono-id")
assert_array(_song.players_given_point).contains_exactly(["marle-id", "crono-id"])
func test_player_gets_at_most_one_point_per_song() -> void:
_song.add_point("crono-id")
_song.add_point("crono-id")
assert_array(_song.players_given_point).contains_exactly(["crono-id"])
func test_removing_point_of_player_without_point_changes_nothing() -> void:
_song.add_point("crono-id")
_song.remove_point("marle-id")
assert_array(_song.players_given_point).contains_exactly(["crono-id"])
+1
View File
@@ -0,0 +1 @@
uid://cfc78daetbf6i