extends "res://addons/gut/test.gd" const Ids = preload("res://scripts/ids.gd") const LogPlayer = preload("res://scripts/canon_log/log_player.gd") const LogLocation = preload("res://scripts/canon_log/log_location.gd") const PartyMember = preload("res://scripts/canon_log/party_member.gd") const Quest = preload("res://scripts/canon_log/quest.gd") const Humiliation = preload("res://scripts/canon_log/humiliation.gd") func test_ids_regex(): assert_true(Ids.is_valid("greywater_docks")) assert_false(Ids.is_valid("Bad Id")) assert_false(Ids.is_valid("has-hyphen")) func test_log_player_carries_race_and_calling_and_no_luck_number(): var p := LogPlayer.new("Aldric", "beastfolk", "cutpurse", "Fortune spits on you") var d := p.to_dict() assert_eq(d["race_id"], "beastfolk") assert_eq(d["calling_id"], "cutpurse") assert_false("luck" in d, "numeric Luck never reaches the log (ยง7)") assert_false("class_id" in d) assert_eq(d.keys().size(), 4) func test_log_player_rejects_a_dead_calling(): var p := LogPlayer.new() assert_false(p.set_calling_id("priest"), "priest is not a calling") assert_true(p.set_calling_id("bonesetter")) assert_false(p.set_race_id("orc")) assert_true(p.set_race_id("dwarf")) func test_log_player_ctor_rejects_calling_passed_as_race(): # The exact shape of the bug: calling three broken call sites used to pass โ€” # LogPlayer.new(name, class_id, luck_descriptor) against the NEW ctor # (name, race_id, calling_id, luck_descriptor). "sellsword" lands in the # race_id slot (rejected โ€” not a race), the descriptor lands in the # calling_id slot (rejected โ€” not a calling), and luck_descriptor is left # at its default. Every field ends up "", which 422s against the schema. var p := LogPlayer.new("Aldric", "sellsword", "Fortune spits on you") var d := p.to_dict() assert_eq(d["race_id"], "", "a calling id is not a legal race_id") assert_eq(d["calling_id"], "", "a luck descriptor is not a legal calling_id") assert_eq(d["luck_descriptor"], "", "old 3-arg call shape must not produce a usable player row") func test_party_member_clamps_disposition(): var m = PartyMember.new("brannoc_thane", "Brannoc Thane", 200) assert_eq(m.disposition, 100) m.set_disposition(-200) assert_eq(m.disposition, -100) func test_quest_status_enum(): var q = Quest.new("find_the_ledger", "The Missing Ledger", "active", "Find it") assert_false(q.set_status("abandoned")) assert_eq(q.status, "active") assert_true(q.set_status("complete")) func test_humiliation_clamps_weight_and_turn(): var h = Humiliation.new("h_1", "vomited on a shrine", 11, -3) assert_eq(h.weight, 10) assert_eq(h.turn, 0) func test_round_trip_each_entity(): var loc = LogLocation.new("greywater_docks", "the Greywater docks") assert_eq(LogLocation.from_dict(loc.to_dict()).to_dict(), loc.to_dict()) var m = PartyMember.new("cadwyn_vell", "Cadwyn Vell", 15) assert_eq(PartyMember.from_dict(m.to_dict()).to_dict(), m.to_dict())