130 lines
4.6 KiB
Plaintext
130 lines
4.6 KiB
Plaintext
var wota = use('wota')
|
|
var os = use('os')
|
|
var blob = use('blob')
|
|
var math = use('math/radians')
|
|
|
|
var EPSILON = 1e-12
|
|
|
|
function stone_if_needed(b) { if (!stone.p(b)) stone(b) }
|
|
|
|
/* Deep comparison capable of blobs + tolerance for floating diff */
|
|
function deep_compare(expected, actual, path) {
|
|
path = path || ''
|
|
if (expected == actual) return { passed: true, messages: [] }
|
|
|
|
if (is_number(expected) && is_number(actual)) {
|
|
if (isNaN(expected) && isNaN(actual)) return { passed: true, messages: [] }
|
|
var diff = abs(expected - actual)
|
|
if (diff <= EPSILON) return { passed: true, messages: [] }
|
|
return { passed: false, messages: [`Value mismatch at ${path}: ${expected} vs ${actual} (diff ${diff})`] }
|
|
}
|
|
|
|
if (is_blob(expected) && is_blob(actual)) {
|
|
stone_if_needed(expected); stone_if_needed(actual)
|
|
if (expected.length != actual.length)
|
|
return { passed: false, messages: [`blob length mismatch at ${path}: ${expected.length} vs ${actual.length}`] }
|
|
for (var i = 0; i < expected.length; i++) {
|
|
if (expected.read_logical(i) != actual.read_logical(i))
|
|
return { passed: false, messages: [`blob bit mismatch at ${path}[${i}]`] }
|
|
}
|
|
return { passed: true, messages: [] }
|
|
}
|
|
|
|
if (is_array(expected) && is_array(actual)) {
|
|
if (expected.length != actual.length)
|
|
return { passed: false, messages: [`Array length mismatch at ${path}: ${expected.length} vs ${actual.length}`] }
|
|
var msgs = []
|
|
for (var i = 0; i < expected.length; i++) {
|
|
var res = deep_compare(expected[i], actual[i], `${path}[${i}]`)
|
|
if (!res.passed) {
|
|
for(var m of res.messages) msgs.push(m)
|
|
}
|
|
}
|
|
return { passed: msgs.length == 0, messages: msgs }
|
|
}
|
|
|
|
if (is_object(expected) && is_object(actual)) {
|
|
var expKeys = sort(array(expected))
|
|
var actKeys = sort(array(actual))
|
|
if (JSON.stringify(expKeys) != JSON.stringify(actKeys))
|
|
return { passed: false, messages: [`Object keys mismatch at ${path}: ${expKeys} vs ${actKeys}`] }
|
|
var msgs = []
|
|
for (var k of expKeys) {
|
|
var res = deep_compare(expected[k], actual[k], `${path}.${k}`)
|
|
if (!res.passed) {
|
|
for(var m of res.messages) msgs.push(m)
|
|
}
|
|
}
|
|
return { passed: msgs.length == 0, messages: msgs }
|
|
}
|
|
|
|
return { passed: false, messages: [`Value mismatch at ${path}: ${JSON.stringify(expected)} vs ${JSON.stringify(actual)}`] }
|
|
}
|
|
|
|
var testarr = []
|
|
for (var i = 0; i < 500; i++) { testarr.push(1) }
|
|
|
|
var testCases = [
|
|
{ name: 'zero', input: 0 },
|
|
{ name: '2023', input: 2023 },
|
|
{ name: 'neg1', input: -1 },
|
|
{ name: '7', input: 7 },
|
|
{ name: 'neg7', input: -7 },
|
|
{ name: '1023', input: 1023 },
|
|
{ name: 'neg1023', input: -1023 },
|
|
{ name: 'large_pos', input: math.power(2, 55) - 1 },
|
|
{ name: 'large_neg', input: -math.power(2, 55) },
|
|
|
|
{ name: 'null', input: null },
|
|
{ name: 'false', input: false },
|
|
{ name: 'true', input: true },
|
|
|
|
{ name: 'float_neg1_01', input: -1.01 },
|
|
{ name: 'float_98_6', input: 98.6 },
|
|
{ name: 'float_euler', input: -0.5772156649 },
|
|
{ name: 'float_precision', input: -1.00000000000001 },
|
|
{ name: 'float_large_neg', input: -10000000000000 },
|
|
{ name: 'float_pow2_55', input: math.power(2, 55) },
|
|
|
|
{ name: 'empty_string', input: '' },
|
|
{ name: 'string_cat', input: 'cat' },
|
|
{ name: 'string_unicode', input: 'U+1F4A9 「うんち絵文字」 «💩»' },
|
|
|
|
{ name: 'large_array', input: testarr },
|
|
|
|
{ name: 'empty_array', input: [] },
|
|
{ name: 'array_123', input: [1, 2, 3] },
|
|
{ name: 'array_mixed', input: [-1, 0, 1.5] },
|
|
|
|
{ name: 'empty_object', input: {} },
|
|
{ name: 'object_ab', input: { a: 1, b: 2 } },
|
|
|
|
{ name: 'nested_object', input: { num: 42, arr: [1, -1, 2.5], str: 'test', obj: { x: true } } },
|
|
|
|
{ name: 'empty_blob', input: blob() },
|
|
{ name: 'nested_array', input: [[]] },
|
|
{ name: 'empty_key_val', input: { '': '' } },
|
|
{ name: 'small_float', input: 1e-10 }
|
|
]
|
|
|
|
function make_test(t) {
|
|
return function() {
|
|
var enc = wota.encode(t.input)
|
|
if (!is_blob(enc)) throw 'encode() should return a blob'
|
|
|
|
var dec = wota.decode(enc)
|
|
|
|
var cmp = deep_compare(t.input, dec)
|
|
if (!cmp.passed) throw text(cmp.messages, '; ')
|
|
}
|
|
}
|
|
|
|
var tests = {}
|
|
for (var i = 0; i < testCases.length; i++) {
|
|
var t = testCases[i]
|
|
var name = t.name || ('case_' + i)
|
|
tests[name] = make_test(t)
|
|
}
|
|
|
|
return tests
|