Texte, Tasten und Dateien
Alle Texte stehen in einer Tabelle mit Deutsch und Englisch, die das Spiel zur Laufzeit liest. Die Tasten werden in Code angelegt, nach physischer Position. SaveStore verwaltet den Spielerschlüssel dieser Installation, schreibt den Speicherstand über eine temporäre Datei, legt unbrauchbare Stände beiseite und behält die zehn neuesten Aufzeichnungen. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
class_name TestFiles
|
||||
extends RefCounted
|
||||
## Temporary folders below user://tests for tests that write files, so that
|
||||
## tests never touch the player's real key, save or recordings.
|
||||
|
||||
|
||||
static func temporary_dir(label: String) -> String:
|
||||
var path := "user://tests".path_join("%s-%d" % [label, Time.get_ticks_usec()])
|
||||
DirAccess.make_dir_recursive_absolute(path)
|
||||
return path
|
||||
|
||||
|
||||
static func remove_dir(path: String) -> void:
|
||||
for file in DirAccess.get_files_at(path):
|
||||
DirAccess.remove_absolute(path.path_join(file))
|
||||
for directory in DirAccess.get_directories_at(path):
|
||||
remove_dir(path.path_join(directory))
|
||||
DirAccess.remove_absolute(path)
|
||||
@@ -0,0 +1 @@
|
||||
uid://cjpx0i0uknopn
|
||||
@@ -0,0 +1,35 @@
|
||||
extends TestCase
|
||||
|
||||
|
||||
func _by_locale() -> Dictionary:
|
||||
var result := {}
|
||||
for translation in I18n.load_translations(I18n.TEXTS_FILE):
|
||||
result[translation.locale] = translation
|
||||
return result
|
||||
|
||||
|
||||
func test_german_and_english_exist() -> void:
|
||||
var translations := _by_locale()
|
||||
check(translations.has("de"), "German")
|
||||
check(translations.has("en"), "English")
|
||||
|
||||
|
||||
func test_every_text_exists_in_every_language() -> void:
|
||||
var translations := _by_locale()
|
||||
var german: Translation = translations["de"]
|
||||
var english: Translation = translations["en"]
|
||||
var keys := german.get_message_list()
|
||||
keys.sort()
|
||||
var english_keys := english.get_message_list()
|
||||
english_keys.sort()
|
||||
check_eq(english_keys, keys, "the same keys")
|
||||
for key in keys:
|
||||
check(not String(german.get_message(key)).is_empty(), "German text for %s" % key)
|
||||
check(not String(english.get_message(key)).is_empty(), "English text for %s" % key)
|
||||
|
||||
|
||||
func test_the_stone_count_has_a_slot_for_the_number() -> void:
|
||||
var translations := _by_locale()
|
||||
for locale: String in translations:
|
||||
var text := String(translations[locale].get_message("STONE_COUNT"))
|
||||
check(text.contains("%d"), "%s: %s" % [locale, text])
|
||||
@@ -0,0 +1 @@
|
||||
uid://qmoy6gvht6ba
|
||||
@@ -0,0 +1,15 @@
|
||||
extends TestCase
|
||||
|
||||
|
||||
func test_every_action_of_the_game_exists() -> void:
|
||||
InputSetup.install()
|
||||
for action in ["move_up", "move_down", "move_left", "move_right", "dig", "save_game", "load_game", "toggle_pause"]:
|
||||
check(InputMap.has_action(action), "action %s" % action)
|
||||
|
||||
|
||||
func test_installing_twice_adds_no_second_set_of_keys() -> void:
|
||||
InputSetup.install()
|
||||
var events := InputMap.action_get_events("move_up").size()
|
||||
InputSetup.install()
|
||||
check_eq(InputMap.action_get_events("move_up").size(), events, "same number of keys")
|
||||
check_eq(events, 2, "W and the arrow key")
|
||||
@@ -0,0 +1 @@
|
||||
uid://dxk7wymwduoy2
|
||||
@@ -0,0 +1,56 @@
|
||||
extends TestCase
|
||||
|
||||
|
||||
func test_the_player_key_is_created_once_and_kept() -> void:
|
||||
var directory := TestFiles.temporary_dir("key")
|
||||
var first := SaveStore.new(directory).player_key()
|
||||
var second := SaveStore.new(directory).player_key()
|
||||
check_eq(first.size(), SaveStore.KEY_BYTES, "sixteen bytes")
|
||||
check_eq(second, first, "the same key on the next start")
|
||||
TestFiles.remove_dir(directory)
|
||||
|
||||
|
||||
func test_a_save_is_written_and_read_back() -> void:
|
||||
var directory := TestFiles.temporary_dir("save")
|
||||
var store := SaveStore.new(directory)
|
||||
check(not store.has_save(), "no save at first")
|
||||
check(store.write_save(PackedByteArray([1, 2, 3])), "written")
|
||||
check(store.write_save(PackedByteArray([4, 5])), "overwritten")
|
||||
check(store.has_save(), "a save exists")
|
||||
check_eq(store.read_save(), PackedByteArray([4, 5]), "the newest save is read")
|
||||
check(not FileAccess.file_exists(directory.path_join(SaveStore.SAVE_FILE + ".tmp")), "no temporary file is left")
|
||||
TestFiles.remove_dir(directory)
|
||||
|
||||
|
||||
func test_an_empty_save_is_not_written() -> void:
|
||||
var directory := TestFiles.temporary_dir("empty")
|
||||
var store := SaveStore.new(directory)
|
||||
check(not store.write_save(PackedByteArray()), "refused")
|
||||
check(not store.has_save(), "no file")
|
||||
TestFiles.remove_dir(directory)
|
||||
|
||||
|
||||
func test_an_unusable_save_can_be_set_aside() -> void:
|
||||
var directory := TestFiles.temporary_dir("aside")
|
||||
var store := SaveStore.new(directory)
|
||||
store.write_save(PackedByteArray([9, 9]))
|
||||
var aside := store.set_aside_save()
|
||||
check(not store.has_save(), "the save is out of the way")
|
||||
check_eq(FileAccess.get_file_as_bytes(aside), PackedByteArray([9, 9]), "its content is kept")
|
||||
TestFiles.remove_dir(directory)
|
||||
|
||||
|
||||
func test_only_the_newest_recordings_are_kept() -> void:
|
||||
var directory := TestFiles.temporary_dir("recordings")
|
||||
var store := SaveStore.new(directory)
|
||||
var paths: PackedStringArray = []
|
||||
for number in SaveStore.KEEP_RECORDINGS + 2:
|
||||
paths.append(store.write_recording(PackedByteArray([number])))
|
||||
OS.delay_usec(10)
|
||||
var names := store.recordings()
|
||||
check_eq(names.size(), SaveStore.KEEP_RECORDINGS, "only the newest are kept")
|
||||
check(not FileAccess.file_exists(paths[0]), "the oldest is gone")
|
||||
check(not FileAccess.file_exists(paths[1]), "the second oldest is gone")
|
||||
check(FileAccess.file_exists(paths[paths.size() - 1]), "the newest is there")
|
||||
check_eq(store.write_recording(PackedByteArray()), "", "an empty recording is not written")
|
||||
TestFiles.remove_dir(directory)
|
||||
@@ -0,0 +1 @@
|
||||
uid://cd4grmj44ifao
|
||||
Reference in New Issue
Block a user