4463e524aa
Auto-format all GDScript files using gdformat from gdtoolkit. This is a baseline formatting pass to ensure consistent style: - Normalizes indentation and spacing - Wraps long lines to 100 characters - Removes trailing whitespace - Standardizes blank lines between functions 68 files reformatted, 8 files left unchanged (3rd-party addon files with parse errors excluded).
122 lines
3.8 KiB
GDScript
122 lines
3.8 KiB
GDScript
extends SceneTree
|
|
|
|
var failures: Array[String] = []
|
|
|
|
|
|
func _initialize() -> void:
|
|
call_deferred("_run")
|
|
|
|
|
|
func _run() -> void:
|
|
_test_registry_integrity()
|
|
_test_definition_backed_behavior()
|
|
_test_state_reference_validation()
|
|
_test_id_round_trip()
|
|
|
|
if failures.is_empty():
|
|
print("[TEST] Simulation definitions passed")
|
|
quit(0)
|
|
return
|
|
|
|
for failure in failures:
|
|
push_error("[TEST] " + failure)
|
|
quit(1)
|
|
|
|
|
|
func _test_registry_integrity() -> void:
|
|
var errors := SimulationDefinitions.validate()
|
|
_check(errors.is_empty(), "Definition registry should validate: %s" % [errors])
|
|
|
|
var action_ids: Array[StringName] = []
|
|
for definition in SimulationDefinitions.get_actions():
|
|
action_ids.append(definition.action_id)
|
|
_check(
|
|
SimulationDefinitions.get_action(definition.action_id) == definition,
|
|
"Action lookup should return '%s'" % definition.action_id
|
|
)
|
|
_check(action_ids.size() == 9, "Registry should contain all nine executable prototype actions")
|
|
|
|
var profession_ids := SimulationDefinitions.get_profession_ids()
|
|
_check(profession_ids.size() == 5, "Registry should contain all five prototype professions")
|
|
for profession_id in profession_ids:
|
|
_check(
|
|
SimulationDefinitions.get_profession(profession_id) != null,
|
|
"Profession lookup should return '%s'" % profession_id
|
|
)
|
|
|
|
|
|
func _test_definition_backed_behavior() -> void:
|
|
var npc := SimNPC.new(500, "DefinitionWorker", SimulationIds.PROFESSION_SCHOLAR, 5.0, 5.0)
|
|
npc.set_task(SimulationIds.ACTION_STUDY)
|
|
var study := SimulationDefinitions.get_action(SimulationIds.ACTION_STUDY)
|
|
_check(
|
|
is_equal_approx(npc.task_duration, study.default_duration),
|
|
"SimNPC should use the action definition's default duration"
|
|
)
|
|
_check(
|
|
study.preferred_profession_id == SimulationIds.PROFESSION_SCHOLAR,
|
|
"Study should reference the stable scholar profession ID"
|
|
)
|
|
var gather := SimulationDefinitions.get_action(SimulationIds.ACTION_GATHER_FOOD)
|
|
_check(
|
|
(
|
|
gather.target_type == SimulationIds.TARGET_RESOURCE
|
|
and gather.resource_action_id == SimulationIds.ACTION_GATHER_FOOD
|
|
),
|
|
"Gather-food target metadata should come from its definition"
|
|
)
|
|
|
|
|
|
func _test_state_reference_validation() -> void:
|
|
var npc := SimNPC.new(501, "ValidationWorker", SimulationIds.PROFESSION_FARMER, 5.0, 5.0)
|
|
var valid_data := NPCStateRecord.capture(npc).to_dictionary()
|
|
var invalid_profession := valid_data.duplicate(true)
|
|
invalid_profession["profession"] = "missing_profession"
|
|
_check(
|
|
NPCStateRecord.from_dictionary(invalid_profession) == null,
|
|
"NPC state should reject an unknown profession ID"
|
|
)
|
|
var invalid_action := valid_data.duplicate(true)
|
|
invalid_action["current_task"] = "missing_action"
|
|
_check(
|
|
NPCStateRecord.from_dictionary(invalid_action) == null,
|
|
"NPC state should reject an unknown action ID"
|
|
)
|
|
|
|
|
|
func _test_id_round_trip() -> void:
|
|
var manager: Node = load("res://simulation/SimulationManager.gd").new()
|
|
manager.debug_logs = false
|
|
root.add_child(manager)
|
|
manager.set_process(false)
|
|
var json_state: String = manager.serialize_state()
|
|
|
|
var restored: Node = load("res://simulation/SimulationManager.gd").new()
|
|
restored.debug_logs = false
|
|
root.add_child(restored)
|
|
restored.set_process(false)
|
|
_check(
|
|
restored.restore_state_from_json(json_state),
|
|
"Definition-backed IDs should restore from serialized state"
|
|
)
|
|
for npc in restored.npcs:
|
|
_check(
|
|
typeof(npc.profession) == TYPE_STRING_NAME, "Profession should restore as StringName"
|
|
)
|
|
_check(
|
|
typeof(npc.current_task) == TYPE_STRING_NAME,
|
|
"Current action should restore as StringName"
|
|
)
|
|
_check(
|
|
SimulationDefinitions.get_profession(npc.profession) != null,
|
|
"Restored profession should resolve through the registry"
|
|
)
|
|
|
|
manager.free()
|
|
restored.free()
|
|
|
|
|
|
func _check(condition: bool, message: String) -> void:
|
|
if not condition:
|
|
failures.append(message)
|