Three test suites covering ImplantNavStack, ImplantRegistry, and ImplantApp lifecycle: - test_implant_nav_stack.gd: 26 tests — push/pop/replace/reset, push_default, is_empty, current/current_payload, signal emission, re-entrancy guard, stack-floor-to-default-on-last-pop. - test_implant_registry.gd: 21 tests — _is_valid_manifest validation, lazy scan flag, get_manifests / get_resolved_mode both trigger scan, cache on second call, real scan finds atlas and economics, no duplicate keys, _MODE_MAP coverage, get_app_instance null before instantiate_all, CURRENT_SCHEMA_VERSION = 1. - test_implant_app_lifecycle.gd: 18 tests — nav created in _ready, starts hidden, open FULLSCREEN/INSERT makes visible, GAMEPLAY/wrong path doesn't open, nav non-empty on open, close hides, app-switching closes active, preserves_state true/false, on_insert_deactivated gated on INSERT (closes) vs FULLSCREEN (no-op), register_screen adds hidden child, duplicate id does not overwrite (first-wins). Two team-lead fix-ups before commit (Stig caught the class_name parse-order issue but used the wrong gdUnit4 hook names): - before_each/after_each renamed to before_test/after_test per gdUnit4 API. test_game_state.gd's use of before_each appears to work by coincidence (that test resets autoload state rather than constructing objects, so the never-called hook didn't matter); tests that rely on hook-driven setup need the correct names. - test_register_screen_duplicate_id_does_not_overwrite rewritten to assert the actual contract (first-wins on _screens dict + duplicate screen is not reparented) instead of Control.visible default, which defaults to true regardless of registration. Also removed a stray client/ui/implant/apps/collision_test/app.tres fixture left over from Hoshe's earlier manual collision-warning verification. It was untracked and would have blocked atlas from registering at runtime (KEY_M collision, collision_test won the scan order). Not committing it. All three suites exit 0, totals 26/26, 42/42, 36/36 passed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
210 lines
7.4 KiB
GDScript
210 lines
7.4 KiB
GDScript
class_name TestImplantRegistry
|
|
extends GdUnitTestSuite
|
|
## Unit tests for ImplantRegistry autoload (#844, D-191, PR #131 item 5).
|
|
## Tests lazy-scan, manifest validation, mode resolution, real-scan results.
|
|
|
|
# Loaded inside method bodies to avoid class_name parse-order trap.
|
|
const MANIFEST_SCRIPT := "res://ui/implant/implant_app_manifest.gd"
|
|
|
|
|
|
func _make_manifest(app_path: String, mode: String = "fullscreen", key: int = -1) -> Resource:
|
|
var ManifestClass := load(MANIFEST_SCRIPT)
|
|
var m = ManifestClass.new()
|
|
m.app_path = app_path
|
|
m.default_mode = mode
|
|
m.default_key = key
|
|
m.schema_version = 1
|
|
return m
|
|
|
|
|
|
func before_test() -> void:
|
|
# Reset to a clean slate so each test gets a fresh scan pass.
|
|
ImplantRegistry._scanned = false
|
|
ImplantRegistry._manifests.clear()
|
|
ImplantRegistry._resolved_modes.clear()
|
|
ImplantRegistry._instances.clear()
|
|
|
|
|
|
func after_test() -> void:
|
|
ImplantRegistry._scanned = false
|
|
ImplantRegistry._manifests.clear()
|
|
ImplantRegistry._resolved_modes.clear()
|
|
ImplantRegistry._instances.clear()
|
|
|
|
|
|
# =============================================================================
|
|
# _is_valid_manifest — white-box validation helper
|
|
# =============================================================================
|
|
|
|
|
|
func test_invalid_manifest_null_returns_false() -> void:
|
|
assert_that(ImplantRegistry._is_valid_manifest(null)).is_false()
|
|
|
|
|
|
func test_invalid_manifest_string_returns_false() -> void:
|
|
assert_that(ImplantRegistry._is_valid_manifest("not a resource")).is_false()
|
|
|
|
|
|
func test_invalid_manifest_plain_resource_no_app_path_returns_false() -> void:
|
|
# A bare Resource has no app_path property.
|
|
assert_that(ImplantRegistry._is_valid_manifest(Resource.new())).is_false()
|
|
|
|
|
|
func test_invalid_manifest_empty_app_path_returns_false() -> void:
|
|
var m = _make_manifest("")
|
|
assert_that(ImplantRegistry._is_valid_manifest(m)).is_false()
|
|
|
|
|
|
func test_valid_manifest_with_app_path_returns_true() -> void:
|
|
var m = _make_manifest("implant/test")
|
|
assert_that(ImplantRegistry._is_valid_manifest(m)).is_true()
|
|
|
|
|
|
# =============================================================================
|
|
# Lazy scan
|
|
# =============================================================================
|
|
|
|
|
|
func test_scanned_false_before_any_call() -> void:
|
|
assert_that(ImplantRegistry._scanned).is_false()
|
|
|
|
|
|
func test_get_manifests_triggers_scan() -> void:
|
|
assert_that(ImplantRegistry._scanned).is_false()
|
|
ImplantRegistry.get_manifests()
|
|
assert_that(ImplantRegistry._scanned).is_true()
|
|
|
|
|
|
func test_get_resolved_mode_triggers_scan() -> void:
|
|
assert_that(ImplantRegistry._scanned).is_false()
|
|
ImplantRegistry.get_resolved_mode("implant/map")
|
|
assert_that(ImplantRegistry._scanned).is_true()
|
|
|
|
|
|
func test_second_get_manifests_uses_cache() -> void:
|
|
# _scanned = true after first call; subsequent calls must not reset it.
|
|
ImplantRegistry.get_manifests()
|
|
assert_that(ImplantRegistry._scanned).is_true()
|
|
ImplantRegistry.get_manifests()
|
|
assert_that(ImplantRegistry._scanned).is_true()
|
|
|
|
|
|
# =============================================================================
|
|
# Real-filesystem scan — verifies atlas and economics apps are found
|
|
# =============================================================================
|
|
|
|
|
|
func test_real_scan_finds_atlas_app() -> void:
|
|
var manifests := ImplantRegistry.get_manifests()
|
|
var found := false
|
|
for m in manifests:
|
|
if m.app_path == "implant/map":
|
|
found = true
|
|
break
|
|
assert_that(found).override_failure_message(
|
|
"ImplantRegistry must find atlas app (implant/map) after scan"
|
|
).is_true()
|
|
|
|
|
|
func test_real_scan_finds_economics_app() -> void:
|
|
var manifests := ImplantRegistry.get_manifests()
|
|
var found := false
|
|
for m in manifests:
|
|
if m.app_path == "implant/economics":
|
|
found = true
|
|
break
|
|
assert_that(found).override_failure_message(
|
|
"ImplantRegistry must find economics app (implant/economics) after scan"
|
|
).is_true()
|
|
|
|
|
|
func test_real_scan_manifests_all_have_schema_version_1() -> void:
|
|
var manifests := ImplantRegistry.get_manifests()
|
|
for m in manifests:
|
|
assert_that(m.schema_version).override_failure_message(
|
|
"All shipped manifests must declare schema_version = 1 — got wrong version for %s" % m.app_path
|
|
).is_equal(1)
|
|
|
|
|
|
func test_real_scan_no_duplicate_keys() -> void:
|
|
# Key collision detection: _scan() must drop the second manifest if two
|
|
# declare the same default_key. Verify no duplicates survive in the result.
|
|
var manifests := ImplantRegistry.get_manifests()
|
|
var seen_keys: Dictionary = {}
|
|
for m in manifests:
|
|
var k: int = m.default_key
|
|
if k >= 0:
|
|
assert_that(not seen_keys.has(k)).override_failure_message(
|
|
"Key %d bound to both '%s' and '%s' — collision not detected by registry" % [
|
|
k, seen_keys.get(k, ""), m.app_path
|
|
]
|
|
).is_true()
|
|
seen_keys[k] = m.app_path
|
|
|
|
|
|
# =============================================================================
|
|
# get_resolved_mode
|
|
# =============================================================================
|
|
|
|
|
|
func test_get_resolved_mode_atlas_is_fullscreen() -> void:
|
|
assert_that(ImplantRegistry.get_resolved_mode("implant/map")).is_equal(HudGroups.Mode.FULLSCREEN)
|
|
|
|
|
|
func test_get_resolved_mode_economics_is_insert() -> void:
|
|
assert_that(ImplantRegistry.get_resolved_mode("implant/economics")).is_equal(HudGroups.Mode.INSERT)
|
|
|
|
|
|
func test_get_resolved_mode_unknown_path_defaults_to_fullscreen() -> void:
|
|
ImplantRegistry.get_manifests() # ensure scan ran
|
|
assert_that(ImplantRegistry.get_resolved_mode("implant/nonexistent")).is_equal(HudGroups.Mode.FULLSCREEN)
|
|
|
|
|
|
# =============================================================================
|
|
# get_app_instance — before instantiate_all
|
|
# =============================================================================
|
|
|
|
|
|
func test_get_app_instance_returns_null_before_instantiate_all() -> void:
|
|
# Registry scans manifests but does not instantiate until instantiate_all()
|
|
# is called from hud.gd. Querying before that must return null.
|
|
ImplantRegistry.get_manifests()
|
|
assert_that(ImplantRegistry.get_app_instance("implant/map")).is_null()
|
|
|
|
|
|
# =============================================================================
|
|
# _MODE_MAP — covers the invalid default_mode guard in _scan()
|
|
# =============================================================================
|
|
|
|
|
|
func test_mode_map_contains_all_valid_mode_strings() -> void:
|
|
assert_that(ImplantRegistry._MODE_MAP.has("gameplay")).is_true()
|
|
assert_that(ImplantRegistry._MODE_MAP.has("insert")).is_true()
|
|
assert_that(ImplantRegistry._MODE_MAP.has("fullscreen")).is_true()
|
|
|
|
|
|
func test_mode_map_does_not_contain_invalid_strings() -> void:
|
|
# _scan() rejects manifests whose default_mode is not in this map.
|
|
assert_that(ImplantRegistry._MODE_MAP.has("bogus")).is_false()
|
|
assert_that(ImplantRegistry._MODE_MAP.has("")).is_false()
|
|
assert_that(ImplantRegistry._MODE_MAP.has("Fullscreen")).is_false() # case-sensitive
|
|
|
|
|
|
func test_real_scan_manifests_have_valid_mode_strings() -> void:
|
|
var manifests := ImplantRegistry.get_manifests()
|
|
for m in manifests:
|
|
assert_that(ImplantRegistry._MODE_MAP.has(m.default_mode)).override_failure_message(
|
|
"Manifest %s has invalid default_mode '%s' — _scan should have rejected it" % [
|
|
m.app_path, m.default_mode
|
|
]
|
|
).is_true()
|
|
|
|
|
|
# =============================================================================
|
|
# Schema version constant
|
|
# =============================================================================
|
|
|
|
|
|
func test_current_schema_version_is_1() -> void:
|
|
assert_that(ImplantRegistry.CURRENT_SCHEMA_VERSION).is_equal(1)
|