This commit is contained in:
2026-01-08 12:07:32 -06:00
parent ef94b55058
commit 8203f6d1c3
16 changed files with 75 additions and 178 deletions

View File

@@ -7,7 +7,7 @@ function mainThread() {
var longLivedTree = bottomUpTree(maxDepth); var longLivedTree = bottomUpTree(maxDepth);
for (let depth = 4; depth <= maxDepth; depth += 2) { for (var depth = 4; depth <= maxDepth; depth += 2) {
var iterations = 1 << maxDepth - depth + 4; var iterations = 1 << maxDepth - depth + 4;
work(iterations, depth); work(iterations, depth);
} }
@@ -16,8 +16,8 @@ function mainThread() {
} }
function work(iterations, depth) { function work(iterations, depth) {
let check = 0; var check = 0;
for (let i = 0; i < iterations; i++) for (var i = 0; i < iterations; i++)
check += itemCheck(bottomUpTree(depth)); check += itemCheck(bottomUpTree(depth));
log.console(`${iterations}\t trees of depth ${depth}\t check: ${check}`); log.console(`${iterations}\t trees of depth ${depth}\t check: ${check}`);
} }

View File

@@ -1,6 +1,6 @@
function fannkuch(n) { function fannkuch(n) {
var perm1 = [n] var perm1 = [n]
for (let i = 0; i < n; i++) perm1[i] = i for (var i = 0; i < n; i++) perm1[i] = i
var perm = [n] var perm = [n]
var count = [n] var count = [n]
var f = 0, flips = 0, nperm = 0, checksum = 0 var f = 0, flips = 0, nperm = 0, checksum = 0
@@ -18,7 +18,7 @@ function fannkuch(n) {
while (k != 0) { while (k != 0) {
i = 0 i = 0
while (2*i < k) { while (2*i < k) {
let t = perm[i]; perm[i] = perm[k-i]; perm[k-i] = t var t = perm[i]; perm[i] = perm[k-i]; perm[k-i] = t
i += 1 i += 1
} }
k = perm[0] k = perm[0]
@@ -34,10 +34,10 @@ function fannkuch(n) {
log.console( checksum ) log.console( checksum )
return flips return flips
} }
let p0 = perm1[0] var p0 = perm1[0]
i = 0 i = 0
while (i < r) { while (i < r) {
let j = i + 1 var j = i + 1
perm1[i] = perm1[j] perm1[i] = perm1[j]
i = j i = j
} }

View File

@@ -8,15 +8,15 @@ var w = h
log.console(`P4\n${w} ${h}`); log.console(`P4\n${w} ${h}`);
for (let y = 0; y < h; ++y) { for (var y = 0; y < h; ++y) {
// Create a blob for the row - we need w bits // Create a blob for the row - we need w bits
var row = new blob(w); var row = new blob(w);
for (let x = 0; x < w; ++x) { for (var x = 0; x < w; ++x) {
zr = zi = tr = ti = 0; zr = zi = tr = ti = 0;
cr = 2 * x / w - 1.5; cr = 2 * x / w - 1.5;
ci = 2 * y / h - 1; ci = 2 * y / h - 1;
for (let i = 0; i < iter && (tr + ti <= limit * limit); ++i) { for (var i = 0; i < iter && (tr + ti <= limit * limit); ++i) {
zi = 2 * zr * zi + ci; zi = 2 * zr * zi + ci;
zr = tr - ti + cr; zr = tr - ti + cr;
tr = zr * zr; tr = zr * zr;

View File

@@ -19,15 +19,15 @@ var notaDecodeTimes = [];
var notaSizes = []; var notaSizes = [];
// Run 100 tests // Run 100 tests
for (let i = 0; i < 100; i++) { for (var i = 0; i < 100; i++) {
// JSON Decode test // JSON Decode test
let start = os.now(); var start = os.now();
var jll = json.decode(ll); var jll = json.decode(ll);
jsonDecodeTimes.push((os.now() - start) * 1000); jsonDecodeTimes.push((os.now() - start) * 1000);
// JSON Encode test // JSON Encode test
start = os.now(); start = os.now();
let jsonStr = JSON.stringify(jll); var jsonStr = JSON.stringify(jll);
jsonEncodeTimes.push((os.now() - start) * 1000); jsonEncodeTimes.push((os.now() - start) * 1000);
// NOTA Encode test // NOTA Encode test

View File

@@ -14,18 +14,18 @@
// Helper to run a function repeatedly and measure total time in seconds. // Helper to run a function repeatedly and measure total time in seconds.
// Returns elapsed time in seconds. // Returns elapsed time in seconds.
function measureTime(fn, iterations) { function measureTime(fn, iterations) {
let t1 = os.now(); var t1 = os.now();
for (let i = 0; i < iterations; i++) { for (var i = 0; i < iterations; i++) {
fn(); fn();
} }
let t2 = os.now(); var t2 = os.now();
return t2 - t1; return t2 - t1;
} }
// We'll define a function that does `encode -> decode` for a given value: // We'll define a function that does `encode -> decode` for a given value:
function roundTripWota(value) { function roundTripWota(value) {
let encoded = wota.encode(value); var encoded = wota.encode(value);
let decoded = wota.decode(encoded); var decoded = wota.decode(encoded);
// Not doing a deep compare here, just measuring performance. // Not doing a deep compare here, just measuring performance.
// (We trust the test suite to verify correctness.) // (We trust the test suite to verify correctness.)
} }
@@ -79,22 +79,22 @@ log.console("Wota Encode/Decode Benchmark");
log.console("===================\n"); log.console("===================\n");
// We'll run each benchmark scenario in turn. // We'll run each benchmark scenario in turn.
for (let bench of benchmarks) { for (var bench of benchmarks) {
// We'll measure how long it takes to do 'iterations' *for each test value* // We'll measure how long it takes to do 'iterations' *for each test value*
// in bench.data. The total loop count is `bench.iterations * bench.data.length`. // in bench.data. The total loop count is `bench.iterations * bench.data.length`.
// Then we compute an overall encode+decode throughput (ops/s). // Then we compute an overall encode+decode throughput (ops/s).
let totalIterations = bench.iterations * bench.data.length; var totalIterations = bench.iterations * bench.data.length;
// We'll define a function that does a roundTrip for *each* data item in bench.data // We'll define a function that does a roundTrip for *each* data item in bench.data
// to measure in one loop iteration. Then we multiply by bench.iterations. // to measure in one loop iteration. Then we multiply by bench.iterations.
function runAllData() { function runAllData() {
for (let val of bench.data) { for (var val of bench.data) {
roundTripWota(val); roundTripWota(val);
} }
} }
let elapsedSec = measureTime(runAllData, bench.iterations); var elapsedSec = measureTime(runAllData, bench.iterations);
let opsPerSec = (totalIterations / elapsedSec).toFixed(1); var opsPerSec = (totalIterations / elapsedSec).toFixed(1);
log.console(`${bench.name}:`); log.console(`${bench.name}:`);
log.console(` Iterations: ${bench.iterations} × ${bench.data.length} data items = ${totalIterations}`); log.console(` Iterations: ${bench.iterations} × ${bench.data.length} data items = ${totalIterations}`);

View File

@@ -108,9 +108,9 @@ def benchmarks = [
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
function measureTime(fn) { function measureTime(fn) {
let start = os.now(); var start = os.now();
fn(); fn();
let end = os.now(); var end = os.now();
return (end - start); // in seconds return (end - start); // in seconds
} }
@@ -128,15 +128,15 @@ function runBenchmarkForLibrary(lib, bench) {
// Pre-store the encoded results for all items so we can measure decode time // Pre-store the encoded results for all items so we can measure decode time
// in a separate pass. Also measure total size once. // in a separate pass. Also measure total size once.
let encodedList = []; var encodedList = [];
let totalSize = 0; var totalSize = 0;
// 1) Measure ENCODING // 1) Measure ENCODING
let encodeTime = measureTime(() => { var encodeTime = measureTime(() => {
for (let i = 0; i < bench.iterations; i++) { for (var i = 0; i < bench.iterations; i++) {
// For each data item, encode it // For each data item, encode it
for (let j = 0; j < bench.data.length; j++) { for (var j = 0; j < bench.data.length; j++) {
let e = lib.encode(bench.data[j]); var e = lib.encode(bench.data[j]);
// store only in the very first iteration, so we can decode them later // store only in the very first iteration, so we can decode them later
// but do not store them every iteration or we blow up memory. // but do not store them every iteration or we blow up memory.
if (i == 0) { if (i == 0) {
@@ -148,11 +148,11 @@ function runBenchmarkForLibrary(lib, bench) {
}); });
// 2) Measure DECODING // 2) Measure DECODING
let decodeTime = measureTime(() => { var decodeTime = measureTime(() => {
for (let i = 0; i < bench.iterations; i++) { for (var i = 0; i < bench.iterations; i++) {
// decode everything we stored during the first iteration // decode everything we stored during the first iteration
for (let e of encodedList) { for (var e of encodedList) {
let decoded = lib.decode(e); var decoded = lib.decode(e);
// not verifying correctness here, just measuring speed // not verifying correctness here, just measuring speed
} }
} }

View File

@@ -133,7 +133,7 @@ log.error = function(msg = new Error())
{ {
var caller = caller_data(1) var caller = caller_data(1)
if (msg instanceof Error) if (is_proto(msg, Error))
msg = msg.name + ": " + msg.message + "\n" + msg.stack msg = msg.name + ": " + msg.message + "\n" + msg.stack
os.print(console_rec(caller.line,caller.file,msg)) os.print(console_rec(caller.line,caller.file,msg))
@@ -149,7 +149,7 @@ function disrupt(err)
if (overling) { if (overling) {
if (err) { if (err) {
// with an err, this is a forceful disrupt // with an err, this is a forceful disrupt
var reason = (err instanceof Error) ? err.stack : err var reason = (is_proto(err, Error)) ? err.stack : err
report_to_overling({type:'disrupt', reason}) report_to_overling({type:'disrupt', reason})
} else } else
report_to_overling({type:'stop'}) report_to_overling({type:'stop'})
@@ -766,8 +766,6 @@ if (!locator)
stone(globalThis) stone(globalThis)
var rads = use_core("math/radians")
$_.clock(_ => { $_.clock(_ => {
// Get capabilities for the main program // Get capabilities for the main program
var file_info = shop.file_info ? shop.file_info(locator.path) : null var file_info = shop.file_info ? shop.file_info(locator.path) : null

View File

@@ -677,7 +677,7 @@ Shop.open_package_dylib = function(pkg) {
} }
// 3. Check core internal symbols (core is never a dynamic library) // 3. Check core internal symbols (core is never a dynamic library)
var core_sym = `js_${path}_use` var core_sym = `js_${path.replaceAll('/', '_')}_use`
if (os.internal_exists(core_sym)) { if (os.internal_exists(core_sym)) {
return { return {
symbol: function() { return os.load_internal(core_sym) }, symbol: function() { return os.load_internal(core_sym) },
@@ -1174,22 +1174,22 @@ Shop.get_package_dir = function(pkg) {
// e.g., c_symbol_for_file('gitea.pockle.world/john/prosperon', 'sprite.c') // e.g., c_symbol_for_file('gitea.pockle.world/john/prosperon', 'sprite.c')
// -> 'js_gitea_pockle_world_john_prosperon_sprite_use' // -> 'js_gitea_pockle_world_john_prosperon_sprite_use'
Shop.c_symbol_for_file = function(pkg, file) { Shop.c_symbol_for_file = function(pkg, file) {
var pkg_safe = pkg.replace(/\//g, '_').replace(/\./g, '_').replace(/-/g, '_') var pkg_safe = pkg.replaceAll(/\//g, '_').replaceAll(/\./g, '_').replaceAll(/-/g, '_')
var file_safe = file.substring(0, file.lastIndexOf('.')).replace(/\//g, '_').replace(/\./g, '_').replace(/-/g, '_') var file_safe = file.substring(0, file.lastIndexOf('.')).replaceAll(/\//g, '_').replaceAll(/\./g, '_').replaceAll(/-/g, '_')
return 'js_' + pkg_safe + '_' + file_safe + '_use' return 'js_' + pkg_safe + '_' + file_safe + '_use'
} }
// Generate C symbol prefix for a package // Generate C symbol prefix for a package
// e.g., c_symbol_prefix('gitea.pockle.world/john/prosperon') -> 'js_gitea_pockle_world_john_prosperon_' // e.g., c_symbol_prefix('gitea.pockle.world/john/prosperon') -> 'js_gitea_pockle_world_john_prosperon_'
Shop.c_symbol_prefix = function(pkg) { Shop.c_symbol_prefix = function(pkg) {
var pkg_safe = pkg.replace(/\//g, '_').replace(/\./g, '_').replace(/-/g, '_') var pkg_safe = pkg.replaceAll(/\//g, '_').replaceAll(/\./g, '_').replaceAll(/-/g, '_')
return 'js_' + pkg_safe + '_' return 'js_' + pkg_safe + '_'
} }
// Get the library name for a package (without extension) // Get the library name for a package (without extension)
// e.g., 'gitea.pockle.world/john/prosperon' -> 'gitea_pockle_world_john_prosperon' // e.g., 'gitea.pockle.world/john/prosperon' -> 'gitea_pockle_world_john_prosperon'
Shop.lib_name_for_package = function(pkg) { Shop.lib_name_for_package = function(pkg) {
return pkg.replace(/\//g, '_').replace(/\./g, '_').replace(/-/g, '_') return pkg.replaceAll(/\//g, '_').replaceAll(/\./g, '_').replaceAll(/-/g, '_')
} }
// Returns { ok: bool, results: [{pkg, ok, error}] } // Returns { ok: bool, results: [{pkg, ok, error}] }

View File

@@ -114,7 +114,7 @@ if (cmd == 'list') {
if (target.startsWith('./')) { if (target.startsWith('./')) {
target = cwd + target.substring(1) target = cwd + target.substring(1)
} else { } else {
// For ../ paths, let fd.realpath handle it if possible // For ../ paths, var fd.realpath handle it if possible
target = fd.realpath(target) || target target = fd.realpath(target) || target
} }
} }

View File

@@ -29,7 +29,7 @@ function is_requestor (fn) {
} }
function check_requestors (list, factory) { function check_requestors (list, factory) {
if (!isa(list, array) || list.some(r => !is_requestor(r))) if (!is_array(list) || list.some(r => !is_requestor(r)))
throw make_reason(factory, 'Bad requestor list.', list) throw make_reason(factory, 'Bad requestor list.', list)
} }
@@ -47,9 +47,9 @@ function schedule (fn, seconds) {
// ———————————————————————————————————————— core runner // ———————————————————————————————————————— core runner
function run (factory, requestors, initial, action, time_limit, throttle = 0) { function run (factory, requestors, initial, action, time_limit, throttle = 0) {
let cancel_list = new Array(requestors.length) var cancel_list = new Array(requestors.length)
let next = 0 var next = 0
let timer_cancel var timer_cancel
function cancel (reason = make_reason(factory, 'Cancel.')) { function cancel (reason = make_reason(factory, 'Cancel.')) {
if (timer_cancel) timer_cancel(), timer_cancel = null if (timer_cancel) timer_cancel(), timer_cancel = null
@@ -60,7 +60,7 @@ function run (factory, requestors, initial, action, time_limit, throttle = 0) {
function start_requestor (value) { function start_requestor (value) {
if (!cancel_list || next >= requestors.length) return if (!cancel_list || next >= requestors.length) return
let idx = next++ var idx = next++
def req = requestors[idx] def req = requestors[idx]
try { try {
@@ -87,7 +87,7 @@ function run (factory, requestors, initial, action, time_limit, throttle = 0) {
} }
def concurrent = throttle ? number.min(throttle, requestors.length) : requestors.length def concurrent = throttle ? number.min(throttle, requestors.length) : requestors.length
for (let i = 0; i < concurrent; i++) start_requestor(initial) for (var i = 0; i < concurrent; i++) start_requestor(initial)
return cancel return cancel
} }
@@ -95,10 +95,10 @@ function run (factory, requestors, initial, action, time_limit, throttle = 0) {
// ———————————————————————————————————————— factories // ———————————————————————————————————————— factories
function _normalize (collection, factory) { function _normalize (collection, factory) {
if (isa(collection)) return { names: null, list: collection } if (is_array(collection)) return { names: null, list: collection }
if (collection && is_object(collection)) { if (collection && is_object(collection)) {
def names = array(collection) def names = array(collection)
def list = names.map(k => collection[k]).filter(is_requestor) def list = names.map(k => collection[k]).filter(is_requestor)
return { names, list } return { names, list }
} }
throw make_reason(factory, 'Expected array or record.', collection) throw make_reason(factory, 'Expected array or record.', collection)
@@ -119,7 +119,7 @@ function par_all (collection, time_limit, throttle) {
return function par_all_req (cb, initial) { return function par_all_req (cb, initial) {
check_callback(cb, factory) check_callback(cb, factory)
let pending = list.length var pending = list.length
def results = new Array(list.length) def results = new Array(list.length)
def cancel = run(factory, list, initial, (val, reason, idx) => { def cancel = run(factory, list, initial, (val, reason, idx) => {
@@ -143,7 +143,7 @@ function par_any (collection, time_limit, throttle) {
return function par_any_req (cb, initial) { return function par_any_req (cb, initial) {
check_callback(cb, factory) check_callback(cb, factory)
let pending = list.length var pending = list.length
def successes = new Array(list.length) def successes = new Array(list.length)
def cancel = run(factory, list, initial, (val, reason, idx) => { def cancel = run(factory, list, initial, (val, reason, idx) => {
@@ -161,14 +161,14 @@ function par_any (collection, time_limit, throttle) {
} }
function race (list, time_limit, throttle) { function race (list, time_limit, throttle) {
def factory = throttle == 1 ? 'fallback' : 'race' def factory = throttle == 1 ? 'fallback' : 'race'
if (!isa(list, array) || list.length == 0) if (!is_array(list) || list.length == 0)
throw make_reason(factory, 'No requestors.') throw make_reason(factory, 'No requestors.')
check_requestors(list, factory) check_requestors(list, factory)
return function race_req (cb, initial) { return function race_req (cb, initial) {
check_callback(cb, factory) check_callback(cb, factory)
let done = false var done = false
def cancel = run(factory, list, initial, (val, reason, idx) => { def cancel = run(factory, list, initial, (val, reason, idx) => {
if (done) return if (done) return
if (val != null) { if (val != null) {
@@ -190,14 +190,14 @@ function fallback (list, time_limit) {
} }
function sequence (list, time_limit) { function sequence (list, time_limit) {
def factory = 'sequence' def factory = 'sequence'
if (!isa(list, array)) throw make_reason(factory, 'Not an array.', list) if (!is_array(list)) throw make_reason(factory, 'Not an array.', list)
check_requestors(list, factory) check_requestors(list, factory)
if (list.length == 0) return (cb, v) => cb(v) if (list.length == 0) return (cb, v) => cb(v)
return function sequence_req (cb, initial) { return function sequence_req (cb, initial) {
check_callback(cb, factory) check_callback(cb, factory)
let idx = 0 var idx = 0
function next (value) { function next (value) {
if (idx >= list.length) return cb(value) if (idx >= list.length) return cb(value)

View File

@@ -5584,16 +5584,6 @@ static void mark_children(JSRuntime *rt, JSGCObjectHeader *gp,
for(i = 0; i < sh->prop_count; i++) { for(i = 0; i < sh->prop_count; i++) {
JSProperty *pr = &p->prop[i]; JSProperty *pr = &p->prop[i];
if (prs->atom != JS_ATOM_NULL) { if (prs->atom != JS_ATOM_NULL) {
/* Mark object-key symbol payload to keep key object alive */
if (!__JS_AtomIsTaggedInt(prs->atom)) {
JSAtomStruct *ap = rt->atom_array[prs->atom];
if (ap && ap->atom_type == JS_ATOM_TYPE_SYMBOL) {
JSAtomSymbol *sp = js_atom_as_symbol(ap);
if (!JS_IsNull(sp->obj_key)) {
JS_MarkValue(rt, sp->obj_key, mark_func);
}
}
}
if (prs->flags & JS_PROP_TMASK) { if (prs->flags & JS_PROP_TMASK) {
if ((prs->flags & JS_PROP_TMASK) == JS_PROP_GETSET) { if ((prs->flags & JS_PROP_TMASK) == JS_PROP_GETSET) {
if (pr->u.getset.getter) if (pr->u.getset.getter)

View File

@@ -314,7 +314,7 @@ function run_tests(package_name, specific_test) {
if (is_text(ret)) { if (is_text(ret)) {
throw new Error(ret) throw new Error(ret)
} else if (ret && (is_text(ret.message) || ret instanceof Error)) { } else if (ret && (is_text(ret.message) || is_proto(ret, Error))) {
throw ret throw ret
} }

View File

@@ -54,8 +54,8 @@ function deepCompare(expected, actual, path) {
passed: false, passed: false,
messages: [`Array length mismatch at ${path}: expected ${expected.length}, got ${actual.length}`] messages: [`Array length mismatch at ${path}: expected ${expected.length}, got ${actual.length}`]
}; };
let messages = []; var messages = [];
for (let i = 0; i < expected.length; i++) { for (var i = 0; i < expected.length; i++) {
var result = deepCompare(expected[i], actual[i], `${path}[${i}]`); var result = deepCompare(expected[i], actual[i], `${path}[${i}]`);
if (!result.passed) { if (!result.passed) {
for(var m of result.messages) messages.push(m); for(var m of result.messages) messages.push(m);
@@ -72,8 +72,8 @@ function deepCompare(expected, actual, path) {
passed: false, passed: false,
messages: [`Object keys mismatch at ${path}: expected ${expKeys}, got ${actKeys}`] messages: [`Object keys mismatch at ${path}: expected ${expKeys}, got ${actKeys}`]
}; };
let messages = []; var messages = [];
for (let key of expKeys) { for (var key of expKeys) {
var result = deepCompare(expected[key], actual[key], `${path}.${key}`); var result = deepCompare(expected[key], actual[key], `${path}.${key}`);
if (!result.passed) { if (!result.passed) {
for(var m of result.messages) messages.push(m); for(var m of result.messages) messages.push(m);

View File

@@ -1,100 +0,0 @@
var num = use('num');
return {
test_num_basic: function() {
// Test matrix creation and operations
var A = new num.Matrix([
[1, 2, 3],
[4, 5, 6],
[7, 8, 10]
]);
log.console("Matrix A:");
log.console(A.toArray());
// Test matrix inversion
var A_inv = A.inverse();
log.console("\nMatrix A inverse:");
log.console(A_inv.toArray());
// Verify A * A_inv = I (approximately)
var I = A.multiply(A_inv);
log.console("\nA * A_inv (should be identity):");
log.console(I.toArray());
// Test array creation
var v = new num.Array([1, 2, 3]);
log.console("\nVector v:");
log.console(v.toArray());
// Test matrix-vector multiplication
var result = A.multiply(v);
log.console("\nA * v:");
log.console(result.toArray());
// Test dot product
var u = new num.Array([4, 5, 6]);
var dot_product = v.dot(u);
log.console("\nv · u =", dot_product);
// Test norm
var v_norm = v.norm();
log.console("||v|| =", v_norm);
// Test matrix-matrix multiplication
var B = new num.Matrix([
[1, 0, 0],
[0, 2, 0],
[0, 0, 3]
]);
var C = A.multiply(B);
log.console("\nA * B:");
log.console(C.toArray());
},
test_num_property: function() {
// Create an array
var arr = new num.Array([10, 20, 30, 40, 50]);
if (arr[0] != 10) throw "arr[0] mismatch"
if (arr[1] != 20) throw "arr[1] mismatch"
if (arr[4] != 50) throw "arr[4] mismatch"
arr[0] = 15
if (arr[0] != 15) throw "arr[0] set failed"
// arr[10] should be null or undefined, check behavior
// log.console("arr[10] =", arr[10]);
if (arr.length != 5) throw "arr.length mismatch"
if (!(arr instanceof num.Array)) throw "instanceof check failed"
},
test_num_setter: function() {
// Create an array
var arr = new num.Array([1, 2, 3, 4, 5]);
// Test setting values
arr[0] = 100;
arr[1] = 200;
arr[2] = 300.5;
if (arr[0] != 100) throw "Setter failed index 0"
if (arr[1] != 200) throw "Setter failed index 1"
if (arr[2] != 300.5) throw "Setter failed index 2"
// Test setting with different types
arr[3] = "123.7"; // Should convert string to number
arr[4] = true; // Should convert boolean to number
// Loose comparison for converted values if needed, or check specific behavior
// Assuming implementation converts:
// log.console("arr[3] =", arr[3]);
// log.console("arr[4] =", arr[4]);
// Test bounds checking - this should fail silently or throw depending on impl
arr[10] = 999;
}
}

View File

@@ -1052,6 +1052,15 @@ return {
if (is_null(object)) throw "null not object" if (is_null(object)) throw "null not object"
}, },
test_is_proto: function() {
var a = {}
var b = meme(a)
if (!is_proto(b, a)) throw "is_proto failed on meme"
var c = new Error()
if (!is_proto(c, Error)) throw "is_proto failed new"
},
// ============================================================================ // ============================================================================
// GLOBAL FUNCTIONS - LENGTH // GLOBAL FUNCTIONS - LENGTH
// ============================================================================ // ============================================================================

View File

@@ -19,7 +19,7 @@ function deep_compare(expected, actual, path) {
return { passed: false, messages: [`Value mismatch at ${path}: ${expected} vs ${actual} (diff ${diff})`] } return { passed: false, messages: [`Value mismatch at ${path}: ${expected} vs ${actual} (diff ${diff})`] }
} }
if ((expected instanceof blob) && (actual instanceof blob)) { if (is_blob(expected) && is_blob(actual)) {
stone_if_needed(expected); stone_if_needed(actual) stone_if_needed(expected); stone_if_needed(actual)
if (expected.length != actual.length) if (expected.length != actual.length)
return { passed: false, messages: [`blob length mismatch at ${path}: ${expected.length} vs ${actual.length}`] } return { passed: false, messages: [`blob length mismatch at ${path}: ${expected.length} vs ${actual.length}`] }
@@ -110,7 +110,7 @@ var testCases = [
function make_test(t) { function make_test(t) {
return function() { return function() {
var enc = wota.encode(t.input) var enc = wota.encode(t.input)
if (!(enc instanceof blob)) throw 'encode() should return a blob' if (!is_blob(enc)) throw 'encode() should return a blob'
var dec = wota.decode(enc) var dec = wota.decode(enc)