Files
aetherbound-guild/runtime/tests/p10_2/content_registry_test.gd
T

137 lines
6.5 KiB
GDScript

extends SceneTree
const Content = preload("res://p10_2/content_registry.gd")
var failures: Array[String] = []
var rejected_cases := 0
func _initialize() -> void:
call_deferred("run_test")
func run_test() -> void:
var first := Content.snapshot()
var second := Content.snapshot()
var validation := Content.validate(first)
expect(validation.ok, "canonical P10.2 registry validates: %s" % str(validation.errors))
expect(first == second, "catalog loading and enrichment are byte-identical")
expect(String(first.catalog_hash).length() == 64, "catalog has a canonical SHA-256")
verify_counts_and_identity(first)
verify_route_and_market_authority(first)
verify_negative_boundaries(first)
if failures.is_empty():
print("ABG_P10_2_CONTENT_REGISTRY_OK region=1 contract=1 equipment=8 enemies=3 routes=9 markets=3 localized=22 source=exact formulas=coin,capacity,offer_level negative_cases=%d" % rejected_cases)
quit(0)
else:
for failure in failures:
push_error(failure)
quit(1)
func verify_counts_and_identity(content: Dictionary) -> void:
expect(content.region.id == "RG-02", "Region identity is exact")
expect(content.contract.id == "CTR-R2-01" and content.contract.region_id == "RG-02", "Contract and Region reference are exact")
expect(content.contract.slice_start_market == 2 and content.contract.slice_end_market == 5, "mid-Contract boundary is exact")
expect(not content.contract.boss_executable, "Boss execution remains frozen")
expect(content.equipment.size() == 8, "EQ-049..EQ-056 are exposed")
expect(content.enemies.size() == 3, "EN-R2-08..EN-R2-10 are exposed")
expect(content.routes.size() == 9 and content.markets.size() == 3, "nine routes and three Markets are exposed")
expect(content.names_zh.size() == 22, "every bounded content identity has zh_CN authority")
expect(content.source == Content.SOURCE_AUTHORITY, "four source blobs are bound exactly")
var ids := {}
for singleton in [content.region, content.contract]:
verify_row(singleton, ids)
for family in [content.equipment, content.enemies, content.routes]:
for row in family:
verify_row(row, ids)
expect(ids.size() == 22, "all runtime identities are unique")
func verify_route_and_market_authority(content: Dictionary) -> void:
var routes := Content.rows_by_id(content, "routes")
var markets := Content.markets_by_index(content)
expect(markets.keys().size() == 3, "Market index lookup is complete")
var seen_new_enemies := {"EN-R2-08": 0, "EN-R2-09": 0, "EN-R2-10": 0}
for market_index in [2, 3, 4]:
var market: Dictionary = markets[market_index]
expect(market.round_index == market_index, "Market %d binds the same Round" % market_index)
expect(market.cleared_rounds_before == market_index - 1, "Market %d clear lineage is exact" % market_index)
expect(market.line_capacity == [4, 5, 5][market_index - 2], "Market %d capacity follows authority" % market_index)
expect(market.offer_level == [1, 1, 2][market_index - 2], "Market %d offer level follows authority" % market_index)
expect(market.route_ids.size() == 3 and market.required_equipment_ids.size() == 2, "Market %d owns exact board rows" % market_index)
for risk in range(3):
var route: Dictionary = routes[market.route_ids[risk]]
expect(route.market_index == market_index and route.round_index == market_index and route.risk == risk, "Market %d risk %d identity is exact" % [market_index, risk])
expect(route.reward_coin == 18 + 2 * market_index + 2 + 7 * risk, "Market %d risk %d reward formula is exact" % [market_index, risk])
expect(route.wave_order.map(func(wave): return wave.enemy_id) == route.enemy_ids, "Market %d risk %d wave order binds composition" % [market_index, risk])
for enemy_id in route.enemy_ids:
if seen_new_enemies.has(enemy_id):
seen_new_enemies[enemy_id] += 1
for enemy_id in seen_new_enemies:
expect(seen_new_enemies[enemy_id] >= 2, "%s appears in at least two route decisions" % enemy_id)
func verify_row(row: Dictionary, ids: Dictionary) -> void:
expect(not ids.has(row.id), "%s is globally unique" % row.id)
ids[row.id] = true
expect(not String(row.name_en).is_empty() and not String(row.name_zh).is_empty(), "%s has both names" % row.id)
expect(not String(row.preview).is_empty() and row.response_tags.size() >= 3, "%s has preview and response tags" % row.id)
expect(String(row.execution_key).begins_with("execute.") and String(row.mechanic_signature).length() == 64, "%s has runtime dispatch and signature" % row.id)
func verify_negative_boundaries(canonical: Dictionary) -> void:
var source_drift := canonical.duplicate(true)
source_drift.source.economy_blob = "0".repeat(40)
expect_rejected(source_drift, "source drift", "source:economy_blob")
var locale_missing := canonical.duplicate(true)
locale_missing.names_zh.erase("EN-R2-10")
expect_rejected(locale_missing, "missing locale", "names_zh_ids")
var duplicate_item := canonical.duplicate(true)
duplicate_item.equipment[1].id = "EQ-049"
expect_rejected(duplicate_item, "duplicate item", "duplicate_global_id:EQ-049")
var unknown_enemy := canonical.duplicate(true)
unknown_enemy.routes[0].enemy_ids[0] = "EN-R2-99"
unknown_enemy.routes[0].wave_order[0].enemy_id = "EN-R2-99"
expect_rejected(unknown_enemy, "unknown route enemy", "route_enemy:RO-R2-M02-Q0")
var reward_drift := canonical.duplicate(true)
reward_drift.routes[4].reward_coin += 1
expect_rejected(reward_drift, "reward drift", "route_reward:RO-R2-M03-Q1")
var executable_boss := canonical.duplicate(true)
executable_boss.contract.boss_executable = true
expect_rejected(executable_boss, "Boss execution leak", "boss_boundary")
var route_mismatch := canonical.duplicate(true)
route_mismatch.markets[1].route_ids[0] = "RO-R2-M02-Q0"
expect_rejected(route_mismatch, "wrong Market route", "market_route:3:0")
var item_mismatch := canonical.duplicate(true)
item_mismatch.markets[2].required_equipment_ids[0] = "EQ-999"
expect_rejected(item_mismatch, "unknown required item", "market_equipment:4:EQ-999")
var filler := canonical.duplicate(true)
filler.enemies[0].rule = "TODO placeholder"
expect_rejected(filler, "filler mechanic", "filler:EN-R2-08:todo")
func expect_rejected(content: Dictionary, label: String, expected_error: String) -> void:
var result := Content.validate(content)
var found := false
for error in result.errors:
if String(error).begins_with(expected_error):
found = true
expect(not result.ok and found, "%s rejects with %s; got %s" % [label, expected_error, str(result.errors)])
if not result.ok and found:
rejected_cases += 1
func expect(condition: bool, message: String) -> void:
if not condition:
failures.append("P10.2 content registry: %s" % message)