quickjs-done-nextgen/tests/test_bjson.js

284 lines
7.1 KiB
JavaScript
Raw Normal View History

import * as bjson from "bjson";
2024-10-10 19:39:12 +00:00
import { assert } from "./assert.js";
2020-09-06 16:53:08 +00:00
function base64decode(s) {
var A = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var n = s.indexOf("=");
if (n < 0) n = s.length;
if (n & 3 === 1) throw Error("bad base64"); // too much padding
var r = new Uint8Array(3 * (n>>2) + (n>>1 & 1) + (n & 1));
var a, b, c, d, i, j;
a = b = c = d = i = j = 0;
while (i+3 < n) {
a = A.indexOf(s[i++]);
b = A.indexOf(s[i++]);
c = A.indexOf(s[i++]);
d = A.indexOf(s[i++]);
if (~63 & (a|b|c|d)) throw Error("bad base64");
r[j++] = a<<2 | b>>4;
r[j++] = 255 & b<<4 | c>>2;
r[j++] = 255 & c<<6 | d;
}
switch (n & 3) {
case 2:
a = A.indexOf(s[i++]);
b = A.indexOf(s[i++]);
if (~63 & (a|b)) throw Error("bad base64");
if (b & 15) throw Error("bad base64");
r[j++] = a<<2 | b>>4;
break;
case 3:
a = A.indexOf(s[i++]);
b = A.indexOf(s[i++]);
c = A.indexOf(s[i++]);
if (~63 & (a|b|c)) throw Error("bad base64");
if (c & 3) throw Error("bad base64");
r[j++] = a<<2 | b>>4;
r[j++] = 255 & b<<4 | c>>2;
break;
}
return r.buffer;
}
2020-09-06 16:53:08 +00:00
function toHex(a)
{
var i, s = "", tab, v;
tab = new Uint8Array(a);
for(i = 0; i < tab.length; i++) {
v = tab[i].toString(16);
if (v.length < 2)
v = "0" + v;
if (i !== 0)
s += " ";
s += v;
}
return s;
}
2020-09-06 17:07:30 +00:00
function isArrayLike(a)
{
return Array.isArray(a) ||
2020-09-06 17:07:30 +00:00
(a instanceof Uint8ClampedArray) ||
(a instanceof Uint8Array) ||
(a instanceof Uint16Array) ||
(a instanceof Uint32Array) ||
(a instanceof Int8Array) ||
(a instanceof Int16Array) ||
(a instanceof Int32Array) ||
2024-09-03 18:32:17 +00:00
(a instanceof Float16Array) ||
2020-09-06 17:07:30 +00:00
(a instanceof Float32Array) ||
(a instanceof Float64Array);
}
2020-09-06 16:53:08 +00:00
function toStr(a)
{
var s, i, props, prop;
switch(typeof(a)) {
case "object":
if (a === null)
return "null";
2020-09-06 17:07:30 +00:00
if (a instanceof Date) {
s = "Date(" + toStr(a.valueOf()) + ")";
} else if (a instanceof Number) {
s = "Number(" + toStr(a.valueOf()) + ")";
} else if (a instanceof String) {
s = "String(" + toStr(a.valueOf()) + ")";
} else if (a instanceof Boolean) {
s = "Boolean(" + toStr(a.valueOf()) + ")";
} else if (isArrayLike(a)) {
2020-09-06 16:53:08 +00:00
s = "[";
for(i = 0; i < a.length; i++) {
if (i != 0)
s += ",";
s += toStr(a[i]);
}
s += "]";
} else {
props = Object.keys(a);
s = "{";
for(i = 0; i < props.length; i++) {
if (i != 0)
s += ",";
prop = props[i];
s += prop + ":" + toStr(a[prop]);
}
s += "}";
}
return s;
case "undefined":
return "undefined";
case "string":
return JSON.stringify(a);
2020-09-06 16:53:08 +00:00
case "number":
if (a == 0 && 1 / a < 0)
return "-0";
else
return a.toString();
break;
default:
return a.toString();
}
}
function bjson_test(a)
{
var buf, r, a_str, r_str;
a_str = toStr(a);
buf = bjson.write(a);
if (0) {
print(a_str, "->", toHex(buf));
}
r = bjson.read(buf, 0, buf.byteLength);
r_str = toStr(r);
if (a_str != r_str) {
print(a_str);
print(r_str);
assert(false);
}
}
2020-09-06 17:07:30 +00:00
/* test multiple references to an object including circular
references */
function bjson_test_reference()
{
var array, buf, i, n, array_buffer;
n = 16;
array = [];
for(i = 0; i < n; i++)
array[i] = {};
array_buffer = new ArrayBuffer(n);
for(i = 0; i < n; i++) {
array[i].next = array[(i + 1) % n];
array[i].idx = i;
array[i].typed_array = new Uint8Array(array_buffer, i, 1);
}
buf = bjson.write(array, bjson.WRITE_OBJ_REFERENCE);
2020-09-06 17:07:30 +00:00
array = bjson.read(buf, 0, buf.byteLength, bjson.READ_OBJ_REFERENCE);
2020-09-06 17:07:30 +00:00
/* check the result */
for(i = 0; i < n; i++) {
assert(array[i].next, array[(i + 1) % n]);
assert(array[i].idx, i);
assert(array[i].typed_array.buffer, array_buffer);
assert(array[i].typed_array.length, 1);
assert(array[i].typed_array.byteOffset, i);
}
}
function bjson_test_regexp()
{
var buf, r;
bjson_test(/xyzzy/);
bjson_test(/xyzzy/digu);
buf = bjson.write(/(?<𝓓𝓸𝓰>dog)/);
r = bjson.read(buf, 0, buf.byteLength);
assert("sup dog".match(r).groups["𝓓𝓸𝓰"], "dog");
}
function bjson_test_map()
{
var buf, r, xs;
xs = [["key", "value"]];
buf = bjson.write(new Map(xs));
r = bjson.read(buf, 0, buf.byteLength);
assert(r instanceof Map);
assert([...r].toString(), xs.toString());
}
function bjson_test_set()
{
var buf, r, xs;
xs = ["one", "two", "three"];
buf = bjson.write(new Set(xs));
r = bjson.read(buf, 0, buf.byteLength);
assert(r instanceof Set);
assert([...r].toString(), xs.toString());
}
function bjson_test_symbol()
{
var buf, r, o;
o = {[Symbol.toStringTag]: "42"};
buf = bjson.write(o);
r = bjson.read(buf, 0, buf.byteLength);
assert(o.toString(), r.toString());
o = Symbol('foo');
buf = bjson.write(o);
r = bjson.read(buf, 0, buf.byteLength);
assert(o.toString(), r.toString());
assert(o !== r);
o = Symbol.for('foo');
buf = bjson.write(o);
r = bjson.read(buf, 0, buf.byteLength);
2024-10-10 19:39:12 +00:00
assert(o, r);
o = Symbol.toStringTag;
buf = bjson.write(o);
r = bjson.read(buf, 0, buf.byteLength);
2024-10-10 19:39:12 +00:00
assert(o, r);
}
function bjson_test_fuzz()
{
var corpus = [
"EBAAAAAABGA=",
"EObm5oIt",
"EAARABMGBgYGBgYGBgYGBv////8QABEALxH/vy8R/78=",
];
for (var input of corpus) {
var buf = base64decode(input);
try {
bjson.read(buf, 0, buf.byteLength);
} catch (e) {
// okay, ignore
}
}
}
2020-09-06 16:53:08 +00:00
function bjson_test_all()
{
var obj;
2020-09-06 16:53:08 +00:00
bjson_test({x:1, y:2, if:3});
bjson_test([1, 2, 3]);
bjson_test([1.0, "aa", true, false, undefined, null, NaN, -Infinity, -0.0]);
if (typeof BigInt !== "undefined") {
bjson_test([BigInt("1"), -BigInt("0x123456789"),
BigInt("0x123456789abcdef123456789abcdef")]);
}
2020-09-06 17:07:30 +00:00
bjson_test([new Date(1234), new String("abc"), new Number(-12.1), new Boolean(true)]);
bjson_test(new Int32Array([123123, 222111, -32222]));
2024-09-03 18:32:17 +00:00
bjson_test(new Float16Array([1024, 1024.5]));
2020-09-06 17:07:30 +00:00
bjson_test(new Float64Array([123123, 222111.5]));
2020-09-06 16:53:08 +00:00
/* tested with a circular reference */
obj = {};
obj.x = obj;
try {
bjson.write(obj);
assert(false);
} catch(e) {
assert(e instanceof TypeError);
}
2020-09-06 17:07:30 +00:00
bjson_test_reference();
bjson_test_regexp();
bjson_test_map();
bjson_test_set();
bjson_test_symbol();
bjson_test_fuzz();
2020-09-06 16:53:08 +00:00
}
bjson_test_all();