Split now playing, the quiz buttons and song loading out of the quiz
NowPlaying, QuizToolbar and SongControls become their own scenes, the auto repeat switch moves into the music player scene, and downloading songs moves into a SongLoader node. The quiz only wires the parts together. Every node keeps its place on screen. Screenshots of every UI state are pixel-identical to before, the layout test still matches the original baseline, and each new part has its own tests.
This commit is contained in:
1 parent
bad4b3ad8b
commit
e94c75e84d
32 files changed
+822
-300
No files matched your search
@@ -70,7 +70,7 @@ func _press(button_path: String) -> void:
|
||||
|
||||
## Presses Next and waits until the first song is playing.
|
||||
func _play_first_song() -> void:
|
||||
_press("NextButton")
|
||||
_press("SongControls/NextButton")
|
||||
await _runner.simulate_frames(2)
|
||||
|
||||
|
||||
|
||||
@@ -12,16 +12,24 @@ const BASELINE_PATH: String = "res://tests/data/layout_baseline.json"
|
||||
|
||||
## Nodes that moved from the main window into the Quiz scene, by their old name.
|
||||
const QUIZ_NODES: Array[String] = [
|
||||
"Open", "FileDialog", "MusicListPanel", "VBoxContainer",
|
||||
"MusicPlayer", "ResetPlaylistButton", "ResetPointsButton", "SettingsButton",
|
||||
"SoundTestButton", "ShowAnswerButton", "NextButton", "RepeatSongCheckButton",
|
||||
"DebugLabel", "SettingsWindow", "NewCharacterSelect", "WinnerWindow", "Log",
|
||||
"Open", "FileDialog", "MusicListPanel", "DebugLabel", "SettingsWindow",
|
||||
"NewCharacterSelect", "WinnerWindow", "Log",
|
||||
]
|
||||
|
||||
## Nodes that moved into the Quiz scene and were renamed there: old name to new name.
|
||||
## Nodes that moved into the Quiz scene under another path: old name to new path in
|
||||
## the quiz.
|
||||
const RENAMED_QUIZ_NODES: Dictionary = {
|
||||
"Players": "PlayersPanel",
|
||||
"ScrollContainer": "InspirationList",
|
||||
"VBoxContainer": "NowPlaying",
|
||||
"MusicPlayer": "MusicPlayer/PlayerBar",
|
||||
"RepeatSongCheckButton": "MusicPlayer/RepeatSongCheckButton",
|
||||
"ResetPlaylistButton": "QuizToolbar/ResetPlaylistButton",
|
||||
"ResetPointsButton": "QuizToolbar/ResetPointsButton",
|
||||
"SettingsButton": "QuizToolbar/SettingsButton",
|
||||
"SoundTestButton": "QuizToolbar/SoundTestButton",
|
||||
"ShowAnswerButton": "SongControls/ShowAnswerButton",
|
||||
"NextButton": "SongControls/NextButton",
|
||||
}
|
||||
|
||||
## Nodes that moved from the main window into the TopBar scene, by their old name.
|
||||
|
||||
@@ -7,7 +7,7 @@ func test_startup_loads_soundtracks_and_preloads_a_song() -> void:
|
||||
assert_int(_server.count("/music/all")).is_equal(1)
|
||||
assert_array(_server.requested_paths).contains(["/music/rand", "/music/addQue", "/music/info"])
|
||||
assert_int(Playlist.song_object_array.size()).is_equal(1)
|
||||
assert_bool((_quiz.get_node("NextButton") as Button).disabled).is_false()
|
||||
assert_bool((_quiz.get_node("SongControls/NextButton") as Button).disabled).is_false()
|
||||
|
||||
|
||||
func test_low_played_mode_fetches_from_low_played_endpoint() -> void:
|
||||
@@ -15,7 +15,7 @@ func test_low_played_mode_fetches_from_low_played_endpoint() -> void:
|
||||
_server.respond_bytes(
|
||||
"/music/rand/low", FileAccess.get_file_as_bytes("res://tests/data/short.mp3"))
|
||||
|
||||
_quiz.fetch_song()
|
||||
_quiz.song_loader.fetch_song()
|
||||
|
||||
assert_int(_server.count("/music/rand/low")).is_equal(1)
|
||||
|
||||
@@ -23,7 +23,7 @@ func test_low_played_mode_fetches_from_low_played_endpoint() -> void:
|
||||
func test_next_plays_preloaded_song_and_fetches_another() -> void:
|
||||
_next_song_is(SONG_INFO[1])
|
||||
|
||||
_press("NextButton")
|
||||
_press("SongControls/NextButton")
|
||||
await _runner.simulate_frames(2)
|
||||
|
||||
assert_int(Playlist.currently_playing_song).is_equal(0)
|
||||
@@ -33,23 +33,23 @@ func test_next_plays_preloaded_song_and_fetches_another() -> void:
|
||||
|
||||
|
||||
func test_title_is_hidden_until_answer_is_shown() -> void:
|
||||
var soundtrack_label: Label = _quiz.get_node("VBoxContainer/SoundtrackLabel")
|
||||
_press("NextButton")
|
||||
var soundtrack_label: Label = _quiz.get_node("NowPlaying/SoundtrackLabel")
|
||||
_press("SongControls/NextButton")
|
||||
await _runner.simulate_frames(2)
|
||||
|
||||
assert_str(soundtrack_label.text).is_equal("????????")
|
||||
|
||||
_press("ShowAnswerButton")
|
||||
_press("SongControls/ShowAnswerButton")
|
||||
|
||||
assert_str(soundtrack_label.text).is_equal("Chrono Trigger")
|
||||
assert_int(_server.count("/music/played?song=0")).is_equal(1)
|
||||
|
||||
|
||||
func test_reset_playlist_clears_server_and_preloads_again() -> void:
|
||||
_press("NextButton")
|
||||
_press("SongControls/NextButton")
|
||||
await _runner.simulate_frames(2)
|
||||
|
||||
_press("ResetPlaylistButton")
|
||||
_press("QuizToolbar/ResetPlaylistButton")
|
||||
|
||||
assert_int(_server.count("/music/reset")).is_equal(1)
|
||||
assert_int(Playlist.currently_playing_song).is_equal(-1)
|
||||
@@ -61,7 +61,7 @@ func test_reset_points_sets_all_scores_to_zero() -> void:
|
||||
_add_player("Crono").add_point()
|
||||
_add_player("Marle").add_point()
|
||||
|
||||
_press("ResetPointsButton")
|
||||
_press("QuizToolbar/ResetPointsButton")
|
||||
|
||||
assert_int(Settings.player_array[0].player_score).is_equal(0)
|
||||
assert_int(Settings.player_array[1].player_score).is_equal(0)
|
||||
@@ -81,13 +81,13 @@ func test_cannot_add_player_without_name() -> void:
|
||||
|
||||
|
||||
func test_failed_song_download_is_retried_until_the_server_answers() -> void:
|
||||
_quiz.song_fetch_retry_seconds = 0.05
|
||||
_quiz.song_loader.retry_seconds = 0.05
|
||||
var songs_before: int = Playlist.song_object_array.size()
|
||||
var mp3: PackedByteArray = FileAccess.get_file_as_bytes("res://tests/data/short.mp3")
|
||||
_server.respond_bytes("/music/rand", PackedByteArray(), 503)
|
||||
var rand_requests_before: int = _server.count("/music/rand")
|
||||
|
||||
_quiz.fetch_song()
|
||||
_quiz.song_loader.fetch_song()
|
||||
await await_millis(200)
|
||||
|
||||
assert_int(_server.count("/music/rand") - rand_requests_before).is_greater(1)
|
||||
@@ -102,13 +102,13 @@ func test_failed_song_download_is_retried_until_the_server_answers() -> void:
|
||||
|
||||
|
||||
func test_failed_song_info_retries_only_that_step() -> void:
|
||||
_quiz.song_fetch_retry_seconds = 0.05
|
||||
_quiz.song_loader.retry_seconds = 0.05
|
||||
var songs_before: int = Playlist.song_object_array.size()
|
||||
_server.respond_bytes("/music/info", PackedByteArray(), 503)
|
||||
var rand_before: int = _server.count("/music/rand")
|
||||
var queue_before: int = _server.count("/music/addQue")
|
||||
|
||||
_quiz.fetch_song()
|
||||
_quiz.song_loader.fetch_song()
|
||||
await await_millis(200)
|
||||
_next_song_is(SONG_INFO[1])
|
||||
await await_millis(200)
|
||||
@@ -124,7 +124,7 @@ func test_failed_song_info_retries_only_that_step() -> void:
|
||||
func test_preloads_as_many_songs_as_the_cache_setting() -> void:
|
||||
Playlist.number_of_tracks_to_preload = 3
|
||||
|
||||
_quiz.fetch_song()
|
||||
_quiz.song_loader.fetch_song()
|
||||
|
||||
assert_int(Playlist.get_preloaded_songs()).is_equal(3)
|
||||
assert_bool(Playlist.is_song_downloading).is_false()
|
||||
@@ -132,7 +132,7 @@ func test_preloads_as_many_songs_as_the_cache_setting() -> void:
|
||||
|
||||
func test_playing_a_song_tops_the_cache_up_again() -> void:
|
||||
Playlist.number_of_tracks_to_preload = 3
|
||||
_quiz.fetch_song()
|
||||
_quiz.song_loader.fetch_song()
|
||||
|
||||
await _play_first_song()
|
||||
|
||||
@@ -141,13 +141,13 @@ func test_playing_a_song_tops_the_cache_up_again() -> void:
|
||||
|
||||
|
||||
func test_cache_keeps_filling_after_a_failed_download() -> void:
|
||||
_quiz.song_fetch_retry_seconds = 0.05
|
||||
_quiz.song_loader.retry_seconds = 0.05
|
||||
Playlist.number_of_tracks_to_preload = 3
|
||||
var mp3: PackedByteArray = FileAccess.get_file_as_bytes("res://tests/data/short.mp3")
|
||||
# One more download works, then the server stops answering
|
||||
_server.fail_after("/music/rand", 1)
|
||||
|
||||
_quiz.fetch_song()
|
||||
_quiz.song_loader.fetch_song()
|
||||
await await_millis(150)
|
||||
|
||||
assert_int(Playlist.get_preloaded_songs()).is_equal(2)
|
||||
@@ -161,7 +161,7 @@ func test_cache_keeps_filling_after_a_failed_download() -> void:
|
||||
|
||||
|
||||
func _open_settings() -> void:
|
||||
_press("SettingsButton")
|
||||
_press("QuizToolbar/SettingsButton")
|
||||
|
||||
|
||||
func _close_settings() -> void:
|
||||
@@ -217,14 +217,14 @@ func test_closing_settings_with_full_cache_downloads_nothing() -> void:
|
||||
|
||||
|
||||
func test_show_answer_before_first_song_does_not_reveal_next_song() -> void:
|
||||
_press("ShowAnswerButton")
|
||||
_press("SongControls/ShowAnswerButton")
|
||||
|
||||
assert_bool(Playlist.song_object_array[0].is_answered).is_false()
|
||||
assert_int(_server.count("/music/played?song=-1")).is_equal(0)
|
||||
|
||||
await _play_first_song()
|
||||
|
||||
assert_str((_quiz.get_node("VBoxContainer/SoundtrackLabel") as Label).text) \
|
||||
assert_str((_quiz.get_node("NowPlaying/SoundtrackLabel") as Label).text) \
|
||||
.is_equal("????????")
|
||||
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ func test_next_plays_the_preloaded_song_after_a_slow_song_list() -> void:
|
||||
|
||||
|
||||
func test_failed_song_list_is_retried_before_preloading() -> void:
|
||||
_quiz.song_fetch_retry_seconds = 0.05
|
||||
_quiz.song_loader.retry_seconds = 0.05
|
||||
_server.respond_json("/music/list", [], 503)
|
||||
_server.release("/music/list")
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
extends GdUnitTestSuite
|
||||
## The music player scene: the player bar and the auto repeat switch under it.
|
||||
|
||||
var _snapshot: AutoloadSnapshot
|
||||
var _runner: GdUnitSceneRunner
|
||||
var _player: MusicPlayer
|
||||
|
||||
|
||||
func before_test() -> void:
|
||||
_snapshot = AutoloadSnapshot.take([Settings])
|
||||
Settings.auto_repeat_song = true
|
||||
_runner = scene_runner("res://MusicPlayer.tscn")
|
||||
_player = _runner.scene()
|
||||
|
||||
|
||||
func after_test() -> void:
|
||||
_snapshot.restore()
|
||||
|
||||
|
||||
func _click(control: Control) -> void:
|
||||
_runner.set_mouse_position(_player.get_viewport().get_final_transform()
|
||||
* control.get_global_rect().get_center())
|
||||
await _runner.simulate_mouse_button_pressed(MOUSE_BUTTON_LEFT)
|
||||
await _runner.await_input_processed()
|
||||
|
||||
|
||||
func test_auto_repeat_starts_on() -> void:
|
||||
assert_bool(_player.auto_repeat_button.button_pressed).is_true()
|
||||
|
||||
|
||||
func test_clicking_auto_repeat_turns_it_off_and_on() -> void:
|
||||
await _click(_player.auto_repeat_button)
|
||||
assert_bool(Settings.auto_repeat_song).is_false()
|
||||
assert_bool(_player.auto_repeat_button.button_pressed).is_false()
|
||||
|
||||
await _click(_player.auto_repeat_button)
|
||||
assert_bool(Settings.auto_repeat_song).is_true()
|
||||
|
||||
|
||||
func test_auto_repeat_is_under_the_player_bar() -> void:
|
||||
await _runner.simulate_frames(1)
|
||||
var bar: Rect2 = (_player.get_node("PlayerBar") as Control).get_global_rect()
|
||||
var repeat: Rect2 = _player.auto_repeat_button.get_global_rect()
|
||||
|
||||
assert_float(repeat.position.y).is_greater_equal(bar.end.y)
|
||||
assert_bool(_player.get_global_rect().encloses(repeat)).is_true()
|
||||
|
||||
|
||||
func test_empty_space_lets_clicks_through() -> void:
|
||||
assert_int(_player.mouse_filter).is_equal(Control.MOUSE_FILTER_IGNORE)
|
||||
@@ -0,0 +1 @@
|
||||
uid://ck3ti57dgce3w
|
||||
@@ -0,0 +1,34 @@
|
||||
extends GdUnitTestSuite
|
||||
## The soundtrack and song shown at the top of the quiz.
|
||||
|
||||
var _runner: GdUnitSceneRunner
|
||||
var _now_playing: NowPlaying
|
||||
|
||||
|
||||
func before_test() -> void:
|
||||
_runner = scene_runner("res://NowPlaying.tscn")
|
||||
_now_playing = _runner.scene()
|
||||
|
||||
|
||||
func _label(label_name: String) -> Label:
|
||||
return _now_playing.get_node(label_name)
|
||||
|
||||
|
||||
func test_starts_empty() -> void:
|
||||
assert_str(_label("SoundtrackLabel").text).is_empty()
|
||||
assert_str(_label("SongLabel").text).is_empty()
|
||||
|
||||
|
||||
func test_show_song_shows_soundtrack_and_song() -> void:
|
||||
_now_playing.show_song("Chrono Trigger", "Corridors of Time")
|
||||
|
||||
assert_str(_label("SoundtrackLabel").text).is_equal("Chrono Trigger")
|
||||
assert_str(_label("SongLabel").text).is_equal("Corridors of Time")
|
||||
|
||||
|
||||
func test_soundtrack_is_above_song() -> void:
|
||||
_now_playing.show_song("Chrono Trigger", "Corridors of Time")
|
||||
await _runner.simulate_frames(1)
|
||||
|
||||
assert_float(_label("SoundtrackLabel").get_global_rect().end.y) \
|
||||
.is_less_equal(_label("SongLabel").get_global_rect().position.y)
|
||||
@@ -0,0 +1 @@
|
||||
uid://cidytlxgrmlk0
|
||||
@@ -80,7 +80,7 @@ func test_click_inside_popup_keeps_it_open() -> void:
|
||||
|
||||
func test_closing_click_does_not_press_button_behind_popup() -> void:
|
||||
var settings: PopupWindow = _popup("SettingsWindow")
|
||||
var reset_button: Button = _quiz.get_node("ResetPlaylistButton")
|
||||
var reset_button: Button = _quiz.get_node("QuizToolbar/ResetPlaylistButton")
|
||||
settings.open()
|
||||
await _runner.simulate_frames(1)
|
||||
assert_bool(settings.panel.get_global_rect().intersects(reset_button.get_global_rect())) \
|
||||
@@ -93,7 +93,7 @@ func test_closing_click_does_not_press_button_behind_popup() -> void:
|
||||
|
||||
|
||||
func test_button_works_again_after_popup_closed() -> void:
|
||||
var reset_button: Button = _quiz.get_node("ResetPlaylistButton")
|
||||
var reset_button: Button = _quiz.get_node("QuizToolbar/ResetPlaylistButton")
|
||||
|
||||
await _click_at(reset_button.get_global_rect().get_center())
|
||||
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
extends GdUnitTestSuite
|
||||
## The row of quiz buttons: each button reports its press, and locking disables the
|
||||
## buttons that use the song list.
|
||||
|
||||
const BUTTON_SIGNALS: Dictionary = {
|
||||
"ResetPlaylistButton": "reset_playlist_pressed",
|
||||
"ResetPointsButton": "reset_points_pressed",
|
||||
"SettingsButton": "settings_pressed",
|
||||
"SoundTestButton": "sound_test_pressed",
|
||||
}
|
||||
|
||||
var _runner: GdUnitSceneRunner
|
||||
var _toolbar: QuizToolbar
|
||||
|
||||
|
||||
func before_test() -> void:
|
||||
_runner = scene_runner("res://QuizToolbar.tscn")
|
||||
_toolbar = _runner.scene()
|
||||
|
||||
|
||||
func _button(button_name: String) -> Button:
|
||||
return _toolbar.get_node(button_name)
|
||||
|
||||
|
||||
func _click(button_name: String) -> void:
|
||||
_runner.set_mouse_position(_toolbar.get_viewport().get_final_transform()
|
||||
* _button(button_name).get_global_rect().get_center())
|
||||
await _runner.simulate_mouse_button_pressed(MOUSE_BUTTON_LEFT)
|
||||
await _runner.await_input_processed()
|
||||
|
||||
|
||||
func test_clicking_each_button_reports_it() -> void:
|
||||
for button_name: String in BUTTON_SIGNALS:
|
||||
var signals: GdUnitSignalAssert = assert_signal(monitor_signals(_toolbar))
|
||||
|
||||
await _click(button_name)
|
||||
|
||||
await signals.override_failure_message(button_name + " not reported") \
|
||||
.is_emitted(BUTTON_SIGNALS[button_name])
|
||||
|
||||
|
||||
func test_buttons_are_in_order_left_to_right() -> void:
|
||||
var lefts: Array = ["ResetPlaylistButton", "ResetPointsButton", "SettingsButton",
|
||||
"SoundTestButton"].map(func(n: String) -> float: return _button(n).position.x)
|
||||
|
||||
for i: int in lefts.size() - 1:
|
||||
assert_float(lefts[i]).is_less(lefts[i + 1])
|
||||
|
||||
|
||||
func test_locking_disables_only_buttons_that_use_the_song_list() -> void:
|
||||
_toolbar.set_locked(true)
|
||||
|
||||
assert_bool(_button("ResetPlaylistButton").disabled).is_true()
|
||||
assert_bool(_button("SoundTestButton").disabled).is_true()
|
||||
assert_bool(_button("ResetPointsButton").disabled).is_false()
|
||||
assert_bool(_button("SettingsButton").disabled).is_false()
|
||||
|
||||
|
||||
func test_unlocking_enables_them_again() -> void:
|
||||
_toolbar.set_locked(true)
|
||||
|
||||
_toolbar.set_locked(false)
|
||||
|
||||
assert_bool(_button("ResetPlaylistButton").disabled).is_false()
|
||||
assert_bool(_button("SoundTestButton").disabled).is_false()
|
||||
|
||||
|
||||
func test_clicks_between_buttons_go_through() -> void:
|
||||
assert_int(_toolbar.mouse_filter).is_equal(Control.MOUSE_FILTER_IGNORE)
|
||||
@@ -0,0 +1 @@
|
||||
uid://ecsdudhpw8oi
|
||||
@@ -51,11 +51,21 @@ func test_top_bar_is_drawn_below_the_quiz() -> void:
|
||||
|
||||
|
||||
func test_quiz_parts_are_their_own_scenes() -> void:
|
||||
for node_name: String in ["MusicListPanel", "PlayersPanel", "InspirationList"]:
|
||||
for node_name: String in ["MusicListPanel", "PlayersPanel", "InspirationList",
|
||||
"NowPlaying", "QuizToolbar", "SongControls", "MusicPlayer"]:
|
||||
assert_str(_quiz.get_node(node_name).scene_file_path) \
|
||||
.is_equal("res://%s.tscn" % node_name)
|
||||
|
||||
|
||||
func test_quiz_downloads_songs_with_a_song_loader() -> void:
|
||||
assert_object(_quiz.song_loader).is_instanceof(SongLoader)
|
||||
|
||||
|
||||
func test_auto_repeat_is_part_of_the_music_player() -> void:
|
||||
assert_object(_quiz.get_node("MusicPlayer/RepeatSongCheckButton")).is_instanceof(CheckButton)
|
||||
assert_object(_quiz.get_node_or_null("RepeatSongCheckButton")).is_null()
|
||||
|
||||
|
||||
func test_top_bar_holds_only_title_and_buttons() -> void:
|
||||
assert_array(_children(_window.get_node("TopBar"))) \
|
||||
.contains_exactly_in_any_order(TOP_BAR_CHILDREN)
|
||||
@@ -83,22 +93,22 @@ func test_clicking_each_top_bar_button_opens_its_popup() -> void:
|
||||
|
||||
|
||||
func test_clicking_quiz_buttons_plays_and_shows_answer() -> void:
|
||||
await _click_at(_center(_quiz.get_node("NextButton")))
|
||||
await _click_at(_center(_quiz.get_node("SongControls/NextButton")))
|
||||
await _runner.simulate_frames(2)
|
||||
assert_int(Playlist.currently_playing_song).is_equal(0)
|
||||
assert_str((_quiz.get_node("VBoxContainer/SoundtrackLabel") as Label).text) \
|
||||
assert_str((_quiz.get_node("NowPlaying/SoundtrackLabel") as Label).text) \
|
||||
.is_not_equal("Chrono Trigger")
|
||||
|
||||
await _click_at(_center(_quiz.get_node("ShowAnswerButton")))
|
||||
await _click_at(_center(_quiz.get_node("SongControls/ShowAnswerButton")))
|
||||
|
||||
assert_str((_quiz.get_node("VBoxContainer/SoundtrackLabel") as Label).text) \
|
||||
assert_str((_quiz.get_node("NowPlaying/SoundtrackLabel") as Label).text) \
|
||||
.is_equal("Chrono Trigger")
|
||||
|
||||
|
||||
func test_clicking_a_song_in_the_music_list_plays_it() -> void:
|
||||
_next_song_is(SONG_INFO[1])
|
||||
await _play_first_song()
|
||||
_press("NextButton")
|
||||
_press("SongControls/NextButton")
|
||||
# Changing song waits a moment for the old one to stop
|
||||
await get_tree().create_timer(0.7).timeout
|
||||
assert_int(Playlist.currently_playing_song).is_equal(1)
|
||||
@@ -137,6 +147,30 @@ func test_character_button_in_the_player_list_picks_a_new_character() -> void:
|
||||
assert_object(crono.character).is_same(texture)
|
||||
|
||||
|
||||
func test_sound_test_button_fetches_the_sound_test_song() -> void:
|
||||
_server.respond_bytes("/music/soundTest", FileAccess.get_file_as_bytes("res://tests/data/short.mp3"))
|
||||
|
||||
await _click_at(_center(_quiz.get_node("QuizToolbar/SoundTestButton")))
|
||||
|
||||
assert_int(_server.count("/music/soundTest")).is_equal(1)
|
||||
|
||||
|
||||
func test_loaded_song_list_shows_in_the_music_list() -> void:
|
||||
# No new song finishes downloading, so only loading the list can show the songs
|
||||
_server.hold("/music/rand")
|
||||
_server.respond_json("/music/list", [
|
||||
{"SongNo": 0, "Soundtrack": "Chrono Trigger", "Song": "Corridors of Time"},
|
||||
{"SongNo": 1, "Soundtrack": "Final Fantasy VI", "Song": "Dancing Mad"},
|
||||
])
|
||||
Playlist.is_song_downloading = false
|
||||
|
||||
_quiz.song_loader.load_song_list()
|
||||
|
||||
var rows: Array[Node] = _quiz.get_node("MusicListPanel/ScrollContainer/MusicList").get_children()
|
||||
assert_array(rows.map(func(row: SongListObject) -> int: return row.song_object.song_number)) \
|
||||
.contains_exactly([0, 1])
|
||||
|
||||
|
||||
func test_quiz_popup_backdrop_covers_the_top_bar() -> void:
|
||||
var settings: PopupWindow = _quiz.get_node("SettingsWindow")
|
||||
settings.open()
|
||||
@@ -169,8 +203,8 @@ func test_sync_disables_quiz_buttons_until_finished() -> void:
|
||||
_top_bar_button("SyncButton").pressed.emit()
|
||||
sync_window.sync_timer.stop()
|
||||
|
||||
for button_name: String in ["SoundTestButton", "ResetPlaylistButton", "ShowAnswerButton",
|
||||
"NextButton"]:
|
||||
for button_name: String in ["QuizToolbar/SoundTestButton", "QuizToolbar/ResetPlaylistButton", "SongControls/ShowAnswerButton",
|
||||
"SongControls/NextButton"]:
|
||||
assert_bool((_quiz.get_node(button_name) as Button).disabled) \
|
||||
.override_failure_message(button_name + " not disabled").is_true()
|
||||
assert_bool(_top_bar_button("SyncButton").disabled).is_false()
|
||||
@@ -180,8 +214,8 @@ func test_sync_disables_quiz_buttons_until_finished() -> void:
|
||||
sync_window._on_sync_timeout()
|
||||
await _runner.simulate_frames(2)
|
||||
|
||||
for button_name: String in ["SoundTestButton", "ResetPlaylistButton", "ShowAnswerButton",
|
||||
"NextButton"]:
|
||||
for button_name: String in ["QuizToolbar/SoundTestButton", "QuizToolbar/ResetPlaylistButton", "SongControls/ShowAnswerButton",
|
||||
"SongControls/NextButton"]:
|
||||
assert_bool((_quiz.get_node(button_name) as Button).disabled) \
|
||||
.override_failure_message(button_name + " still disabled").is_false()
|
||||
# The search list in the main window and the quiz playlist are both reloaded
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
extends GdUnitTestSuite
|
||||
## Show answer and Next: each reports its press, also from its keyboard shortcut, and
|
||||
## Next is only enabled while a song is ready.
|
||||
|
||||
var _runner: GdUnitSceneRunner
|
||||
var _controls: SongControls
|
||||
|
||||
|
||||
func before_test() -> void:
|
||||
_runner = scene_runner("res://SongControls.tscn")
|
||||
_controls = _runner.scene()
|
||||
|
||||
|
||||
func _click(button: Button) -> void:
|
||||
_runner.set_mouse_position(_controls.get_viewport().get_final_transform()
|
||||
* button.get_global_rect().get_center())
|
||||
await _runner.simulate_mouse_button_pressed(MOUSE_BUTTON_LEFT)
|
||||
await _runner.await_input_processed()
|
||||
|
||||
|
||||
func _press_keys(keys: Array[Key]) -> void:
|
||||
for key: Key in keys:
|
||||
_runner.simulate_key_press(key)
|
||||
await _runner.await_input_processed()
|
||||
keys.reverse()
|
||||
for key: Key in keys:
|
||||
_runner.simulate_key_release(key)
|
||||
await _runner.await_input_processed()
|
||||
|
||||
|
||||
func test_next_starts_disabled() -> void:
|
||||
assert_bool(_controls.next_button.disabled).is_true()
|
||||
|
||||
|
||||
func test_clicking_show_answer_reports_it() -> void:
|
||||
var signals: GdUnitSignalAssert = assert_signal(monitor_signals(_controls))
|
||||
|
||||
await _click(_controls.show_answer_button)
|
||||
|
||||
await signals.is_emitted("show_answer_pressed")
|
||||
|
||||
|
||||
func test_clicking_next_reports_it_when_enabled() -> void:
|
||||
_controls.set_next_enabled(true)
|
||||
var signals: GdUnitSignalAssert = assert_signal(monitor_signals(_controls))
|
||||
|
||||
await _click(_controls.next_button)
|
||||
|
||||
await signals.is_emitted("next_pressed")
|
||||
|
||||
|
||||
func test_clicking_disabled_next_does_nothing() -> void:
|
||||
var signals: GdUnitSignalAssert = assert_signal(monitor_signals(_controls))
|
||||
|
||||
await _click(_controls.next_button)
|
||||
|
||||
await signals.wait_until(200).is_not_emitted("next_pressed")
|
||||
|
||||
|
||||
func test_alt_v_shows_answer_and_alt_c_plays_next() -> void:
|
||||
_controls.set_next_enabled(true)
|
||||
var signals: GdUnitSignalAssert = assert_signal(monitor_signals(_controls))
|
||||
|
||||
await _press_keys([KEY_ALT, KEY_V])
|
||||
await signals.is_emitted("show_answer_pressed")
|
||||
await _press_keys([KEY_ALT, KEY_C])
|
||||
await signals.is_emitted("next_pressed")
|
||||
|
||||
|
||||
func test_locking_disables_both() -> void:
|
||||
_controls.set_next_enabled(true)
|
||||
|
||||
_controls.set_locked(true)
|
||||
|
||||
assert_bool(_controls.show_answer_button.disabled).is_true()
|
||||
assert_bool(_controls.next_button.disabled).is_true()
|
||||
|
||||
|
||||
func test_unlocking_enables_show_answer_but_waits_for_a_song_for_next() -> void:
|
||||
_controls.set_locked(true)
|
||||
|
||||
_controls.set_locked(false)
|
||||
|
||||
assert_bool(_controls.show_answer_button.disabled).is_false()
|
||||
assert_bool(_controls.next_button.disabled).is_true()
|
||||
@@ -0,0 +1 @@
|
||||
uid://c43ii6v73reks
|
||||
@@ -0,0 +1,122 @@
|
||||
extends GdUnitTestSuite
|
||||
## Downloading songs into the Playlist ahead of time, against a fake server.
|
||||
|
||||
const SONG_INFO: Dictionary = {"SongNo": 0, "Soundtrack": "Chrono Trigger", "Song": "Corridors of Time"}
|
||||
|
||||
var _snapshot: AutoloadSnapshot
|
||||
var _server: FakeHttpTransport
|
||||
var _loader: SongLoader
|
||||
|
||||
|
||||
func before_test() -> void:
|
||||
_snapshot = AutoloadSnapshot.take([Settings, Playlist])
|
||||
Playlist.reset_playlist()
|
||||
Playlist.is_song_downloading = false
|
||||
Playlist.number_of_tracks_to_preload = 1
|
||||
Settings.use_low_played_mode = false
|
||||
_server = FakeHttpTransport.new().install()
|
||||
_server.respond_json("/music/list", [])
|
||||
_server.respond_bytes("/music/rand", FileAccess.get_file_as_bytes("res://tests/data/short.mp3"))
|
||||
_server.respond_bytes("/music/addQue", PackedByteArray())
|
||||
_server.respond_json("/music/info", SONG_INFO)
|
||||
_loader = auto_free(SongLoader.new())
|
||||
add_child(_loader)
|
||||
|
||||
|
||||
func after_test() -> void:
|
||||
_server.uninstall()
|
||||
_snapshot.restore()
|
||||
|
||||
|
||||
func test_load_song_list_adds_songs_already_played_on_the_server() -> void:
|
||||
_server.respond_json("/music/list", [
|
||||
{"SongNo": 0, "Soundtrack": "Chrono Trigger", "Song": "Corridors of Time"},
|
||||
])
|
||||
_server.respond_json("/music/info", {"SongNo": 1, "Soundtrack": "Final Fantasy VI", "Song": "Dancing Mad"})
|
||||
var signals: GdUnitSignalAssert = assert_signal(monitor_signals(_loader))
|
||||
|
||||
_loader.load_song_list()
|
||||
|
||||
await signals.is_emitted("song_list_loaded")
|
||||
var first: SongObject = Playlist.song_object_array[0]
|
||||
assert_str(first.soundtrack_title).is_equal("Chrono Trigger")
|
||||
assert_bool(first.has_played).is_true()
|
||||
assert_bool(first.is_answered).is_true()
|
||||
|
||||
|
||||
func test_load_song_list_then_preloads_a_new_song() -> void:
|
||||
_loader.load_song_list()
|
||||
|
||||
assert_int(_server.count("/music/rand")).is_equal(1)
|
||||
assert_int(Playlist.song_object_array.size()).is_equal(1)
|
||||
|
||||
|
||||
func test_fetch_song_downloads_queues_and_adds_the_song() -> void:
|
||||
var signals: GdUnitSignalAssert = assert_signal(monitor_signals(_loader))
|
||||
|
||||
_loader.fetch_song()
|
||||
|
||||
await signals.is_emitted("song_added")
|
||||
assert_array(_server.requested_paths).contains_exactly(["/music/rand", "/music/addQue", "/music/info"])
|
||||
var song: SongObject = Playlist.song_object_array[0]
|
||||
assert_str(song.song_title).is_equal("Corridors of Time")
|
||||
assert_object(song.song).is_not_null()
|
||||
assert_bool(Playlist.is_song_downloading).is_false()
|
||||
|
||||
|
||||
func test_fetch_song_keeps_going_until_the_cache_is_full() -> void:
|
||||
Playlist.number_of_tracks_to_preload = 3
|
||||
|
||||
_loader.fetch_song()
|
||||
|
||||
assert_int(Playlist.song_object_array.size()).is_equal(3)
|
||||
assert_int(_server.count("/music/rand")).is_equal(3)
|
||||
|
||||
|
||||
func test_low_played_mode_uses_its_endpoint() -> void:
|
||||
Settings.use_low_played_mode = true
|
||||
_server.respond_bytes("/music/rand/low", FileAccess.get_file_as_bytes("res://tests/data/short.mp3"))
|
||||
|
||||
_loader.fetch_song()
|
||||
|
||||
assert_int(_server.count("/music/rand/low")).is_equal(1)
|
||||
assert_int(_server.count("/music/rand")).is_equal(0)
|
||||
|
||||
|
||||
func test_fetch_song_if_idle_does_nothing_while_downloading() -> void:
|
||||
Playlist.is_song_downloading = true
|
||||
|
||||
_loader.fetch_song_if_idle()
|
||||
|
||||
assert_int(_server.count("/music/rand")).is_equal(0)
|
||||
|
||||
|
||||
func test_fill_cache_does_nothing_when_the_cache_is_full() -> void:
|
||||
_loader.fetch_song()
|
||||
|
||||
_loader.fill_cache()
|
||||
|
||||
assert_int(_server.count("/music/rand")).is_equal(1)
|
||||
|
||||
|
||||
func test_fill_cache_downloads_after_the_cache_size_grows() -> void:
|
||||
_loader.fetch_song()
|
||||
Playlist.number_of_tracks_to_preload = 2
|
||||
|
||||
_loader.fill_cache()
|
||||
|
||||
assert_int(_server.count("/music/rand")).is_equal(2)
|
||||
|
||||
|
||||
func test_failed_step_is_retried_alone() -> void:
|
||||
_loader.retry_seconds = 0.05
|
||||
_server.fail_after("/music/info", 0)
|
||||
|
||||
_loader.fetch_song()
|
||||
assert_int(Playlist.song_object_array.size()).is_equal(0)
|
||||
_server.respond_json("/music/info", SONG_INFO)
|
||||
await get_tree().create_timer(0.2).timeout
|
||||
|
||||
assert_int(_server.count("/music/rand")).is_equal(1)
|
||||
assert_int(_server.count("/music/addQue")).is_equal(1)
|
||||
assert_int(Playlist.song_object_array.size()).is_equal(1)
|
||||
@@ -0,0 +1 @@
|
||||
uid://caew6u3yi8m4n
|
||||
@@ -24,7 +24,7 @@ func test_winning_turns_statistics_off() -> void:
|
||||
func test_resetting_points_turns_statistics_back_on() -> void:
|
||||
await _give_point_with_keybind(1)
|
||||
|
||||
_press("ResetPointsButton")
|
||||
_press("QuizToolbar/ResetPointsButton")
|
||||
|
||||
assert_bool(Settings.add_to_stats).is_true()
|
||||
|
||||
@@ -33,7 +33,7 @@ func test_statistics_turned_off_by_hand_stay_off_after_reset() -> void:
|
||||
Settings.add_to_stats = false
|
||||
await _give_point_with_keybind(1)
|
||||
|
||||
_press("ResetPointsButton")
|
||||
_press("QuizToolbar/ResetPointsButton")
|
||||
|
||||
assert_bool(Settings.add_to_stats).is_false()
|
||||
|
||||
@@ -41,7 +41,7 @@ func test_statistics_turned_off_by_hand_stay_off_after_reset() -> void:
|
||||
func test_settings_checkbox_shows_statistics_off_after_win() -> void:
|
||||
await _give_point_with_keybind(1)
|
||||
|
||||
_press("SettingsButton")
|
||||
_press("QuizToolbar/SettingsButton")
|
||||
|
||||
assert_bool(_stats_checkbox().button_pressed).is_false()
|
||||
|
||||
@@ -50,13 +50,13 @@ func test_songs_after_a_win_are_not_counted() -> void:
|
||||
await _give_point_with_keybind(1)
|
||||
var played_before: int = _server.count("/music/played?song=0")
|
||||
|
||||
_press("ShowAnswerButton")
|
||||
_press("SongControls/ShowAnswerButton")
|
||||
|
||||
assert_int(_server.count("/music/played?song=0")).is_equal(played_before)
|
||||
|
||||
|
||||
func test_winning_score_cannot_go_below_one() -> void:
|
||||
_press("SettingsButton")
|
||||
_press("QuizToolbar/SettingsButton")
|
||||
var lower_button: Button = _quiz.get_node("SettingsWindow").get_node("%LowerButton")
|
||||
|
||||
for i: int in 3:
|
||||
|
||||
Reference in new issue
Block a user