115 lines
5.3 KiB
GDScript
115 lines
5.3 KiB
GDScript
extends SceneTree
|
|
|
|
const EntryShell = preload("res://entry/entry_shell.gd")
|
|
const SettingsStore = preload("res://entry/settings_store.gd")
|
|
const SETTINGS_PATH := "user://dev1_settings_credits_test.json"
|
|
|
|
var failures: Array[String] = []
|
|
|
|
|
|
func _initialize() -> void:
|
|
call_deferred("run_test")
|
|
|
|
|
|
func run_test() -> void:
|
|
_cleanup()
|
|
var shell = EntryShell.new()
|
|
shell.auto_start = false
|
|
shell.settings_store.path = SETTINGS_PATH
|
|
root.add_child(shell)
|
|
await process_frame
|
|
shell.settings = shell.settings_store.defaults()
|
|
shell.settings.setup_completed = true
|
|
shell.settings.locale = "en"
|
|
shell.show_title()
|
|
shell.show_settings()
|
|
await process_frame
|
|
verify_categories(shell)
|
|
verify_apply_discard_and_runtime(shell)
|
|
verify_credits(shell)
|
|
shell.queue_free()
|
|
await process_frame
|
|
_cleanup()
|
|
if failures.is_empty():
|
|
print("ABG_DEV1_SETTINGS_OK set=001,002,003,004,005,006 sys=008 persisted=true apply_discard=true caller=title unavailable_reasons=true audio_bus=true")
|
|
quit(0)
|
|
else:
|
|
for failure in failures:
|
|
push_error(failure)
|
|
quit(1)
|
|
|
|
|
|
func verify_categories(shell) -> void:
|
|
expect(shell.get_node_or_null("SettingsSafeArea/SettingsFrame") != null, "Settings uses the enamel workspace frame")
|
|
for category in ["display", "motion", "audio", "controls", "language", "credits"]:
|
|
shell.open_settings_category(category)
|
|
expect(shell.find_child("SettingsContent", true, false) != null, "category %s opens" % category)
|
|
var selected: Button = shell.find_child("SettingsCategory_%s" % category, true, false)
|
|
expect(selected != null and selected.disabled and bool(selected.get_meta("selected_entry_tab", false)), "category %s has an explicit selected segment" % category)
|
|
shell.open_settings_category("audio")
|
|
var content = shell.find_child("SettingsContent", true, false)
|
|
expect(content.get_node("SettingAmbienceUnavailable").disabled and not content.get_node("SettingAmbienceUnavailable").tooltip_text.is_empty(), "absent ambience has a precise reason")
|
|
expect(content.get_node("SettingVoiceUnavailable").disabled and not content.get_node("SettingVoiceUnavailable").tooltip_text.is_empty(), "absent voice has a precise reason")
|
|
shell.open_settings_category("controls")
|
|
content = shell.find_child("SettingsContent", true, false)
|
|
expect(content.get_node("SettingRemapUnavailable").disabled and "later" in content.get_node("SettingRemapUnavailable").tooltip_text, "remapping names its later-page boundary")
|
|
|
|
|
|
func verify_apply_discard_and_runtime(shell) -> void:
|
|
shell.settings_category = "display"
|
|
shell.show_settings()
|
|
expect(shell.find_child("SettingSafeArea", true, false).get_node_or_null("Chrome") != null, "settings choices keep the value-plate chrome")
|
|
expect(shell.find_child("SettingHighContrast", true, false).get_node_or_null("Chrome") != null, "settings toggles keep the authored state chrome")
|
|
shell.settings_draft.safe_area = 48
|
|
shell.settings_draft.text_scale = 1.3
|
|
shell.settings_draft.brightness = 0.9
|
|
shell.settings_draft.high_contrast = true
|
|
shell.settings_draft.color_cues = false
|
|
shell.settings_draft.reduced_motion = true
|
|
shell.settings_draft.reduced_flashes = true
|
|
shell.settings_draft.low_power = true
|
|
shell.settings_draft.master_muted = true
|
|
shell.settings_draft.music_volume = 0.4
|
|
shell.settings_draft.sfx_volume = 0.5
|
|
shell.settings_draft.captions = false
|
|
shell.settings_draft.caption_detail = "full"
|
|
shell.settings_draft.dynamic_range = "night"
|
|
shell.settings_draft.hold_duration = 1.0
|
|
shell.settings_draft.vibration = false
|
|
shell.apply_settings()
|
|
var loaded: Dictionary = shell.settings_store.load_settings()
|
|
expect(loaded.ok and int(loaded.settings.safe_area) == 48 and is_equal_approx(float(loaded.settings.text_scale), 1.3), "display settings persist")
|
|
expect(loaded.settings.reduced_motion and loaded.settings.reduced_flashes and loaded.settings.low_power, "motion settings persist")
|
|
expect(loaded.settings.master_muted and not loaded.settings.captions and loaded.settings.dynamic_range == "night", "audio/caption settings persist")
|
|
expect(is_equal_approx(float(loaded.settings.hold_duration), 1.0) and not loaded.settings.vibration, "control settings persist")
|
|
expect(AudioServer.is_bus_mute(AudioServer.get_bus_index(&"Master")), "Master mute applies to the real audio bus")
|
|
shell.settings_draft.safe_area = 0
|
|
shell.request_settings_back()
|
|
expect("Unsaved" in shell.settings_notice, "Back with changes requires Apply or Discard")
|
|
shell.discard_settings()
|
|
expect(shell.current_screen == "title" and int(shell.settings.safe_area) == 48, "Discard returns to exact caller without applying")
|
|
shell.show_settings()
|
|
|
|
|
|
func verify_credits(shell) -> void:
|
|
shell.show_credits()
|
|
var content = shell.find_child("SettingsContent", true, false)
|
|
var combined := ""
|
|
for child in content.get_children():
|
|
if child is Label:
|
|
combined += child.text
|
|
expect("SIL Open Font License" in combined and "offline" in combined and "no analytics" in combined, "Credits states authorship, license, offline and privacy facts")
|
|
shell.discard_settings()
|
|
expect(shell.current_screen == "title", "Credits returns to Title")
|
|
|
|
|
|
func _cleanup() -> void:
|
|
for path in [SETTINGS_PATH, "%s.bak" % SETTINGS_PATH, "%s.candidate" % SETTINGS_PATH]:
|
|
if FileAccess.file_exists(path):
|
|
DirAccess.remove_absolute(path)
|
|
|
|
|
|
func expect(condition: bool, message: String) -> void:
|
|
if not condition:
|
|
failures.append("DEV-1 Settings: %s" % message)
|