Short songs (#30): a quiz settings switch and a Seconds per song row (30 by default, 10-120 in steps of 5), saved with the quiz settings. Only part of each quiz song plays, from a random point 10-60% into it, picked once per song so restart and repeat play the same part. The progress bar, time and seeking stay within the part, a hidden beginning counts inside it, and its end counts as the song ending (repeat, stop or go to the next song as set). Random songs (#51): the low-played switch in Settings is now a Normal / Low played / Classic choice, stored as Settings.random_mode and not saved. fetch_random_song(mode) picks /music/rand, /music/rand/low or /music/rand/classic. Closes #30 Closes #51 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
257 lines
8.7 KiB
GDScript
257 lines
8.7 KiB
GDScript
extends GdUnitTestSuite
|
|
## The settings files in the config folder: the settings the game saves by itself, and the
|
|
## config file with the server, password and debug mode that the user edits by hand.
|
|
|
|
const SAVED_VALUES: Dictionary = {
|
|
&"auto_repeat_song": false, &"stop_after_current": false, &"hide_next_track": false,
|
|
&"hide_beginning": true, &"hide_for_seconds": 7.0, &"hide_length": true,
|
|
&"hide_ticks": true, &"winning_score": 13, &"inspiration_list_speed": 4,
|
|
&"fullscreen": true, &"last_seen_version": "1.2.3", &"theme_id": "original_web",
|
|
&"reduce_animations": true,
|
|
&"short_songs": true, &"short_song_seconds": 45,
|
|
}
|
|
|
|
var _snapshot: AutoloadSnapshot
|
|
var _config_dir_before: String
|
|
var _config_dir: String
|
|
|
|
|
|
func before_test() -> void:
|
|
_snapshot = AutoloadSnapshot.take([Settings])
|
|
_config_dir_before = OS.get_environment(Settings.CONFIG_DIR_ENV)
|
|
_config_dir = create_temp_dir("settings_files")
|
|
OS.set_environment(Settings.CONFIG_DIR_ENV, _config_dir)
|
|
DirAccess.remove_absolute(Settings.saved_settings_path())
|
|
DirAccess.remove_absolute(Settings.config_path())
|
|
|
|
|
|
func after_test() -> void:
|
|
OS.set_environment(Settings.CONFIG_DIR_ENV, _config_dir_before)
|
|
_snapshot.restore()
|
|
|
|
|
|
func _set_settings(values: Dictionary) -> void:
|
|
for setting: StringName in values:
|
|
Settings.set(setting, values[setting])
|
|
|
|
|
|
func _write_config(text: String) -> void:
|
|
var file: FileAccess = FileAccess.open(Settings.config_path(), FileAccess.WRITE)
|
|
file.store_string(text)
|
|
file.close()
|
|
|
|
|
|
func _saved_file() -> ConfigFile:
|
|
var file: ConfigFile = ConfigFile.new()
|
|
assert_int(file.load(Settings.saved_settings_path())).is_equal(OK)
|
|
return file
|
|
|
|
|
|
func test_saved_settings_load_back() -> void:
|
|
_set_settings(SAVED_VALUES)
|
|
Settings.save_settings()
|
|
_snapshot.restore()
|
|
|
|
Settings.load_saved_settings()
|
|
|
|
for setting: StringName in SAVED_VALUES:
|
|
assert_that(Settings.get(setting)).override_failure_message(setting) \
|
|
.is_equal(SAVED_VALUES[setting])
|
|
|
|
|
|
func test_every_saved_setting_is_tested() -> void:
|
|
var saved: Array = []
|
|
for section: String in Settings.SAVED_SETTINGS:
|
|
saved.append_array(Settings.SAVED_SETTINGS[section])
|
|
|
|
assert_array(saved).contains_exactly_in_any_order(SAVED_VALUES.keys())
|
|
|
|
|
|
func test_missing_file_keeps_the_current_settings() -> void:
|
|
Settings.winning_score = 9
|
|
|
|
Settings.load_saved_settings()
|
|
|
|
assert_int(Settings.winning_score).is_equal(9)
|
|
|
|
|
|
func test_value_of_the_wrong_type_is_ignored() -> void:
|
|
var file: ConfigFile = ConfigFile.new()
|
|
file.set_value("quiz", "winning_score", "lots")
|
|
file.set_value("quiz", "hide_ticks", true)
|
|
file.save(Settings.saved_settings_path())
|
|
Settings.winning_score = 9
|
|
Settings.hide_ticks = false
|
|
|
|
Settings.load_saved_settings()
|
|
|
|
assert_int(Settings.winning_score).is_equal(9)
|
|
assert_bool(Settings.hide_ticks).is_true()
|
|
|
|
|
|
func test_statistics_settings_are_not_saved() -> void:
|
|
Settings.save_settings()
|
|
|
|
var file: ConfigFile = _saved_file()
|
|
assert_bool(file.has_section_key("quiz", "add_to_stats")).is_false()
|
|
assert_bool(file.has_section_key("quiz", "random_mode")).is_false()
|
|
|
|
|
|
func test_queue_ids_are_saved_and_load_back() -> void:
|
|
Settings.set_queue_id("https://music.example.com", "queue-1")
|
|
Settings.winning_score = 12
|
|
Settings.save_settings()
|
|
Settings.queue_ids.clear()
|
|
|
|
Settings.load_saved_settings()
|
|
|
|
assert_str(_saved_file().get_value("queues", "https://music.example.com")).is_equal("queue-1")
|
|
assert_dict(Settings.queue_ids).is_equal({"https://music.example.com": "queue-1"})
|
|
|
|
|
|
func test_saving_a_queue_id_leaves_the_other_settings_as_saved() -> void:
|
|
Settings.winning_score = 10
|
|
Settings.save_settings()
|
|
Settings.winning_score = 12
|
|
|
|
Settings.set_queue_id("https://music.example.com", "queue-1")
|
|
|
|
var file: ConfigFile = _saved_file()
|
|
assert_int(file.get_value("quiz", "winning_score")).is_equal(10)
|
|
assert_str(file.get_value("queues", "https://music.example.com")).is_equal("queue-1")
|
|
|
|
|
|
func test_saving_a_queue_id_without_a_file_saves_only_the_queue_id() -> void:
|
|
Settings.set_queue_id("https://music.example.com", "queue-1")
|
|
|
|
var file: ConfigFile = _saved_file()
|
|
assert_array(file.get_sections()).contains_exactly(["queues"])
|
|
assert_str(file.get_value("queues", "https://music.example.com")).is_equal("queue-1")
|
|
|
|
|
|
func test_new_queue_id_replaces_only_its_server() -> void:
|
|
Settings.set_queue_id("https://music.example.com", "queue-1")
|
|
Settings.set_queue_id("http://localhost:8080", "local-1")
|
|
Settings.set_queue_id("https://music.example.com", "queue-2")
|
|
|
|
var file: ConfigFile = _saved_file()
|
|
assert_str(file.get_value("queues", "https://music.example.com")).is_equal("queue-2")
|
|
assert_str(file.get_value("queues", "http://localhost:8080")).is_equal("local-1")
|
|
|
|
|
|
func test_file_without_queues_keeps_the_current_queue_ids() -> void:
|
|
Settings.save_settings()
|
|
Settings.queue_ids["https://music.example.com"] = "queue-1"
|
|
|
|
Settings.load_saved_settings()
|
|
|
|
assert_dict(Settings.queue_ids).is_equal({"https://music.example.com": "queue-1"})
|
|
|
|
|
|
func test_fullscreen_is_saved_when_it_changes() -> void:
|
|
Settings.set_fullscreen(true)
|
|
assert_bool(_saved_file().get_value("window", "fullscreen")).is_true()
|
|
|
|
Settings.set_fullscreen(false)
|
|
assert_bool(_saved_file().get_value("window", "fullscreen")).is_false()
|
|
|
|
|
|
func test_files_are_in_the_folder_from_the_environment() -> void:
|
|
assert_str(Settings.saved_settings_path().get_base_dir()).is_equal(_config_dir)
|
|
assert_str(Settings.config_path().get_base_dir()).is_equal(_config_dir)
|
|
|
|
|
|
func test_files_are_in_the_config_folder_without_the_environment() -> void:
|
|
OS.unset_environment(Settings.CONFIG_DIR_ENV)
|
|
|
|
assert_str(Settings.config_dir()).is_equal(OS.get_config_dir().path_join("MusicPlayer"))
|
|
|
|
|
|
func test_debug_mode_saves_to_a_file_of_its_own() -> void:
|
|
Settings.is_debug = true
|
|
var debug_path: String = Settings.saved_settings_path()
|
|
Settings.is_debug = false
|
|
|
|
assert_str(debug_path).is_not_equal(Settings.saved_settings_path())
|
|
|
|
|
|
func test_missing_config_file_is_written_with_everything_commented_out() -> void:
|
|
var config: IniFile = Settings.load_config()
|
|
|
|
assert_bool(FileAccess.file_exists(Settings.config_path())).is_true()
|
|
assert_array(config.get_sections()).is_empty()
|
|
var text: String = FileAccess.get_file_as_string(Settings.config_path())
|
|
for setting: String in ["#url = ", "#password =", "#debug = "]:
|
|
assert_str(text).contains(setting)
|
|
|
|
|
|
func test_commented_out_config_gives_the_defaults() -> void:
|
|
Settings.apply_config(Settings.load_config())
|
|
|
|
assert_bool(Settings.is_debug).is_equal(OS.has_feature("debug"))
|
|
var server: String = Settings.DEBUG_SERVER if Settings.is_debug else Settings.SERVERS[0]
|
|
assert_str(Settings.default_path).is_equal(server)
|
|
assert_str(Settings.api_password).is_empty()
|
|
|
|
|
|
func test_config_sets_server_password_and_debug() -> void:
|
|
_write_config("[server]\nurl = https://tmusic.sanplex.xyz/\n"
|
|
+ "password = secret\n[game]\ndebug = false\n")
|
|
|
|
Settings.apply_config(Settings.load_config())
|
|
|
|
assert_bool(Settings.is_debug).is_false()
|
|
assert_str(Settings.default_path).is_equal("https://tmusic.sanplex.xyz")
|
|
assert_int(Settings.selected_server).is_equal(1)
|
|
assert_array(Settings.servers).is_equal(Settings.SERVERS)
|
|
assert_str(Settings.api_password).is_equal("secret")
|
|
|
|
|
|
func test_server_not_in_the_list_is_added_to_it() -> void:
|
|
_write_config("[server]\nurl = http://music.home:9000\n")
|
|
|
|
Settings.apply_config(Settings.load_config())
|
|
|
|
assert_str(Settings.default_path).is_equal("http://music.home:9000")
|
|
assert_str(Settings.servers[Settings.selected_server]).is_equal("http://music.home:9000")
|
|
assert_int(Settings.servers.size()).is_equal(Settings.SERVERS.size() + 1)
|
|
|
|
|
|
func test_debug_mode_from_the_config_uses_the_local_server() -> void:
|
|
_write_config("[game]\ndebug = true\n")
|
|
|
|
Settings.apply_config(Settings.load_config())
|
|
|
|
assert_bool(Settings.is_debug).is_true()
|
|
assert_str(Settings.default_path).is_equal(Settings.DEBUG_SERVER)
|
|
assert_int(Settings.winning_score).is_equal(Settings.DEBUG_WINNING_SCORE)
|
|
|
|
|
|
func test_both_comment_styles_work() -> void:
|
|
_write_config("# hash comment\n[server]\n; semicolon comment\n#url = http://a\n"
|
|
+ "password = pa;ss#word\n # indented\n[game]\ndebug = false\n")
|
|
|
|
Settings.apply_config(Settings.load_config())
|
|
|
|
assert_str(Settings.api_password).is_equal("pa;ss#word")
|
|
assert_bool(Settings.is_debug).is_false()
|
|
assert_str(Settings.default_path).is_equal(Settings.SERVERS[0])
|
|
|
|
|
|
func test_config_value_of_the_wrong_type_is_ignored() -> void:
|
|
_write_config("[game]\ndebug = maybe\n")
|
|
|
|
Settings.apply_config(Settings.load_config())
|
|
|
|
assert_bool(Settings.is_debug).is_equal(OS.has_feature("debug"))
|
|
|
|
|
|
func test_config_file_is_never_overwritten() -> void:
|
|
_write_config("; mine\n[server]\npassword = secret\n")
|
|
|
|
Settings.load_config()
|
|
Settings.save_settings()
|
|
|
|
assert_str(FileAccess.get_file_as_string(Settings.config_path())) \
|
|
.is_equal("; mine\n[server]\npassword = secret\n")
|