load.ha (4990B)
1 use fmt; 2 3 fn roundtrip(input: str, expected: value) void = { 4 const val = loadstr(input)!; 5 defer finish(val); 6 assert(equal(val, expected)); 7 const s = dumpstr(val); 8 defer free(s); 9 const val = loadstr(input)!; 10 defer finish(val); 11 assert(equal(val, expected)); 12 }; 13 14 fn errassert(input: str, expected_loc: (uint, uint)) void = { 15 const loc = loadstr(input) as invalid; 16 if (loc.0 != expected_loc.0 || loc.1 != expected_loc.1) { 17 fmt::errorfln("=== JSON:\n{}", input)!; 18 fmt::errorfln("=== expected error location:\n({}, {})", 19 expected_loc.0, expected_loc.1)!; 20 fmt::errorfln("=== actual error location:\n({}, {})", 21 loc.0, loc.1)!; 22 abort(); 23 }; 24 }; 25 26 @test fn load() void = { 27 let obj = newobject(); 28 defer finish(obj); 29 let obj2 = newobject(); 30 defer finish(obj2); 31 32 roundtrip(`1234`, 1234.0); 33 roundtrip(`[]`, []); 34 roundtrip(`[1, 2, 3, null]`, [1.0, 2.0, 3.0, _null]); 35 roundtrip(`{}`, obj); 36 set(&obj, "hello", "world"); 37 set(&obj, "answer", 42.0); 38 roundtrip(`{ "hello": "world", "answer": 42 }`, obj); 39 reset(&obj); 40 roundtrip(`[[] ]`, [[]]); 41 roundtrip(`[""]`, [""]); 42 roundtrip(`["a"]`, ["a"]); 43 roundtrip(`[false]`, [false]); 44 roundtrip(`[null, 1, "1", {}]`, [_null, 1.0, "1", obj]); 45 roundtrip(`[null]`, [_null]); 46 roundtrip("[1\n]", [1.0]); 47 roundtrip(`[1,null,null,null,2]`, [1.0, _null, _null, _null, 2.0]); 48 set(&obj, "", 0.0); 49 roundtrip(`{"":0}`, obj); 50 reset(&obj); 51 set(&obj, "foo\0bar", 42.0); 52 roundtrip(`{"foo\u0000bar": 42}`, obj); 53 reset(&obj); 54 set(&obj, "min", -1.0e+28); 55 set(&obj, "max", +1.0e+28); 56 roundtrip(`{"min": -1.0e+28, "max": 1.0e+28}`, obj); 57 reset(&obj); 58 set(&obj, "id", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); 59 set(&obj2, "id", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); 60 set(&obj, "x", [obj2]); 61 roundtrip(`{"x":[{"id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}], "id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}`, obj); 62 reset(&obj); 63 reset(&obj2); 64 set(&obj, "a", []); 65 roundtrip(`{"a":[]}`, obj); 66 roundtrip("{\n" `"a": []` "\n}", obj); 67 reset(&obj); 68 roundtrip(`"\u0060\u012a\u12AB"`, "\u0060\u012a\u12AB"); 69 roundtrip(`"\"\\\/\b\f\n\r\t"`, "\"\\/\b\f\n\r\t"); 70 roundtrip(`"\\u0000"`, `\u0000`); 71 roundtrip(`"\""`, `"`); 72 roundtrip(`"a/*b*/c/*d//e"`, "a/*b*/c/*d//e"); 73 roundtrip(`"\\a"`, `\a`); 74 roundtrip(`"\\n"`, `\n`); 75 roundtrip(`"\u0012"`, "\u0012"); 76 roundtrip(`[ "asd"]`, ["asd"]); 77 roundtrip(`"new\u000Aline"`, "new\nline"); 78 roundtrip(`"\u0000"`, "\0"); 79 roundtrip(`"\u002c"`, "\u002c"); 80 roundtrip(`"asd "`, "asd "); 81 roundtrip(`" "`, " "); 82 roundtrip(`"\u0821"`, "\u0821"); 83 roundtrip(`"\u0123"`, "\u0123"); 84 roundtrip(`"\u0061\u30af\u30EA\u30b9"`, "\u0061\u30af\u30EA\u30b9"); 85 roundtrip(`"\uA66D"`, "\uA66D"); 86 roundtrip(`"\u005C"`, `\`); 87 roundtrip(`"\u0022"`, `"`); 88 roundtrip(`""`, ""); 89 roundtrip(` [] `, []); 90 91 errassert(`[1,,]`, (1, 4)); 92 errassert(`[1 true]`, (1, 7)); 93 errassert(`["": 1]`, (1, 4)); 94 errassert(`[,1]`, (1, 2)); 95 errassert(`[1,,2]`, (1, 4)); 96 errassert(`["",]`, (1, 5)); 97 errassert(`["x"`, (1, 5)); 98 errassert(`[x`, (1, 2)); 99 errassert(`[3[4]]`, (1, 3)); 100 errassert(`[1:2]`, (1, 3)); 101 errassert(`[,]`, (1, 2)); 102 errassert(`[-]`, (1, 3)); 103 errassert(`[ , ""]`, (1, 5)); 104 errassert("[\"a\",\n4\n,1,", (3, 4)); 105 errassert(`[1,]`, (1, 4)); 106 errassert("[\"\va\"\\f", (1, 3)); 107 errassert(`[*]`, (1, 2)); 108 errassert(`[1,`, (1, 4)); 109 errassert("[1,\n1\n,1", (3, 3)); 110 errassert(`[{}`, (1, 4)); 111 errassert(`["x", truth]`, (1, 11)); 112 errassert(`{[: "x"}`, (1, 2)); 113 errassert(`{"x", null}`, (1, 5)); 114 errassert(`{"x"::"b"}`, (1, 6)); 115 errassert(`{"a":"a" 123}`, (1, 12)); 116 errassert(`{"a" b}`, (1, 6)); 117 errassert(`{:"b"}`, (1, 2)); 118 errassert(`{"a" "b"}`, (1, 8)); 119 errassert(`{"a":`, (1, 6)); 120 errassert(`{"a"`, (1, 5)); 121 errassert(`{1:1}`, (1, 2)); 122 errassert(`{9999E9999:1}`, (1, 10)); 123 errassert(`{null:null,null:null}`, (1, 5)); 124 errassert(`{"id":0,,,,,}`, (1, 9)); 125 errassert(`{'a':0}`, (1, 2)); 126 errassert(`{"id":0,}`, (1, 9)); 127 errassert(`{"a":"b",,"c":"d"}`, (1, 10)); 128 errassert(`{true: false}`, (1, 5)); 129 errassert(`{"a":"a`, (1, 8)); 130 errassert(`{ "foo" : "bar", "a" }`, (1, 22)); 131 errassert(` `, (1, 2)); 132 errassert(`<null>`, (1, 1)); 133 errassert(`["asd]`, (1, 7)); 134 errassert(`True`, (1, 4)); 135 errassert(`]`, (1, 1)); 136 errassert(`}`, (1, 1)); 137 errassert(`{"x": true,`, (1, 12)); 138 errassert(`[`, (1, 2)); 139 errassert(`{`, (1, 2)); 140 errassert(``, (1, 1)); 141 errassert("\0", (1, 1)); 142 errassert(`{"":`, (1, 5)); 143 errassert(`['`, (1, 2)); 144 errassert(`["`, (1, 3)); 145 errassert(`[,`, (1, 2)); 146 errassert(`[{`, (1, 3)); 147 errassert(`{[`, (1, 2)); 148 errassert(`{]`, (1, 2)); 149 errassert(`[}`, (1, 2)); 150 errassert(`{'`, (1, 2)); 151 errassert(`{"`, (1, 3)); 152 errassert(`{,`, (1, 2)); 153 errassert(`["\{["\{["\{["\{`, (1, 4)); 154 errassert(`*`, (1, 1)); 155 errassert(`\u000A""`, (1, 1)); 156 errassert("\f", (1, 1)); 157 }; 158 159 @test fn nestlimit() void = { 160 const s = `{ "foo": [[[{"bar": ["baz"]}]]] }`; 161 const val = loadstr(s, 6: nestlimit)!; 162 finish(val); 163 assert(loadstr(s, 5: nestlimit) is limitreached); 164 };