Follow the GDScript style guide in every script
- Types on every parameter, return value and variable, and snake_case names (the player name limit is the constant MAX_NAME_LENGTH). - Spelling fixes: *_triggered, character_selected, separator, caught_errors. The server's catched_errors key stays as the server sends it. - Signals are connected with signal.connect() instead of by name. - Code is ordered signals, constants, exported vars, vars, @onready vars, functions, with @onready on one line and two blank lines between functions. - Every script starts with a ## description. Template comments, old LOC notes and commented-out code are gone, apart from the local play code. - Lines are at most 100 characters, apart from the local play path. - The screenshot tour turns off the blinking text cursor so pictures match.
This commit is contained in:
1 parent
674604425f
commit
a0428e3475
45 files changed
+580
-589
No files matched your search
@@ -87,6 +87,7 @@ static func prepare_autoloads() -> void:
|
||||
func run(on_state: Callable) -> void:
|
||||
# The debug build lowers the winning score on startup; keep it out of reach
|
||||
Settings.winning_score = 20
|
||||
_stop_caret_blink(_main)
|
||||
await _settle()
|
||||
await on_state.call("startup", null)
|
||||
|
||||
@@ -194,6 +195,14 @@ func _call(method: String, args: Array = []) -> Variant:
|
||||
return _main.callv(method, args)
|
||||
|
||||
|
||||
# A blinking text cursor would be shown in some pictures and not in others
|
||||
func _stop_caret_blink(node: Node) -> void:
|
||||
if node is TextEdit || node is LineEdit:
|
||||
node.caret_blink = false
|
||||
for child: Node in node.get_children():
|
||||
_stop_caret_blink(child)
|
||||
|
||||
|
||||
func _server() -> FakeHttpTransport:
|
||||
return MusicServerClient.transport
|
||||
|
||||
|
||||
@@ -58,9 +58,14 @@ const RENAMED_SCENES: Dictionary = {
|
||||
"Player": "PlayerRow",
|
||||
}
|
||||
|
||||
## Nodes renamed inside a popup: old path from the main window, and new path.
|
||||
const SYNC_COLUMNS: String = "SyncPopup/SyncPanel/ScrollContainer/SyncVBoxContainer"
|
||||
|
||||
## Nodes renamed inside a popup: the path after the moves above, and the new path.
|
||||
const RENAMED_PATHS: Dictionary = {
|
||||
"SearchPopup/ScrollContainer/VBoxContainer": "SearchPopup/ScrollContainer/SearchResults",
|
||||
SYNC_COLUMNS + "/CatchedErrorsVBox": SYNC_COLUMNS + "/CaughtErrorsVBox",
|
||||
SYNC_COLUMNS + "/CaughtErrorsVBox/CatchedErrorsLabel":
|
||||
SYNC_COLUMNS + "/CaughtErrorsVBox/CaughtErrorsLabel",
|
||||
}
|
||||
|
||||
## How far a node may be from its old place, in pixels.
|
||||
@@ -102,9 +107,10 @@ static func new_path(old_path: String) -> String:
|
||||
var first: String = parts[0]
|
||||
parts[0] = MOVED.get(first, first)
|
||||
var path: String = "/".join(parts)
|
||||
# In order, so a node inside a renamed node is found after its parent's rename
|
||||
for renamed: String in RENAMED_PATHS:
|
||||
if path == renamed || path.begins_with(renamed + "/"):
|
||||
return RENAMED_PATHS[renamed] + path.trim_prefix(renamed)
|
||||
path = RENAMED_PATHS[renamed] + path.trim_prefix(renamed)
|
||||
return path
|
||||
|
||||
|
||||
|
||||
@@ -105,7 +105,8 @@ func test_rows_follow_player_order_and_numbering() -> void:
|
||||
_add("Marle")
|
||||
_add("Lucca")
|
||||
|
||||
assert_array(_rows().map(func(row: PlayerRow) -> String: return row.player_object.player_name)) \
|
||||
assert_array(_rows().map(
|
||||
func(row: PlayerRow) -> String: return row.player_object.player_name)) \
|
||||
.contains_exactly(["Crono", "Marle", "Lucca"])
|
||||
assert_array(_rows().map(func(row: PlayerRow) -> int: return row.list_index)) \
|
||||
.contains_exactly([0, 1, 2])
|
||||
|
||||
@@ -9,6 +9,12 @@ const MAIN_WINDOW_CHILDREN: Array[String] = [
|
||||
"ShortcutsPopup", "StatisticsPopupPanel", "AboutPopup", "LogPopup",
|
||||
]
|
||||
|
||||
## The quiz buttons that are disabled while the server syncs.
|
||||
const LOCKED_BY_SYNC: Array[String] = [
|
||||
"QuizToolbar/SoundTestButton", "QuizToolbar/ResetPlaylistButton",
|
||||
"SongControls/ShowAnswerButton", "SongControls/NextButton",
|
||||
]
|
||||
|
||||
const TOP_BAR_CHILDREN: Array[String] = [
|
||||
"TopPanelContainer", "Title", "SyncButton", "SearchButton", "StatisticsButton",
|
||||
"ShortcutsButton", "AboutButton", "QRButton",
|
||||
@@ -130,7 +136,8 @@ func test_points_from_the_player_list_reach_the_song_and_log() -> void:
|
||||
(_player_row(crono).get_node("HBoxContainer/AddPoint") as BaseButton).pressed.emit()
|
||||
|
||||
assert_array(Playlist.song_object_array[0].players_given_point).contains_exactly([crono.id])
|
||||
assert_int((_window.get_node("%LogPopup").get_node("%LogVBoxContainer") as Node).get_child_count()) \
|
||||
var log_rows: Node = _window.get_node("%LogPopup").get_node("%LogVBoxContainer")
|
||||
assert_int(log_rows.get_child_count()) \
|
||||
.is_equal(1)
|
||||
|
||||
|
||||
@@ -143,12 +150,13 @@ func test_character_button_in_the_player_list_picks_a_new_character() -> void:
|
||||
assert_bool(character_select.visible).is_true()
|
||||
var texture: ImageTexture = ImageTexture.create_from_image(
|
||||
Image.create(4, 4, false, Image.FORMAT_RGBA8))
|
||||
character_select.new_new_character_selected.emit(texture)
|
||||
character_select.character_selected.emit(texture)
|
||||
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"))
|
||||
_server.respond_bytes("/music/soundTest",
|
||||
FileAccess.get_file_as_bytes("res://tests/data/short.mp3"))
|
||||
|
||||
await _click_at(_center(_quiz.get_node("QuizToolbar/SoundTestButton")))
|
||||
|
||||
@@ -166,7 +174,8 @@ func test_loaded_song_list_shows_in_the_music_list() -> void:
|
||||
|
||||
_quiz.song_loader.load_song_list()
|
||||
|
||||
var rows: Array[Node] = _quiz.get_node("MusicListPanel/ScrollContainer/MusicList").get_children()
|
||||
var rows: Array[Node] = _quiz.get_node("MusicListPanel/ScrollContainer/MusicList") \
|
||||
.get_children()
|
||||
assert_array(rows.map(func(row: SongRow) -> int: return row.song_object.song_number)) \
|
||||
.contains_exactly([0, 1])
|
||||
|
||||
@@ -203,8 +212,7 @@ func test_sync_disables_quiz_buttons_until_finished() -> void:
|
||||
_top_bar_button("SyncButton").pressed.emit()
|
||||
sync_popup.sync_timer.stop()
|
||||
|
||||
for button_name: String in ["QuizToolbar/SoundTestButton", "QuizToolbar/ResetPlaylistButton", "SongControls/ShowAnswerButton",
|
||||
"SongControls/NextButton"]:
|
||||
for button_name: String in LOCKED_BY_SYNC:
|
||||
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()
|
||||
@@ -214,8 +222,7 @@ func test_sync_disables_quiz_buttons_until_finished() -> void:
|
||||
sync_popup._on_sync_timeout()
|
||||
await _runner.simulate_frames(2)
|
||||
|
||||
for button_name: String in ["QuizToolbar/SoundTestButton", "QuizToolbar/ResetPlaylistButton", "SongControls/ShowAnswerButton",
|
||||
"SongControls/NextButton"]:
|
||||
for button_name: String in LOCKED_BY_SYNC:
|
||||
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
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
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"}
|
||||
const SONG_INFO: Dictionary = {
|
||||
"SongNo": 0, "Soundtrack": "Chrono Trigger", "Song": "Corridors of Time",
|
||||
}
|
||||
|
||||
var _snapshot: AutoloadSnapshot
|
||||
var _server: FakeHttpTransport
|
||||
@@ -32,7 +34,8 @@ 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"})
|
||||
_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()
|
||||
@@ -57,7 +60,8 @@ func test_fetch_song_downloads_queues_and_adds_the_song() -> void:
|
||||
_loader.fetch_song()
|
||||
|
||||
await signals.is_emitted("song_added")
|
||||
assert_array(_server.requested_paths).contains_exactly(["/music/rand", "/music/addQue", "/music/info"])
|
||||
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()
|
||||
@@ -75,7 +79,8 @@ func test_fetch_song_keeps_going_until_the_cache_is_full() -> void:
|
||||
|
||||
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"))
|
||||
_server.respond_bytes("/music/rand/low",
|
||||
FileAccess.get_file_as_bytes("res://tests/data/short.mp3"))
|
||||
|
||||
_loader.fetch_song()
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
extends GdUnitTestSuite
|
||||
## The sync popup on its own: starting a sync, its progress, and how the result is shown.
|
||||
|
||||
var _server: FakeHttpTransport
|
||||
var _snapshot: AutoloadSnapshot
|
||||
@@ -132,7 +133,7 @@ func test_errors_are_listed() -> void:
|
||||
|
||||
_finish_sync(result)
|
||||
|
||||
assert_bool(_node("CatchedErrorsVBox").visible).is_true()
|
||||
assert_bool(_node("CaughtErrorsVBox").visible).is_true()
|
||||
|
||||
|
||||
func test_reopening_after_sync_shows_result_without_syncing_again() -> void:
|
||||
@@ -152,7 +153,7 @@ func test_errors_section_has_errors_header() -> void:
|
||||
|
||||
_finish_sync(result)
|
||||
|
||||
assert_str((_node("CatchedErrorsVBox").get_child(0) as Label).text).is_equal("Errors")
|
||||
assert_str((_node("CaughtErrorsVBox").get_child(0) as Label).text).is_equal("Errors")
|
||||
|
||||
|
||||
func test_long_names_wrap_instead_of_widening_the_window() -> void:
|
||||
@@ -173,7 +174,7 @@ func test_long_names_wrap_instead_of_widening_the_window() -> void:
|
||||
var panel_width: float = (_window.get_node("SyncPanel") as Control).size.x
|
||||
assert_float(_node("SyncHBoxContainer").get_combined_minimum_size().x) \
|
||||
.is_less(panel_width)
|
||||
assert_float(_node("CatchedErrorsVBox").get_combined_minimum_size().x) \
|
||||
assert_float(_node("CaughtErrorsVBox").get_combined_minimum_size().x) \
|
||||
.is_less(panel_width)
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
extends GdUnitTestSuite
|
||||
## ListRow: text, alternating backgrounds and wrapping.
|
||||
|
||||
|
||||
func _background(list_row: ListRow) -> Color:
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
extends GdUnitTestSuite
|
||||
## How the music player shows a song's time, including the hidden parts.
|
||||
|
||||
var _music_player: MusicPlayer
|
||||
var _hide_beginning: bool
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
extends GdUnitTestSuite
|
||||
## MusicServerClient: which paths it asks for and how it handles the answers.
|
||||
|
||||
var _server: FakeHttpTransport
|
||||
|
||||
@@ -115,7 +116,8 @@ func test_mark_song_played_sends_put() -> void:
|
||||
|
||||
|
||||
func test_character_name_is_url_encoded() -> void:
|
||||
MusicServerClient.fetch_character_image("Paper Mario.png", func(_body: PackedByteArray) -> void: pass)
|
||||
MusicServerClient.fetch_character_image("Paper Mario.png",
|
||||
func(_body: PackedByteArray) -> void: pass)
|
||||
|
||||
assert_array(_server.requested_paths).contains_exactly(["/character?name=Paper%20Mario.png"])
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
extends GdUnitTestSuite
|
||||
## PlayerObject: points, and the first point, match point and winner signals.
|
||||
|
||||
var _winning_score: int
|
||||
var _player: PlayerObject
|
||||
@@ -20,7 +21,7 @@ func test_first_point_triggers_first_point_signal() -> void:
|
||||
_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("first_point_triggered")
|
||||
await assert_signal(_player).is_emitted("player_point_given")
|
||||
|
||||
|
||||
@@ -30,7 +31,7 @@ func test_one_point_from_winning_triggers_match_point() -> void:
|
||||
|
||||
_player.add_point()
|
||||
|
||||
await assert_signal(_player).is_emitted("match_point_triggerd")
|
||||
await assert_signal(_player).is_emitted("match_point_triggered")
|
||||
|
||||
|
||||
func test_reaching_winning_score_triggers_winner() -> void:
|
||||
@@ -41,7 +42,7 @@ func test_reaching_winning_score_triggers_winner() -> void:
|
||||
_player.add_point()
|
||||
|
||||
assert_int(_player.player_score).is_equal(3)
|
||||
await assert_signal(_player).is_emitted("winner_triggerd")
|
||||
await assert_signal(_player).is_emitted("winner_triggered")
|
||||
|
||||
|
||||
func test_score_does_not_go_past_winning_score() -> void:
|
||||
@@ -91,7 +92,7 @@ func test_dropping_back_to_zero_allows_first_point_again() -> void:
|
||||
|
||||
_player.add_point()
|
||||
|
||||
await assert_signal(_player).is_emitted("first_point_triggerd")
|
||||
await assert_signal(_player).is_emitted("first_point_triggered")
|
||||
|
||||
|
||||
func test_reset_points() -> void:
|
||||
@@ -125,7 +126,7 @@ func test_winning_score_of_one_is_won_with_first_point() -> void:
|
||||
|
||||
_player.add_point()
|
||||
|
||||
await assert_signal(_player).is_emitted("winner_triggerd")
|
||||
await assert_signal(_player).is_emitted("winner_triggered")
|
||||
|
||||
|
||||
func test_first_point_is_match_point_when_winning_score_is_two() -> void:
|
||||
@@ -134,5 +135,5 @@ func test_first_point_is_match_point_when_winning_score_is_two() -> void:
|
||||
|
||||
_player.add_point()
|
||||
|
||||
await assert_signal(_player).is_emitted("match_point_triggerd")
|
||||
await assert_signal(_player).is_emitted("match_point_triggered")
|
||||
assert_bool(_player.is_first_point).is_false()
|
||||
@@ -1,4 +1,5 @@
|
||||
extends GdUnitTestSuite
|
||||
## Playlist: moving through the songs, answering them and keeping points.
|
||||
|
||||
var _server: FakeHttpTransport
|
||||
var _add_to_stats: bool
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
extends GdUnitTestSuite
|
||||
## How the search popup finds and orders matching soundtracks.
|
||||
|
||||
const SearchWindowScript: GDScript = preload("res://search_popup.gd")
|
||||
|
||||
@@ -36,7 +37,8 @@ func test_ignores_spaces() -> void:
|
||||
|
||||
|
||||
func test_and_matches_ampersand() -> void:
|
||||
assert_array(_search.find_matches("mario and luigi")).contains(["Mario & Luigi: Superstar Saga"])
|
||||
assert_array(_search.find_matches("mario and luigi")) \
|
||||
.contains(["Mario & Luigi: Superstar Saga"])
|
||||
|
||||
|
||||
func test_accented_letters_match_plain_letters() -> void:
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
extends GdUnitTestSuite
|
||||
## Settings: the version number.
|
||||
|
||||
|
||||
func test_version_comes_from_project_settings() -> void:
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
extends GdUnitTestSuite
|
||||
## SongObject: what it shows before and after the answer, and its points.
|
||||
|
||||
var _is_debug: bool
|
||||
var _song: SongObject
|
||||
|
||||
Reference in new issue
Block a user