extends Node ## 消息协议属性测试 ## Feature: godot-ai-town-game, Property 16: 数据序列化往返 # 测试配置 const TEST_ITERATIONS = 100 # 每个属性测试运行 100 次 func _ready(): print("=== Message Protocol Property Tests ===") test_property_serialization_roundtrip() test_message_creation() test_message_validation() print("=== All tests completed ===") ## Feature: godot-ai-town-game, Property 16: 数据序列化往返 func test_property_serialization_roundtrip(): """ 属性测试:数据序列化往返 对于任意游戏数据对象,序列化为 JSON 后再反序列化应该得到等价的对象 """ print("\n[Property Test] Serialization Roundtrip") var passed = 0 var failed = 0 for i in range(TEST_ITERATIONS): # 生成随机消息数据 var original_message = _generate_random_message() # 序列化 var serialized = MessageProtocol.serialize(original_message) # 反序列化 var deserialized = MessageProtocol.deserialize(serialized) # 验证往返一致性 if _deep_equals(original_message, deserialized): passed += 1 else: failed += 1 print(" FAILED iteration ", i + 1) print(" Original: ", original_message) print(" Deserialized: ", deserialized) print(" Result: ", passed, "/", TEST_ITERATIONS, " passed") if failed > 0: print(" ❌ FAILED: ", failed, " iterations failed") else: print(" ✅ PASSED: All iterations successful") func test_message_creation(): """测试消息创建函数""" print("\n[Unit Test] Message Creation") # 测试各种消息类型 var auth_msg = MessageProtocol.create_auth_request("test_user") assert(auth_msg.has("type"), "Auth message should have type") assert(auth_msg["type"] == "auth_request", "Auth message type should be auth_request") assert(auth_msg["data"]["username"] == "test_user", "Auth message should contain username") var char_msg = MessageProtocol.create_character_create("TestChar") assert(char_msg["type"] == "character_create", "Character create message type correct") assert(char_msg["data"]["name"] == "TestChar", "Character name correct") var move_msg = MessageProtocol.create_character_move("char_123", Vector2(100, 200), Vector2(1, 0)) assert(move_msg["type"] == "character_move", "Move message type correct") assert(move_msg["data"]["character_id"] == "char_123", "Character ID correct") assert(move_msg["data"]["position"]["x"] == 100, "Position X correct") print(" ✅ PASSED: All message creation tests passed") func test_message_validation(): """测试消息验证""" print("\n[Unit Test] Message Validation") # 有效消息 var valid_msg = MessageProtocol.create_message(MessageProtocol.MessageType.PING, {}) assert(MessageProtocol.validate_message(valid_msg), "Valid message should pass validation") # 无效消息 - 缺少字段 var invalid_msg1 = {"type": "ping"} assert(not MessageProtocol.validate_message(invalid_msg1), "Message without data should fail") var invalid_msg2 = {"data": {}, "timestamp": 123} assert(not MessageProtocol.validate_message(invalid_msg2), "Message without type should fail") # 无效消息 - 错误的类型 var invalid_msg3 = {"type": "invalid_type", "data": {}, "timestamp": 123} assert(not MessageProtocol.validate_message(invalid_msg3), "Message with invalid type should fail") print(" ✅ PASSED: All validation tests passed") ## 生成随机消息用于测试 func _generate_random_message() -> Dictionary: var message_types = [ MessageProtocol.MessageType.AUTH_REQUEST, MessageProtocol.MessageType.CHARACTER_CREATE, MessageProtocol.MessageType.CHARACTER_MOVE, MessageProtocol.MessageType.DIALOGUE_SEND, MessageProtocol.MessageType.PING ] var random_type = message_types[randi() % message_types.size()] var data = {} match random_type: MessageProtocol.MessageType.AUTH_REQUEST: data = {"username": "user_" + str(randi())} MessageProtocol.MessageType.CHARACTER_CREATE: data = {"name": "char_" + str(randi() % 1000)} MessageProtocol.MessageType.CHARACTER_MOVE: data = { "character_id": "char_" + str(randi()), "position": { "x": randf_range(0, 1000), "y": randf_range(0, 1000) }, "direction": { "x": randf_range(-1, 1), "y": randf_range(-1, 1) } } MessageProtocol.MessageType.DIALOGUE_SEND: data = { "sender_id": "char_" + str(randi()), "receiver_id": "char_" + str(randi()), "message": "Test message " + str(randi()) } MessageProtocol.MessageType.PING: data = {} return MessageProtocol.create_message(random_type, data) ## 深度比较两个字典是否相等(使用工具类) func _deep_equals(a, b) -> bool: return Utils.deep_equals(a, b)