1import * as bjson from "./bjson.so";
2
3function assert(actual, expected, message) {
4    if (arguments.length == 1)
5        expected = true;
6
7    if (actual === expected)
8        return;
9
10    if (actual !== null && expected !== null
11    &&  typeof actual == 'object' && typeof expected == 'object'
12    &&  actual.toString() === expected.toString())
13        return;
14
15    throw Error("assertion failed: got |" + actual + "|" +
16                ", expected |" + expected + "|" +
17                (message ? " (" + message + ")" : ""));
18}
19
20function toHex(a)
21{
22    var i, s = "", tab, v;
23    tab = new Uint8Array(a);
24    for(i = 0; i < tab.length; i++) {
25        v = tab[i].toString(16);
26        if (v.length < 2)
27            v = "0" + v;
28        if (i !== 0)
29            s += " ";
30        s += v;
31    }
32    return s;
33}
34
35function isArrayLike(a)
36{
37    return Array.isArray(a) ||
38        (a instanceof Uint8ClampedArray) ||
39        (a instanceof Uint8Array) ||
40        (a instanceof Uint16Array) ||
41        (a instanceof Uint32Array) ||
42        (a instanceof Int8Array) ||
43        (a instanceof Int16Array) ||
44        (a instanceof Int32Array) ||
45        (a instanceof Float32Array) ||
46        (a instanceof Float64Array);
47}
48
49function toStr(a)
50{
51    var s, i, props, prop;
52
53    switch(typeof(a)) {
54    case "object":
55        if (a === null)
56            return "null";
57        if (a instanceof Date) {
58            s = "Date(" + toStr(a.valueOf()) + ")";
59        } else if (a instanceof Number) {
60            s = "Number(" + toStr(a.valueOf()) + ")";
61        } else if (a instanceof String) {
62            s = "String(" + toStr(a.valueOf()) + ")";
63        } else if (a instanceof Boolean) {
64            s = "Boolean(" + toStr(a.valueOf()) + ")";
65        } else if (isArrayLike(a)) {
66            s = "[";
67            for(i = 0; i < a.length; i++) {
68                if (i != 0)
69                    s += ",";
70                s += toStr(a[i]);
71            }
72            s += "]";
73        } else {
74            props = Object.keys(a);
75            s = "{";
76            for(i = 0; i < props.length; i++) {
77                if (i != 0)
78                    s += ",";
79                prop = props[i];
80                s += prop + ":" + toStr(a[prop]);
81            }
82            s += "}";
83        }
84        return s;
85    case "undefined":
86        return "undefined";
87    case "string":
88        return a.__quote();
89    case "number":
90    case "bigfloat":
91        if (a == 0 && 1 / a < 0)
92            return "-0";
93        else
94            return a.toString();
95        break;
96    default:
97        return a.toString();
98    }
99}
100
101function bjson_test(a)
102{
103    var buf, r, a_str, r_str;
104    a_str = toStr(a);
105    buf = bjson.write(a);
106    if (0) {
107        print(a_str, "->", toHex(buf));
108    }
109    r = bjson.read(buf, 0, buf.byteLength);
110    r_str = toStr(r);
111    if (a_str != r_str) {
112        print(a_str);
113        print(r_str);
114        assert(false);
115    }
116}
117
118/* test multiple references to an object including circular
119   references */
120function bjson_test_reference()
121{
122    var array, buf, i, n, array_buffer;
123    n = 16;
124    array = [];
125    for(i = 0; i < n; i++)
126        array[i] = {};
127    array_buffer = new ArrayBuffer(n);
128    for(i = 0; i < n; i++) {
129        array[i].next = array[(i + 1) % n];
130        array[i].idx = i;
131        array[i].typed_array = new Uint8Array(array_buffer, i, 1);
132    }
133    buf = bjson.write(array, true);
134
135    array = bjson.read(buf, 0, buf.byteLength, true);
136
137    /* check the result */
138    for(i = 0; i < n; i++) {
139        assert(array[i].next, array[(i + 1) % n]);
140        assert(array[i].idx, i);
141        assert(array[i].typed_array.buffer, array_buffer);
142        assert(array[i].typed_array.length, 1);
143        assert(array[i].typed_array.byteOffset, i);
144    }
145}
146
147function bjson_test_all()
148{
149    var obj;
150
151    bjson_test({x:1, y:2, if:3});
152    bjson_test([1, 2, 3]);
153    bjson_test([1.0, "aa", true, false, undefined, null, NaN, -Infinity, -0.0]);
154    if (typeof BigInt !== "undefined") {
155        bjson_test([BigInt("1"), -BigInt("0x123456789"),
156               BigInt("0x123456789abcdef123456789abcdef")]);
157    }
158    if (typeof BigFloat !== "undefined") {
159        BigFloatEnv.setPrec(function () {
160            bjson_test([BigFloat("0.1"), BigFloat("-1e30"), BigFloat("0"),
161                   BigFloat("-0"), BigFloat("Infinity"), BigFloat("-Infinity"),
162                   0.0 / BigFloat("0"), BigFloat.MAX_VALUE,
163                   BigFloat.MIN_VALUE]);
164        }, 113, 15);
165    }
166    if (typeof BigDecimal !== "undefined") {
167        bjson_test([BigDecimal("0"),
168                    BigDecimal("0.8"), BigDecimal("123321312321321e100"),
169                    BigDecimal("-1233213123213214332333223332e100"),
170                    BigDecimal("1.233e-1000")]);
171    }
172
173    bjson_test([new Date(1234), new String("abc"), new Number(-12.1), new Boolean(true)]);
174
175    bjson_test(new Int32Array([123123, 222111, -32222]));
176    bjson_test(new Float64Array([123123, 222111.5]));
177
178    /* tested with a circular reference */
179    obj = {};
180    obj.x = obj;
181    try {
182        bjson.write(obj);
183        assert(false);
184    } catch(e) {
185        assert(e instanceof TypeError);
186    }
187
188    bjson_test_reference();
189}
190
191bjson_test_all();
192