At startup and after resetting the playlist, loading the song list and preloading the first song started at the same time. When the list answered last, it cleared the playlist and dropped the preloaded song. Preloading now starts once the list has loaded, and loading the list is retried if it fails.
123 lines
4.2 KiB
GDScript
123 lines
4.2 KiB
GDScript
class_name MainWindowTestSuite
|
|
extends GdUnitTestSuite
|
|
## Base for tests that run the real main window against a fake MusicServer.
|
|
|
|
const SONG_INFO: Array[Dictionary] = [
|
|
{"SongNo": 0, "Soundtrack": "Chrono Trigger", "Song": "Corridors of Time"},
|
|
{"SongNo": 1, "Soundtrack": "Final Fantasy VI", "Song": "Dancing Mad"},
|
|
]
|
|
|
|
var _server: FakeHttpTransport
|
|
var _snapshot: AutoloadSnapshot
|
|
var _runner: GdUnitSceneRunner
|
|
var _window: Control
|
|
|
|
|
|
func before_test() -> void:
|
|
_snapshot = AutoloadSnapshot.take([Settings, Playlist])
|
|
Playlist.reset_playlist()
|
|
Playlist.first_song_played = false
|
|
Playlist.is_song_downloading = false
|
|
Settings.player_array.clear()
|
|
Settings.add_to_stats = true
|
|
Settings.hide_next_track = true
|
|
Settings.use_low_played_mode = false
|
|
Settings.winning_score = 20
|
|
|
|
_server = FakeHttpTransport.new().install()
|
|
var mp3: PackedByteArray = FileAccess.get_file_as_bytes("res://tests/data/short.mp3")
|
|
_server.respond_json("/music/all", ["Chrono Trigger", "Final Fantasy VI"])
|
|
_server.respond_json("/music/all/order", ["Chrono Trigger", "Final Fantasy VI"])
|
|
_server.respond_json("/music/list", [])
|
|
_server.respond_json("/characters", [])
|
|
_server.respond_bytes("/music/rand", mp3)
|
|
_server.respond_bytes("/music/addQue", PackedByteArray())
|
|
_server.respond_json("/music/info", SONG_INFO[0])
|
|
_server.respond_bytes("/music/reset", PackedByteArray())
|
|
_server.respond_bytes("/music/played?song=0", PackedByteArray())
|
|
|
|
_before_window_starts()
|
|
_runner = scene_runner("res://MainWindow.tscn")
|
|
_window = _runner.scene()
|
|
# The debug build lowers the winning score on startup; keep it out of reach
|
|
Settings.winning_score = 20
|
|
|
|
|
|
## Override to change the fake server before the window starts and sends its first
|
|
## requests.
|
|
func _before_window_starts() -> void:
|
|
pass
|
|
|
|
|
|
func after_test() -> void:
|
|
# Let nodes queued for deletion by the window be freed before orphans are counted
|
|
await await_idle_frame()
|
|
_server.uninstall()
|
|
_snapshot.restore()
|
|
|
|
|
|
## Makes the next song the server hands out the one described by [param info].
|
|
func _next_song_is(info: Dictionary) -> void:
|
|
_server.respond_json("/music/info", info)
|
|
|
|
|
|
func _press(button_path: String) -> void:
|
|
(_window.get_node(button_path) as Button).pressed.emit()
|
|
|
|
|
|
## Presses Next and waits until the first song is playing.
|
|
func _play_first_song() -> void:
|
|
_press("NextButton")
|
|
await _runner.simulate_frames(2)
|
|
|
|
|
|
## Adds a player through the name field, the same way the user does.
|
|
func _add_player(player_name: String) -> PlayerObject:
|
|
var name_field: TextEdit = _window.get_node(
|
|
"Players/VBoxContainer/AddPlayerContainer/PlayerNameField")
|
|
name_field.text = player_name
|
|
_runner.invoke("add_player")
|
|
return Settings.player_array.back() if !Settings.player_array.is_empty() else null
|
|
|
|
|
|
## Returns the row in the player list that shows [param player_object].
|
|
func _player_row(player_object: PlayerObject) -> Player:
|
|
var rows: Node = _window.get_node(
|
|
"Players/VBoxContainer/ScrollContainer/PlayersListVBoxContainer")
|
|
for row: Player in rows.get_children():
|
|
if row.player_object == player_object:
|
|
return row
|
|
return null
|
|
|
|
|
|
## Removes a player with the remove button in its row.
|
|
func _remove_player(player_object: PlayerObject) -> void:
|
|
(_player_row(player_object).get_node("HBoxContainer/RemovePlayer") as BaseButton) \
|
|
.pressed.emit()
|
|
await _runner.simulate_frames(1)
|
|
|
|
|
|
## Presses [param keys] together, e.g. [code][KEY_ALT, KEY_1][/code], then releases them.
|
|
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()
|
|
|
|
|
|
## Gives a point with Alt+<number>.
|
|
func _give_point_with_keybind(number: int) -> void:
|
|
await _press_keys([KEY_ALT, (KEY_0 + number) as Key])
|
|
|
|
|
|
## Takes a point with Ctrl+Alt+<number>.
|
|
func _take_point_with_keybind(number: int) -> void:
|
|
await _press_keys([KEY_CTRL, KEY_ALT, (KEY_0 + number) as Key])
|
|
|
|
|
|
func _scores() -> Array:
|
|
return Settings.player_array.map(func(p: PlayerObject) -> int: return p.player_score)
|