""" 测试RobustJSONParser的各种修复能力。 验证解析器能够处理: 1. 基本的markdown包裹 2. 思考内容清理 3. 缺少逗号的修复 4. 括号不平衡的修复 5. 控制字符转义 6. 尾随逗号移除 """ import json import unittest from json_parser import RobustJSONParser, JSONParseError class TestRobustJSONParser(unittest.TestCase): """测试鲁棒JSON解析器的各种修复策略。""" def setUp(self): """初始化解析器。""" self.parser = RobustJSONParser( enable_json_repair=False, # 先测试本地修复 enable_llm_repair=False, ) def test_basic_json(self): """测试解析基本的合法JSON。""" json_str = '{"name": "test", "value": 123}' result = self.parser.parse(json_str, "基本测试") self.assertEqual(result["name"], "test") self.assertEqual(result["value"], 123) def test_markdown_wrapped(self): """测试解析被```json包裹的JSON。""" json_str = """```json { "name": "test", "value": 123 } ```""" result = self.parser.parse(json_str, "Markdown包裹测试") self.assertEqual(result["name"], "test") self.assertEqual(result["value"], 123) def test_thinking_content_removal(self): """测试清理思考内容。""" json_str = """让我想想如何构造这个JSON { "name": "test", "value": 123 }""" result = self.parser.parse(json_str, "思考内容清理测试") self.assertEqual(result["name"], "test") self.assertEqual(result["value"], 123) def test_missing_comma_fix(self): """测试修复缺少的逗号。""" # 这是实际错误中常见的情况:数组元素之间缺少逗号 json_str = """{ "totalWords": 40000, "globalGuidelines": [ "重点突出技术红利分配失衡" "详略策略:技术创新" ], "chapters": [] }""" result = self.parser.parse(json_str, "缺少逗号修复测试") self.assertEqual(len(result["globalGuidelines"]), 2) def test_unbalanced_brackets(self): """测试修复括号不平衡。""" # 缺少结束括号 json_str = """{ "name": "test", "nested": { "value": 123 } """ # 缺少最外层的 } result = self.parser.parse(json_str, "括号不平衡测试") self.assertEqual(result["name"], "test") self.assertEqual(result["nested"]["value"], 123) def test_control_character_escape(self): """测试转义控制字符。""" # JSON字符串中的裸换行符应该被转义 json_str = """{ "text": "这是第一行 这是第二行", "value": 123 }""" result = self.parser.parse(json_str, "控制字符转义测试") # 确保换行符被正确处理 self.assertIn("第一行", result["text"]) self.assertIn("第二行", result["text"]) def test_trailing_comma_removal(self): """测试移除尾随逗号。""" json_str = """{ "name": "test", "value": 123, "items": [1, 2, 3,], }""" result = self.parser.parse(json_str, "尾随逗号测试") self.assertEqual(result["name"], "test") self.assertEqual(len(result["items"]), 3) def test_colon_equals_fix(self): """测试修复冒号等号错误。""" json_str = """{ "name":= "test", "value": 123 }""" result = self.parser.parse(json_str, "冒号等号测试") self.assertEqual(result["name"], "test") def test_extract_first_json(self): """测试从文本中提取第一个JSON结构。""" json_str = """这是一些说明文字,下面是JSON: { "name": "test", "value": 123 } 后面还有一些其他文字""" result = self.parser.parse(json_str, "提取JSON测试") self.assertEqual(result["name"], "test") self.assertEqual(result["value"], 123) def test_complex_real_world_case(self): """测试真实世界的复杂案例(类似实际错误)。""" # 模拟实际错误:缺少逗号、有markdown包裹、有思考内容 json_str = """我需要构造一个篇幅规划 ```json { "totalWords": 40000, "tolerance": 2000, "globalGuidelines": [ "重点突出技术红利分配失衡、人才流失与职业认同危机等结构性矛盾" "详略策略:技术创新与传统技艺的碰撞" "案例导向:优先引用真实数据和调研" ], "chapters": [ { "chapterId": "ch1", "targetWords": 5000 } ] } ```""" result = self.parser.parse(json_str, "复杂真实案例测试") self.assertEqual(result["totalWords"], 40000) self.assertEqual(result["tolerance"], 2000) self.assertEqual(len(result["globalGuidelines"]), 3) self.assertEqual(len(result["chapters"]), 1) def test_expected_keys_validation(self): """测试期望键的验证。""" json_str = '{"name": "test"}' # 不应该因为缺少键而失败,只是警告 result = self.parser.parse( json_str, "键验证测试", expected_keys=["name", "value"] ) self.assertIn("name", result) def test_wrapper_key_extraction(self): """测试从包裹键中提取数据。""" json_str = """{ "wrapper": { "name": "test", "value": 123 } }""" result = self.parser.parse( json_str, "包裹键测试", extract_wrapper_key="wrapper" ) self.assertEqual(result["name"], "test") self.assertEqual(result["value"], 123) def test_empty_input(self): """测试空输入。""" with self.assertRaises(JSONParseError): self.parser.parse("", "空输入测试") def test_invalid_json_after_all_repairs(self): """测试所有修复策略都无法处理的情况。""" # 这是一个严重损坏的JSON,无法修复 json_str = "{完全不是JSON格式的内容###" with self.assertRaises(JSONParseError): self.parser.parse(json_str, "无法修复测试") def run_manual_test(): """手动运行测试,打印详细信息。""" print("=" * 60) print("开始测试RobustJSONParser") print("=" * 60) parser = RobustJSONParser(enable_json_repair=False, enable_llm_repair=False) # 测试实际错误案例 test_case = """```json { "totalWords": 40000, "tolerance": 2000, "globalGuidelines": [ "重点突出技术红利分配失衡、人才流失与职业认同危机等结构性矛盾" "详略策略:技术创新与传统技艺的碰撞" ], "chapters": [] } ```""" print("\n测试案例:") print(test_case) print("\n" + "=" * 60) try: result = parser.parse(test_case, "手动测试") print("\n✓ 解析成功!") print("\n解析结果:") print(json.dumps(result, ensure_ascii=False, indent=2)) except Exception as e: print(f"\n✗ 解析失败: {e}") print("\n" + "=" * 60) if __name__ == "__main__": # 运行手动测试 run_manual_test() # 运行单元测试 print("\n\n运行单元测试...") unittest.main(verbosity=2)