| 14 | } |
| 15 | |
| 16 | static void test_json_healing() { |
| 17 | auto parse = [](const std::string & str) { |
| 18 | std::cerr << "# Parsing: " << str << '\n'; |
| 19 | std::string::const_iterator it = str.begin(); |
| 20 | const auto end = str.end(); |
| 21 | common_json out; |
| 22 | std::string healing_marker = "$llama.cpp.json$"; |
| 23 | if (common_json_parse(it, end, healing_marker, out)) { |
| 24 | auto dump = out.json.dump(); |
| 25 | std::cerr << "Parsed: " << dump << '\n'; |
| 26 | std::cerr << "Magic: " << out.healing_marker.json_dump_marker << '\n'; |
| 27 | std::string result; |
| 28 | if (!out.healing_marker.json_dump_marker.empty()) { |
| 29 | auto i = dump.find(out.healing_marker.json_dump_marker); |
| 30 | if (i == std::string::npos) { |
| 31 | throw std::runtime_error("Failed to find magic in dump " + dump + " (magic: " + out.healing_marker.json_dump_marker + ")"); |
| 32 | } |
| 33 | result = dump.substr(0, i); |
| 34 | } else { |
| 35 | result = dump; |
| 36 | } |
| 37 | std::cerr << "Result: " << result << '\n'; |
| 38 | if (string_starts_with(str, result)) { |
| 39 | std::cerr << "Failure!\n"; |
| 40 | } |
| 41 | // return dump; |
| 42 | } else { |
| 43 | throw std::runtime_error("Failed to parse: " + str); |
| 44 | } |
| 45 | |
| 46 | }; |
| 47 | auto parse_all = [&](const std::string & str) { |
| 48 | for (size_t i = 1; i < str.size(); i++) { |
| 49 | parse(str.substr(0, i)); |
| 50 | } |
| 51 | }; |
| 52 | parse_all("{\"a\": \"b\"}"); |
| 53 | parse_all("{\"hey\": 1, \"ho\\\"ha\": [1]}"); |
| 54 | |
| 55 | parse_all("[{\"a\": \"b\"}]"); |
| 56 | |
| 57 | auto test = [&](const std::vector<std::string> & inputs, const std::string & expected, const std::string & expected_marker) { |
| 58 | for (const auto & input : inputs) { |
| 59 | common_json out; |
| 60 | assert_equals(true, common_json_parse(input, "$foo", out)); |
| 61 | assert_equals<std::string>(expected, out.json.dump()); |
| 62 | assert_equals<std::string>(expected_marker, out.healing_marker.json_dump_marker); |
| 63 | } |
| 64 | }; |
| 65 | // No healing needed: |
| 66 | test( |
| 67 | { |
| 68 | R"([{"a":"b"}, "y"])", |
| 69 | }, |
| 70 | R"([{"a":"b"},"y"])", |
| 71 | "" |
| 72 | ); |
| 73 | // Partial literals can't be healed: |
no test coverage detected