# test_chat_hyperlink_dice_parity.gd —— 40250 聊天物品超链接与 /dice 掷骰系统回归测试 extends SceneTree const SystemClass = preload("res://chat_hyperlink_dice_system.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_chat_hyperlink_dice_parity (Batch 27 Direction 3) ===") _test_item_hyperlink_encode_decode() _test_tooltip_generation() _test_broken_hyperlink_handling() _test_dice_command_variations() 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_item_hyperlink_encode_decode() -> void: print("\n--- Test 1: Item Hyperlink Encode & Decode Round-trip ---") var original_item = { "vnum": 189, "name": "Poison Sword+9", "flags": 1, "sockets": [28430, 28431, 28432], "attributes": [ { "type": 72, "value": 45 }, # 平均伤害 45% { "type": 71, "value": -12 }, # 技能伤害 -12% { "type": 17, "value": 10 } # 半人加成 10% ] } # 1. Encode var link_str = SystemClass.encode_item_hyperlink(original_item) _assert(link_str.begins_with("|cffffc700|Hitem:"), "Link starts with official color and header") _assert(link_str.ends_with("[Poison Sword+9]|h|r"), "Link ends with brackets and reset tag") # 2. Decode var decoded = SystemClass.decode_item_hyperlink(link_str) _assert(decoded["valid"] == true, "Decoded successfully") _assert(decoded["vnum"] == 189, "Vnum matches 189") _assert(decoded["name"] == "Poison Sword+9", "Name matches Poison Sword+9") _assert(decoded["sockets"][0] == 28430, "Socket 0 matches 28430") _assert(decoded["sockets"][1] == 28431, "Socket 1 matches 28431") _assert(decoded["sockets"][2] == 28432, "Socket 2 matches 28432") _assert(decoded["attributes"].size() == 3, "Decoded 3 attributes") _assert(decoded["attributes"][0]["type"] == 72 and decoded["attributes"][0]["value"] == 45, "Attr 0 is Type 72 Val 45") func _test_tooltip_generation() -> void: print("\n--- Test 2: Tooltip Generation on Link Hover ---") var decoded = { "valid": true, "vnum": 11299, "name": "Black Steel Armor+9", "sockets": [28440, 28441, 0], "attributes": [ { "type": 1, "value": 2000 } # 最大生命值 +2000 ] } var tooltip = SystemClass.build_tooltip_text(decoded) _assert(tooltip.contains("Black Steel Armor+9"), "Tooltip contains item name") _assert(tooltip.contains("Vnum: 11299"), "Tooltip contains item vnum") _assert(tooltip.contains("镶嵌宝石 [Vnum 28440]"), "Tooltip contains socket 1 gem") _assert(tooltip.contains("附加属性: 类型 1 +2000"), "Tooltip contains max HP bonus") func _test_broken_hyperlink_handling() -> void: print("\n--- Test 3: Broken Hyperlink Text Safety ---") var r1 = SystemClass.decode_item_hyperlink("Just normal chat text") _assert(r1["valid"] == false, "Normal text produces invalid hyperlink result") var r2 = SystemClass.decode_item_hyperlink("|cffffc700|Hitem:corrupted_data|h") _assert(r2["valid"] == false, "Corrupted hyperlink handled safely without crash") func _test_dice_command_variations() -> void: print("\n--- Test 4: 40250 /dice Command Logic (1:1 do_dice) ---") # 1. Default /dice (1..100) var d1 = SystemClass.execute_dice("Player1", [], 77) _assert(d1["roll"] == 77, "Default dice rolled 77") _assert(d1["start"] == 1 and d1["end"] == 100, "Default range is 1-100") _assert(d1["message"].contains("77 (1-100)"), "Message correctly formatted") # 2. Single arg /dice 20 (1..20) var d2 = SystemClass.execute_dice("Player2", ["20"], 15) _assert(d2["roll"] == 15, "Dice rolled 15 in range 1-20") _assert(d2["start"] == 1 and d2["end"] == 20, "Single arg range is 1-20") # 3. Two args reversed: /dice 80 20 -> auto min/max to (20..80) var d3 = SystemClass.execute_dice("Player3", ["80", "20"], 50) _assert(d3["start"] == 20 and d3["end"] == 80, "Auto swaps reversed range to 20-80") _assert(d3["roll"] == 50, "Rolled 50 within normalized range")