# test_intro_create_parity.gd —— 40250 3D 角色塑形创建回归测试 extends SceneTree const SystemClass = preload("res://intro_create_phase.gd") var _passed: int = 0 var _failed: int = 0 func _assert(cond: bool, msg: String) -> void: if cond: _passed += 1 print(" [PASS] %s" % msg) else: _failed += 1 printerr(" [FAIL] %s" % msg) func _init() -> void: print("\n=== Running test_intro_create_parity (Batch 29 Direction 4) ===") _test_class_gender_shape_matrix() _test_canonical_start_stats() _test_turntable_360_rotation() _test_character_name_validation() _test_successful_character_creation() print("\n=== Result: %d Passed, %d Failed ===" % [_passed, _failed]) if _failed == 0: print("ALL TESTS PASSED!\n") else: printerr("SOME TESTS FAILED!\n") quit(0 if _failed == 0 else 1) func _test_class_gender_shape_matrix() -> void: print("\n--- Test 1: Class, Gender, and Shape Matrix ---") var cr = SystemClass.new() _assert(cr.selected_job == SystemClass.JOB_WARRIOR, "Default job is Warrior") _assert(cr.selected_gender == SystemClass.GENDER_MALE, "Default gender is Male") _assert(cr.selected_shape == SystemClass.SHAPE_0, "Default shape is Shape 0") # Switch to Assassin, Female, Shape 1 var s_job = cr.select_job(SystemClass.JOB_ASSASSIN) var s_gen = cr.select_gender(SystemClass.GENDER_FEMALE) var s_shp = cr.select_shape(SystemClass.SHAPE_1) _assert(s_job == true and cr.selected_job == SystemClass.JOB_ASSASSIN, "Switched to Assassin") _assert(s_gen == true and cr.selected_gender == SystemClass.GENDER_FEMALE, "Switched to Female") _assert(s_shp == true and cr.selected_shape == SystemClass.SHAPE_1, "Switched to Shape 1") # Reject invalid selections _assert(cr.select_job(99) == false, "Reject invalid job id 99") _assert(cr.select_gender(5) == false, "Reject invalid gender id 5") _assert(cr.select_shape(3) == false, "Reject invalid shape id 3") func _test_canonical_start_stats() -> void: print("\n--- Test 2: 40250 Canonical START_STAT Table (CON, INT, STR, DEX) ---") var cr = SystemClass.new() # 1. Warrior: [4, 3, 6, 3] cr.select_job(SystemClass.JOB_WARRIOR) var st_w = cr.get_current_stats() _assert(st_w["con"] == 4 and st_w["int"] == 3 and st_w["str"] == 6 and st_w["dex"] == 3, "Warrior stats: 4/3/6/3") # 2. Assassin: [3, 3, 4, 6] cr.select_job(SystemClass.JOB_ASSASSIN) var st_a = cr.get_current_stats() _assert(st_a["con"] == 3 and st_a["int"] == 3 and st_a["str"] == 4 and st_a["dex"] == 6, "Assassin stats: 3/3/4/6") # 3. Sura: [3, 5, 5, 3] cr.select_job(SystemClass.JOB_SURA) var st_s = cr.get_current_stats() _assert(st_s["con"] == 3 and st_s["int"] == 5 and st_s["str"] == 5 and st_s["dex"] == 3, "Sura stats: 3/5/5/3") # 4. Shaman: [4, 6, 3, 3] cr.select_job(SystemClass.JOB_SHAMAN) var st_m = cr.get_current_stats() _assert(st_m["con"] == 4 and st_m["int"] == 6 and st_m["str"] == 3 and st_m["dex"] == 3, "Shaman stats: 4/6/3/3") func _test_turntable_360_rotation() -> void: print("\n--- Test 3: Turntable 360-Degree Rotation ---") var cr = SystemClass.new() cr.rotate_turntable(45.0) _assert(cr.turntable_rotation_deg == 45.0, "Rotated by 45 degrees") cr.rotate_turntable(340.0) # 45 + 340 = 385 -> wraps to 25 _assert(is_equal_approx(cr.turntable_rotation_deg, 25.0), "Rotated beyond 360 wrapped correctly to 25 degrees") cr.rotate_turntable(-30.0) # 25 - 30 = -5 -> wraps to 355 _assert(is_equal_approx(cr.turntable_rotation_deg, 355.0), "Negative rotation wrapped correctly to 355 degrees") func _test_character_name_validation() -> void: print("\n--- Test 4: Character Name Validation Rules ---") var cr = SystemClass.new() # Empty var r_empty = cr.validate_character_name("") _assert(r_empty["error_code"] == "EMPTY_NAME", "Reject empty name") # Too short (< 2) var r_short = cr.validate_character_name("A") _assert(r_short["error_code"] == "INVALID_NAME_LENGTH", "Reject name length < 2") # Too long (> 12) var r_long = cr.validate_character_name("VeryLongHeroNameExceeding12") _assert(r_long["error_code"] == "INVALID_NAME_LENGTH", "Reject name length > 12") # Contains space var r_space = cr.validate_character_name("Hello World") _assert(r_space["error_code"] == "NAME_CONTAINS_SPACE", "Reject name containing spaces") # Banned word (GM / Admin) var r_gm = cr.validate_character_name("[GM]Tester") _assert(r_gm["error_code"] == "NAME_CONTAINS_BANNED_WORD", "Reject name containing [GM]") var r_ok = cr.validate_character_name("DarkKnight") _assert(r_ok["valid"] == true, "Valid name DarkKnight passed") func _test_successful_character_creation() -> void: print("\n--- Test 5: Successful Character Creation Payload ---") var cr = SystemClass.new() cr.select_job(SystemClass.JOB_WARRIOR) cr.select_gender(SystemClass.GENDER_MALE) cr.select_shape(SystemClass.SHAPE_0) var res = cr.create_character("Conan", 1) _assert(res["success"] == true, "Created character Conan successfully") var ch = res["character"] _assert(ch["name"] == "Conan", "Name matches Conan") _assert(ch["level"] == 1, "Level is 1") _assert(ch["empire"] == 1, "Empire is 1 (Shinsoo)") _assert(ch["stats"]["str"] == 6, "Warrior STR is 6") _assert(ch["delete_code"] == "1234567", "Generated 7-digit delete code")