754d7f1e92
Lässt sich ein unbrauchbarer Spielstand nicht beiseitelegen, bleibt das Speichern gesperrt, bis ein Stand erfolgreich geladen wird; so wird er nie überschrieben. Ein gescheitertes automatisches Speichern zeigt SAVE_FAILED, und jedes gescheiterte Speichern wird protokolliert. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
77 lines
2.9 KiB
GDScript
77 lines
2.9 KiB
GDScript
extends TestCase
|
|
## Starts the real main scene with its own storage folder and runs a few
|
|
## frames.
|
|
|
|
|
|
func _start_main(directory: String) -> Node:
|
|
var main: Node = load("res://main.tscn").instantiate()
|
|
main.storage_dir = directory
|
|
tree.root.add_child(main)
|
|
return main
|
|
|
|
|
|
func _stop_main(main: Node) -> void:
|
|
tree.root.remove_child(main)
|
|
main.free()
|
|
|
|
|
|
func test_a_new_game_starts_and_the_player_joins() -> void:
|
|
var directory := TestFiles.temporary_dir("main")
|
|
var main := _start_main(directory)
|
|
for frame in 5:
|
|
await tree.process_frame
|
|
var session: GwSession = main.session
|
|
check(session != null and session.is_running(), "a session runs")
|
|
check(not session.is_broken(), "the simulation is healthy")
|
|
check_eq(session.local_player(), 0, "the local player has joined")
|
|
check_eq(main.avatar.position, GridMotion.tile_center(session.spawn_point()), "the figure stands on the spawn")
|
|
check_eq(main.hud.stone_text(), tr("STONE_COUNT") % 0, "the HUD shows the stones")
|
|
_stop_main(main)
|
|
TestFiles.remove_dir(directory)
|
|
|
|
|
|
func test_a_saved_game_is_continued_on_the_next_start() -> void:
|
|
var directory := TestFiles.temporary_dir("continue")
|
|
var first := _start_main(directory)
|
|
await tree.process_frame
|
|
var tick_at_save: int = first.session.tick()
|
|
check(first.save_game(), "the game was saved")
|
|
_stop_main(first)
|
|
|
|
var second := _start_main(directory)
|
|
await tree.process_frame
|
|
check(second.session.tick() > tick_at_save, "the saved world continues")
|
|
check_eq(second.session.local_player(), 0, "the same player rejoins")
|
|
_stop_main(second)
|
|
TestFiles.remove_dir(directory)
|
|
|
|
|
|
func test_an_unusable_save_is_set_aside_and_a_new_world_starts() -> void:
|
|
var directory := TestFiles.temporary_dir("broken")
|
|
var store := SaveStore.new(directory)
|
|
store.write_save(PackedByteArray([1, 2, 3]))
|
|
var main := _start_main(directory)
|
|
await tree.process_frame
|
|
check(main.session.is_running(), "a new world runs")
|
|
check(main.session.tick() <= 5, "it is new, tick %d" % main.session.tick())
|
|
check(FileAccess.file_exists(directory.path_join(SaveStore.SAVE_FILE + ".broken")), "the unusable save is kept aside")
|
|
check_eq(main.hud.message(), tr("LOAD_FAILED"), "the player is told")
|
|
_stop_main(main)
|
|
TestFiles.remove_dir(directory)
|
|
|
|
|
|
func test_an_unusable_save_that_cannot_be_set_aside_is_never_overwritten() -> void:
|
|
var directory := TestFiles.temporary_dir("stuck")
|
|
var store := SaveStore.new(directory)
|
|
store.write_save(PackedByteArray([1, 2, 3]))
|
|
# A folder under the set-aside name keeps the unusable save from moving.
|
|
DirAccess.make_dir_absolute(directory.path_join(SaveStore.SAVE_FILE + ".broken"))
|
|
var main := _start_main(directory)
|
|
await tree.process_frame
|
|
check(main.session.is_running(), "a new world runs")
|
|
check(not main.save_game(), "saving is refused")
|
|
check_eq(store.read_save(), PackedByteArray([1, 2, 3]), "the unusable save is untouched")
|
|
check_eq(main.hud.message(), tr("LOAD_FAILED"), "the player is told")
|
|
_stop_main(main)
|
|
TestFiles.remove_dir(directory)
|