Buttons get 12 px of side padding. The top bar buttons, the quiz toolbar and Show answer/Next are laid out in rows with 12 px gaps and are all 36 px tall, and the ±1 buttons use a compact StepButton style. "Randomize new track" is now "Next song". Player rows show the name and the score apart, alternate like the other lists and highlight the character under the mouse. The name field is a LineEdit with a 10-letter limit; blank and duplicate names are refused, and a full list says "Up to 7 players". Remove buttons update when editing is switched instead of every frame, and the spacer panels are gone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
238 lines
7.3 KiB
GDScript
238 lines
7.3 KiB
GDScript
extends GdUnitTestSuite
|
|
## The player list on its own: adding players through the name field, removing them
|
|
## and asking for a new character.
|
|
|
|
var _snapshot: AutoloadSnapshot
|
|
var _runner: GdUnitSceneRunner
|
|
var _panel: PlayersPanel
|
|
|
|
|
|
func before_test() -> void:
|
|
_snapshot = AutoloadSnapshot.take([Settings])
|
|
Settings.player_array.clear()
|
|
Settings.edit_players = false
|
|
_runner = scene_runner("res://quiz/PlayersPanel.tscn")
|
|
_panel = _runner.scene()
|
|
|
|
|
|
func after_test() -> void:
|
|
await await_idle_frame()
|
|
_snapshot.restore()
|
|
|
|
|
|
func _rows() -> Array[Node]:
|
|
return _panel.players_list_container.get_children()
|
|
|
|
|
|
func _add(player_name: String) -> void:
|
|
_panel.new_player_name_field.text = player_name
|
|
_panel.add_player()
|
|
|
|
|
|
func _click(control: Control) -> void:
|
|
_runner.set_mouse_position(_panel.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_add_button_shows_and_hides_the_add_row() -> void:
|
|
assert_bool(_panel.add_player_container.visible).is_false()
|
|
|
|
await _click(_panel.add_players_button)
|
|
assert_bool(_panel.add_player_container.visible).is_true()
|
|
assert_bool(Settings.edit_players).is_true()
|
|
|
|
await _click(_panel.add_players_button)
|
|
assert_bool(_panel.add_player_container.visible).is_false()
|
|
assert_bool(Settings.edit_players).is_false()
|
|
|
|
|
|
func test_adding_a_name_adds_a_player_and_a_row() -> void:
|
|
var signals: GdUnitSignalAssert = assert_signal(monitor_signals(_panel))
|
|
|
|
_add("Crono")
|
|
|
|
assert_int(Settings.player_array.size()).is_equal(1)
|
|
var crono: PlayerObject = Settings.player_array[0]
|
|
assert_str(crono.player_name).is_equal("Crono")
|
|
await signals.is_emitted("player_added", [crono])
|
|
assert_str(_panel.new_player_name_field.text).is_empty()
|
|
assert_object((_rows()[0] as PlayerRow).player_object).is_same(crono)
|
|
|
|
|
|
func test_add_button_in_the_row_adds_the_player() -> void:
|
|
await _click(_panel.add_players_button)
|
|
_panel.new_player_name_field.text = "Marle"
|
|
|
|
await _click(_panel.add_player_button)
|
|
|
|
assert_int(Settings.player_array.size()).is_equal(1)
|
|
|
|
|
|
func test_enter_in_the_name_field_adds_the_player() -> void:
|
|
await _click(_panel.add_players_button)
|
|
_panel.new_player_name_field.text = "Lucca"
|
|
_panel.new_player_name_field.grab_focus()
|
|
|
|
_runner.simulate_key_pressed(KEY_ENTER)
|
|
await _runner.await_input_processed()
|
|
|
|
assert_array(Settings.player_array.map(
|
|
func(p: PlayerObject) -> String: return p.player_name)).contains_exactly(["Lucca"])
|
|
|
|
|
|
func test_empty_name_adds_nobody() -> void:
|
|
var signals: GdUnitSignalAssert = assert_signal(monitor_signals(_panel))
|
|
|
|
_add("")
|
|
|
|
assert_array(Settings.player_array).is_empty()
|
|
assert_array(_rows()).is_empty()
|
|
await signals.wait_until(200).is_not_emitted("player_added")
|
|
|
|
|
|
func test_cannot_add_more_than_max_players() -> void:
|
|
for i: int in Settings.MAX_NUMBER_OF_PLAYERS + 1:
|
|
_add("Player %d" % i)
|
|
|
|
assert_int(Settings.player_array.size()).is_equal(Settings.MAX_NUMBER_OF_PLAYERS)
|
|
assert_int(_rows().size()).is_equal(Settings.MAX_NUMBER_OF_PLAYERS)
|
|
|
|
|
|
func test_rows_follow_player_order_and_numbering() -> void:
|
|
_add("Crono")
|
|
_add("Marle")
|
|
_add("Lucca")
|
|
|
|
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])
|
|
|
|
|
|
func test_remove_button_removes_the_player_and_row() -> void:
|
|
_add("Crono")
|
|
_add("Marle")
|
|
var crono: PlayerObject = Settings.player_array[0]
|
|
var signals: GdUnitSignalAssert = assert_signal(monitor_signals(_panel))
|
|
|
|
(_rows()[0].get_node("%RemovePlayer") as BaseButton).pressed.emit()
|
|
|
|
await signals.is_emitted("player_removed", [crono])
|
|
assert_array(Settings.player_array.map(
|
|
func(p: PlayerObject) -> String: return p.player_name)).contains_exactly(["Marle"])
|
|
assert_int(_rows().size()).is_equal(1)
|
|
assert_int((_rows()[0] as PlayerRow).list_index).is_equal(0)
|
|
|
|
|
|
func test_character_button_asks_for_a_new_character() -> void:
|
|
_add("Crono")
|
|
var row: PlayerRow = _rows()[0]
|
|
var signals: GdUnitSignalAssert = assert_signal(monitor_signals(_panel))
|
|
|
|
(row.get_node("%Character") as BaseButton).pressed.emit()
|
|
|
|
await signals.is_emitted("change_character_requested", [row, "Crono"])
|
|
|
|
|
|
func test_reload_shows_new_scores() -> void:
|
|
_add("Crono")
|
|
Settings.player_array[0].player_score = 3
|
|
|
|
_panel.reload()
|
|
|
|
assert_str((_rows()[0] as PlayerRow).score_label.text).is_equal("3")
|
|
|
|
|
|
func test_row_shows_the_name_and_the_score_apart() -> void:
|
|
_add("Crono")
|
|
var row: PlayerRow = _rows()[0]
|
|
|
|
row.add_point()
|
|
row.add_point()
|
|
|
|
assert_str(row.player_name_field.text).is_equal("Crono")
|
|
assert_str(row.score_label.text).is_equal("2")
|
|
|
|
|
|
func test_names_are_trimmed_and_blank_ones_refused() -> void:
|
|
_add(" Crono ")
|
|
_add(" ")
|
|
|
|
assert_array(Settings.player_array.map(
|
|
func(p: PlayerObject) -> String: return p.player_name)).contains_exactly(["Crono"])
|
|
|
|
|
|
func test_a_name_can_only_be_used_once() -> void:
|
|
_add("Crono")
|
|
_add("crono")
|
|
|
|
assert_int(Settings.player_array.size()).is_equal(1)
|
|
assert_str(_panel.new_player_name_field.text).is_equal("crono")
|
|
|
|
|
|
func test_name_field_takes_at_most_ten_letters() -> void:
|
|
_panel.new_player_name_field.insert_text_at_caret("Abcdefghijklmnop")
|
|
|
|
assert_str(_panel.new_player_name_field.text).is_equal("Abcdefghij")
|
|
|
|
|
|
func test_full_list_says_so_instead_of_offering_the_name_field() -> void:
|
|
await _click(_panel.add_players_button)
|
|
for i: int in Settings.MAX_NUMBER_OF_PLAYERS:
|
|
_add("Player %d" % i)
|
|
|
|
assert_bool(_panel.add_player_hint.visible).is_true()
|
|
assert_str(_panel.add_player_hint.text).is_equal("Up to 7 players")
|
|
assert_bool(_panel.new_player_name_field.visible).is_false()
|
|
|
|
(_rows()[0].get_node("%RemovePlayer") as BaseButton).pressed.emit()
|
|
|
|
assert_bool(_panel.add_player_hint.visible).is_false()
|
|
assert_bool(_panel.new_player_name_field.visible).is_true()
|
|
|
|
|
|
func test_remove_buttons_show_only_while_editing() -> void:
|
|
_add("Crono")
|
|
var remove: Control = _rows()[0].get_node("%RemovePlayer")
|
|
assert_bool(remove.visible).is_false()
|
|
|
|
await _click(_panel.add_players_button)
|
|
assert_bool((_rows()[0].get_node("%RemovePlayer") as Control).visible).is_true()
|
|
|
|
await _click(_panel.add_players_button)
|
|
assert_bool((_rows()[0].get_node("%RemovePlayer") as Control).visible).is_false()
|
|
|
|
|
|
func test_rows_alternate_like_the_other_lists() -> void:
|
|
_add("Crono")
|
|
_add("Marle")
|
|
_add("Lucca")
|
|
|
|
assert_array(_rows().map(func(row: PlayerRow) -> String: return row.theme_type_variation)) \
|
|
.contains_exactly(["ListRowEven", "ListRowOdd", "ListRowEven"])
|
|
|
|
|
|
func test_character_is_highlighted_under_the_mouse() -> void:
|
|
_add("Crono")
|
|
var row: PlayerRow = _rows()[0]
|
|
|
|
row.character.mouse_entered.emit()
|
|
assert_str(row.character_frame.theme_type_variation).is_equal("PlayerCharacterHover")
|
|
row.character.mouse_exited.emit()
|
|
assert_str(row.character_frame.theme_type_variation).is_equal("PlayerCharacter")
|
|
assert_str(row.character.tooltip_text).is_equal("Change character")
|
|
|
|
|
|
func test_seven_players_fit_without_scrolling_while_adding() -> void:
|
|
await _click(_panel.add_players_button)
|
|
for i: int in Settings.MAX_NUMBER_OF_PLAYERS:
|
|
_add("Player %d" % i)
|
|
await _runner.simulate_frames(2)
|
|
|
|
var panel: Rect2 = _panel.get_global_rect()
|
|
var last: Rect2 = (_rows().back() as Control).get_global_rect()
|
|
assert_bool(panel.encloses(last)).is_true()
|