- A Quiz settings button under the player bar opens a small card above it with the quiz settings, including Auto repeat, which moves there from under the player bar. The card does not dim the quiz, so it can be changed during a song, and grows to fit its rows. - A Settings button in the top bar opens the application settings: server, fullscreen and songs to download ahead. Quick sync is gone, as the server no longer has it, and the server list is in Settings. - Labels use sentence case, and seconds to hide show as whole numbers. - Debug builds switch to the local server and a low winning score in the Settings autoload, before any scene asks the server for anything. The DEBUG label moves to the top bar, so it shows on every tab. - Search moves from the top bar back to the quiz toolbar, as the Statistics tab has its own search.
144 lines
4.3 KiB
GDScript
144 lines
4.3 KiB
GDScript
extends MainWindowTestSuite
|
|
## The Search popup: typing, the result list, the count, the highlighted letters and
|
|
## the layout.
|
|
|
|
const SOUNDTRACKS: Array[String] = [
|
|
"Chrono Trigger", "Final Fantasy VI", "Mario & Luigi: Superstar Saga", "Super Mario 64",
|
|
"The Legend of Zelda: A Link to the Past",
|
|
]
|
|
|
|
var _popup: SearchPopup
|
|
|
|
|
|
func _before_window_starts() -> void:
|
|
_server.respond_json("/music/all/order", SOUNDTRACKS)
|
|
|
|
|
|
func before_test() -> void:
|
|
super()
|
|
_popup = _window.get_node("SearchPopup")
|
|
|
|
|
|
func _open() -> void:
|
|
await _click_at(_quiz.get_node("QuizToolbar/SearchButton").get_global_rect().get_center())
|
|
await _runner.simulate_frames(1)
|
|
|
|
|
|
func _type(text: String) -> void:
|
|
for letter: String in text:
|
|
_popup.search_field.insert_text_at_caret(letter)
|
|
_popup.search_field.text_changed.emit(_popup.search_field.text)
|
|
|
|
|
|
func _row_texts() -> Array[String]:
|
|
var texts: Array[String] = []
|
|
for row: PanelContainer in _popup.search_results.get_children():
|
|
if row.visible:
|
|
texts.append((row.get_child(0) as RichTextLabel).text)
|
|
return texts
|
|
|
|
|
|
func test_shows_every_soundtrack_with_a_count() -> void:
|
|
await _open()
|
|
|
|
assert_array(_popup.shown_names()).contains_exactly(SOUNDTRACKS)
|
|
assert_str(_popup.count_label.text).is_equal("5 soundtracks")
|
|
assert_bool(_popup.empty_label.visible).is_false()
|
|
assert_bool(_popup.search_field.has_focus()).is_true()
|
|
|
|
|
|
func test_typing_filters_and_counts() -> void:
|
|
await _open()
|
|
|
|
_type("mario")
|
|
|
|
assert_array(_popup.shown_names()) \
|
|
.contains_exactly(["Mario & Luigi: Superstar Saga", "Super Mario 64"])
|
|
assert_str(_popup.count_label.text).is_equal("2 of 5 soundtracks")
|
|
|
|
|
|
func test_enter_does_not_break_the_search() -> void:
|
|
await _open()
|
|
_type("chrono")
|
|
|
|
_runner.simulate_key_pressed(KEY_ENTER)
|
|
await _runner.await_input_processed()
|
|
|
|
assert_str(_popup.search_field.text).is_equal("chrono")
|
|
assert_array(_popup.shown_names()).contains_exactly(["Chrono Trigger"])
|
|
|
|
|
|
func test_no_match_says_so() -> void:
|
|
await _open()
|
|
|
|
_type("metroid")
|
|
|
|
assert_array(_popup.shown_names()).is_empty()
|
|
assert_bool(_popup.empty_label.visible).is_true()
|
|
assert_str(_popup.count_label.text).is_equal("0 of 5 soundtracks")
|
|
|
|
|
|
func test_short_search_does_not_match_letters_far_apart() -> void:
|
|
await _open()
|
|
|
|
_type("sm")
|
|
|
|
assert_array(_popup.shown_names()).is_empty()
|
|
_type("r")
|
|
assert_array(_popup.shown_names()).contains_exactly(["Super Mario 64"])
|
|
|
|
|
|
func test_matched_letters_are_highlighted() -> void:
|
|
await _open()
|
|
var color: String = _popup.get_theme_color(&"font_color", &"HighlightLarge").to_html(false)
|
|
|
|
_type("trig")
|
|
|
|
assert_array(_row_texts()).contains_exactly(["Chrono [color=#%s]Trig[/color]ger" % color])
|
|
|
|
|
|
func test_letters_in_order_are_highlighted_one_by_one() -> void:
|
|
var color: Color = Color.ORANGE
|
|
var text: String = SearchPopup.highlighted_name("Super Mario 64", "smr", color)
|
|
var c: String = color.to_html(false)
|
|
|
|
assert_str(text).is_equal(
|
|
"[color=#%s]S[/color]uper [color=#%s]M[/color]a[color=#%s]r[/color]io 64" % [c, c, c])
|
|
|
|
|
|
func test_square_brackets_in_names_are_shown_as_text() -> void:
|
|
assert_str(SearchPopup.highlighted_name("Disc [1]", "", Color.ORANGE)) \
|
|
.is_equal("Disc [lb]1]")
|
|
|
|
|
|
func test_clear_shows_everything_again_without_highlights() -> void:
|
|
await _open()
|
|
_type("mario")
|
|
|
|
await _click_at(_popup.clear_button.get_global_rect().get_center())
|
|
|
|
assert_str(_popup.search_field.text).is_empty()
|
|
assert_array(_row_texts()).contains_exactly(SOUNDTRACKS)
|
|
|
|
|
|
func test_rows_alternate_like_the_other_lists() -> void:
|
|
await _open()
|
|
_type("mario")
|
|
|
|
var rows: Array[Node] = _popup.search_results.get_children().filter(
|
|
func(row: Control) -> bool: return row.visible)
|
|
assert_str(String(rows[0].theme_type_variation)).is_equal("ListRowEven")
|
|
assert_str(String(rows[1].theme_type_variation)).is_equal("ListRowOdd")
|
|
|
|
|
|
func test_everything_fits_inside_the_panel_at_its_real_size() -> void:
|
|
await _open()
|
|
|
|
var panel: Rect2 = _popup.search_panel.get_global_rect()
|
|
for node: Control in [_popup.search_field, _popup.clear_button, _popup.count_label,
|
|
_popup.search_results.get_parent()]:
|
|
assert_bool(panel.encloses(node.get_global_rect())) \
|
|
.override_failure_message(node.name + " is outside the panel").is_true()
|
|
assert_vector(node.scale).is_equal(Vector2.ONE)
|
|
assert_bool(Rect2(Vector2.ZERO, Vector2(1920, 1080)).encloses(panel)).is_true()
|