remove typeof'

This commit is contained in:
2026-01-06 11:08:27 -06:00
parent df07069c38
commit 63cf76dcf9
17 changed files with 139 additions and 205 deletions

View File

@@ -203,7 +203,7 @@ function calibrate_batch_size(bench_fn, is_batch) {
// Find a batch size that takes at least MIN_SAMPLE_NS
while (n < MAX_BATCH_SIZE) {
// Ensure n is a valid number before calling
if (typeof n != 'number' || n < 1) {
if (!is_number(n) || n < 1) {
n = 1
break
}
@@ -217,7 +217,7 @@ function calibrate_batch_size(bench_fn, is_batch) {
// Double the batch size
var new_n = n * 2
// Check if multiplication produced a valid number
if (typeof new_n != 'number' || new_n > MAX_BATCH_SIZE) {
if (!is_number(new_n) || new_n > MAX_BATCH_SIZE) {
n = MAX_BATCH_SIZE
break
}
@@ -225,12 +225,12 @@ function calibrate_batch_size(bench_fn, is_batch) {
}
// Adjust to target sample duration
if (dt > 0 && dt < TARGET_SAMPLE_NS && typeof n == 'number' && typeof dt == 'number') {
if (dt > 0 && dt < TARGET_SAMPLE_NS && is_number(n) && is_number(dt)) {
var calc = n * TARGET_SAMPLE_NS / dt
if (typeof calc == 'number' && calc > 0) {
if (is_number(calc) && calc > 0) {
var target_n = number.floor(calc)
// Check if floor returned a valid number
if (typeof target_n == 'number' && target_n > 0) {
if (is_number(target_n) && target_n > 0) {
if (target_n > MAX_BATCH_SIZE) target_n = MAX_BATCH_SIZE
if (target_n < MIN_BATCH_SIZE) target_n = MIN_BATCH_SIZE
n = target_n
@@ -239,7 +239,7 @@ function calibrate_batch_size(bench_fn, is_batch) {
}
// Safety check - ensure we always return a valid batch size
if (typeof n != 'number' || n < 1) {
if (!is_number(n) || n < 1) {
n = 1
}
@@ -254,7 +254,7 @@ function run_single_bench(bench_fn, bench_name) {
// 1. Object with { setup, run, teardown } - structured format
// 2. Function that accepts (n) - batch format
// 3. Function that accepts () - legacy format
var is_structured = typeof bench_fn == 'object' && bench_fn.run
var is_structured = is_object(bench_fn) && bench_fn.run
var is_batch = false
var batch_size = 1
var setup_fn = null
@@ -285,7 +285,7 @@ function run_single_bench(bench_fn, bench_name) {
batch_size = calibrate_batch_size(calibrate_fn, is_batch)
// Safety check for structured benchmarks
if (typeof batch_size != 'number' || batch_size < 1) {
if (!is_number(batch_size) || batch_size < 1) {
batch_size = 1
}
} else {
@@ -307,8 +307,9 @@ function run_single_bench(bench_fn, bench_name) {
// Warmup phase
for (var i = 0; i < WARMUP_BATCHES; i++) {
// Ensure batch_size is valid before warmup
if (typeof batch_size != 'number' || batch_size < 1) {
log.console(`WARNING: batch_size became ${typeof batch_size} = ${batch_size}, resetting to 1`)
if (!is_number(batch_size) || batch_size < 1) {
var type_str = is_null(batch_size) ? 'null' : is_number(batch_size) ? 'number' : is_text(batch_size) ? 'text' : is_object(batch_size) ? 'object' : is_array(batch_size) ? 'array' : is_function(batch_size) ? 'function' : is_logical(batch_size) ? 'logical' : 'unknown'
log.console(`WARNING: batch_size became ${type_str} = ${batch_size}, resetting to 1`)
batch_size = 1
}
@@ -332,7 +333,7 @@ function run_single_bench(bench_fn, bench_name) {
// Measurement phase - collect SAMPLES timing samples
for (var i = 0; i < SAMPLES; i++) {
// Double-check batch_size is valid (should never happen, but defensive)
if (typeof batch_size != 'number' || batch_size < 1) {
if (!is_number(batch_size) || batch_size < 1) {
batch_size = 1
}
@@ -439,11 +440,11 @@ function run_benchmarks(package_name, specific_bench) {
bench_mod = shop.use(mod_path, use_pkg)
var benches = []
if (typeof bench_mod == 'function') {
if (is_function(bench_mod)) {
benches.push({name: 'main', fn: bench_mod})
} else if (typeof bench_mod == 'object') {
} else if (is_object(bench_mod)) {
for (var k in bench_mod) {
if (typeof bench_mod[k] == 'function') {
if (is_function(bench_mod[k])) {
benches.push({name: k, fn: bench_mod[k]})
}
}

View File

@@ -174,7 +174,7 @@ function mount(source, name) {
mount_info.zip_blob = blob // keep blob alive
} else {
var zip = miniz.read(blob)
if (!zip || typeof zip.count != 'function') {
if (!is_object(zip) || !is_function(zip.count)) {
throw new Error("Invalid archive file (not zip or qop): " + source)
}

View File

@@ -38,7 +38,7 @@ function parse_key(key) {
function get_nested(obj, path) {
var current = obj
for (var segment of path) {
if (!current || typeof current != 'object') return null
if (is_null(current) || !is_object(current)) return null
current = current[segment]
}
return current
@@ -49,7 +49,7 @@ function set_nested(obj, path, value) {
var current = obj
for (var i = 0; i < path.length - 1; i++) {
var segment = path[i]
if (!current[segment] || typeof current[segment] != 'object') {
if (is_null(current[segment]) || !is_object(current[segment])) {
current[segment] = {}
}
current = current[segment]
@@ -74,8 +74,8 @@ function parse_value(str) {
// Format value for display
function format_value(val) {
if (typeof val == 'string') return '"' + val + '"'
if (typeof val == 'number' && val >= 1000) {
if (is_text(val)) return '"' + val + '"'
if (is_number(val) && val >= 1000) {
// Add underscores to large numbers
return val.toString().replace(/\B(?=(\d{3})+(?!\d))/g, '_')
}

View File

@@ -96,7 +96,7 @@ globalThis.isa = function(value, master) {
if (master == null) return false
// isa(value, function) - check if function.prototype is in chain
if (typeof master == 'function') {
if (is_function(master)) {
// Special type checks
if (master == stone) return is_stone(value)
if (master == number) return is_number(value)
@@ -119,7 +119,7 @@ globalThis.isa = function(value, master) {
}
// isa(object, master_object) - check prototype chain
if (typeof master == 'object') {
if (is_object(master)) {
var proto = _getPrototypeOf(value)
while (proto != null) {
if (proto == master) return true
@@ -543,7 +543,7 @@ function actor_send(actor, message) {
if (!isa(actor, actor) && !isa(actor.replycc, actor)) throw new Error(`Must send to an actor object. Attempted send to ${actor}`)
if (typeof message != 'object') throw new Error('Must send an object record.')
if (!is_object(message)) throw new Error('Must send an object record.')
// message to self
if (actor[ACTORDATA].id == _cell.id) {
@@ -611,10 +611,10 @@ var need_stop = false
var replies = {}
globalThis.send = function send(actor, message, reply) {
if (typeof actor != 'object')
if (!is_object(actor))
throw new Error(`Must send to an actor object. Provided: ${actor}`);
if (typeof message != 'object')
if (!is_object(message))
throw new Error('Message must be an object')
var send = {type:"user", data: message}

View File

@@ -25,7 +25,7 @@ function make_reason (factory, excuse, evidence) {
}
function is_requestor (fn) {
return typeof fn == 'function' && (fn.length == 1 || fn.length == 2)
return is_function(fn) && (fn.length == 1 || fn.length == 2)
}
function check_requestors (list, factory) {
@@ -34,13 +34,13 @@ function check_requestors (list, factory) {
}
function check_callback (cb, factory) {
if (typeof cb != 'function' || cb.length != 2)
if (!is_function(cb) || cb.length != 2)
throw make_reason(factory, 'Not a callback.', cb)
}
function schedule (fn, seconds) {
if (seconds == null || seconds <= 0) return fn()
if (typeof delay == 'function') return delay(fn, seconds)
if (is_function(delay)) return delay(fn, seconds)
throw make_reason('schedule', '@.delay capability required for timeouts.')
}
@@ -54,7 +54,7 @@ function run (factory, requestors, initial, action, time_limit, throttle = 0) {
function cancel (reason = make_reason(factory, 'Cancel.')) {
if (timer_cancel) timer_cancel(), timer_cancel = null
if (!cancel_list) return
cancel_list.forEach(c => { try { if (typeof c == 'function') c(reason) } catch (_) {} })
cancel_list.forEach(c => { try { if (is_function(c)) c(reason) } catch (_) {} })
cancel_list = null
}
@@ -81,7 +81,7 @@ function run (factory, requestors, initial, action, time_limit, throttle = 0) {
}
if (time_limit != null) {
if (typeof time_limit != 'number' || time_limit < 0)
if (!is_number(time_limit) || time_limit < 0)
throw make_reason(factory, 'Bad time limit.', time_limit)
if (time_limit > 0) timer_cancel = schedule(() => cancel(make_reason(factory, 'Timeout.', time_limit)), time_limit)
}
@@ -96,7 +96,7 @@ function run (factory, requestors, initial, action, time_limit, throttle = 0) {
function _normalize (collection, factory) {
if (isa(collection)) return { names: null, list: collection }
if (collection && typeof collection == 'object') {
if (collection && is_object(collection)) {
def names = array(collection)
def list = names.map(k => collection[k]).filter(is_requestor)
return { names, list }

View File

@@ -10,7 +10,7 @@ function make_reason(factory, excuse, evidence) {
}
function is_requestor(fn) {
return typeof fn == 'function' && (fn.length == 1 || fn.length == 2)
return is_function(fn) && (fn.length == 1 || fn.length == 2)
}
function check_requestors(list, factory) {
@@ -19,7 +19,7 @@ function check_requestors(list, factory) {
}
function check_callback(cb, factory) {
if (typeof cb != 'function' || cb.length != 2)
if (!is_function(cb) || cb.length != 2)
throw make_reason(factory, 'Not a callback.', cb)
}
@@ -88,10 +88,10 @@ function parallel(requestor_array, throttle, need) {
return function(callback, value) { callback([]) }
if (need == null) need = length
if (typeof need != 'number' || need < 0 || need > length)
if (!is_number(need) || need < 0 || need > length)
throw make_reason(factory, 'Bad need.', need)
if (throttle != null && (typeof throttle != 'number' || throttle < 1))
if (throttle != null && (!is_number(throttle) || throttle < 1))
throw make_reason(factory, 'Bad throttle.', throttle)
return function parallel_requestor(callback, value) {
@@ -107,7 +107,7 @@ function parallel(requestor_array, throttle, need) {
if (finished) return
finished = true
cancel_list.forEach(c => {
try { if (typeof c == 'function') c(reason) } catch (_) {}
try { if (is_function(c)) c(reason) } catch (_) {}
})
}
@@ -170,10 +170,10 @@ function race(requestor_array, throttle, need) {
def length = requestor_array.length
if (need == null) need = 1
if (typeof need != 'number' || need < 1 || need > length)
if (!is_number(need) || need < 1 || need > length)
throw make_reason(factory, 'Bad need.', need)
if (throttle != null && (typeof throttle != 'number' || throttle < 1))
if (throttle != null && (!is_number(throttle) || throttle < 1))
throw make_reason(factory, 'Bad throttle.', throttle)
return function race_requestor(callback, value) {
@@ -189,7 +189,7 @@ function race(requestor_array, throttle, need) {
if (finished) return
finished = true
cancel_list.forEach(c => {
try { if (typeof c == 'function') c(reason) } catch (_) {}
try { if (is_function(c)) c(reason) } catch (_) {}
})
}
@@ -304,7 +304,7 @@ function sequence(requestor_array) {
// Converts a unary function into a requestor.
function requestorize(unary) {
def factory = 'requestorize'
if (typeof unary != 'function')
if (!is_function(unary))
throw make_reason(factory, 'Not a function.', unary)
return function requestorized(callback, value) {
@@ -322,7 +322,7 @@ function requestorize(unary) {
// Converts a factory that takes arrays to one that takes objects.
function objectify(factory_fn) {
def factory = 'objectify'
if (typeof factory_fn != 'function')
if (!is_function(factory_fn))
throw make_reason(factory, 'Not a factory.', factory_fn)
return function objectified_factory(object_of_requestors, ...rest) {

View File

@@ -111,7 +111,7 @@ function pack(sources, archive_path, read_dir) {
log.console("Created " + archive_path)
}
if (typeof arg == 'undefined' || arg.length < 1) {
if (!is_array(arg) || arg.length < 1) {
print_usage()
} else {
if (arg[0] == "-l") {

View File

@@ -38,7 +38,6 @@ DEF(def, "def")
DEF(this, "this")
DEF(delete, "delete")
DEF(void, "void")
DEF(typeof, "typeof")
DEF(new, "new")
DEF(in, "in")
DEF(instanceof, "instanceof")

View File

@@ -202,7 +202,6 @@ DEF( inc_loc, 2, 0, 0, loc8)
DEF( add_loc, 2, 1, 0, loc8)
DEF( not, 1, 1, 1, none)
DEF( lnot, 1, 1, 1, none)
DEF( typeof, 1, 1, 1, none)
DEF( delete, 1, 2, 1, none)
DEF( delete_var, 5, 0, 1, atom)
@@ -328,7 +327,6 @@ DEF( call2, 1, 1, 1, npopx)
DEF( call3, 1, 1, 1, npopx)
DEF( is_null, 1, 1, 1, none)
DEF( typeof_is_function, 1, 1, 1, none)
#endif
#undef DEF

View File

@@ -11696,48 +11696,6 @@ static __exception int js_operator_instanceof(JSContext *ctx, JSValue *sp)
return 0;
}
static __exception int js_operator_typeof(JSContext *ctx, JSValueConst op1)
{
JSAtom atom;
uint32_t tag;
tag = JS_VALUE_GET_NORM_TAG(op1);
switch(tag) {
case JS_TAG_INT:
case JS_TAG_FLOAT64:
atom = JS_ATOM_number;
break;
case JS_TAG_BOOL:
atom = JS_ATOM_boolean;
break;
case JS_TAG_STRING:
case JS_TAG_STRING_ROPE:
atom = JS_ATOM_string;
break;
case JS_TAG_OBJECT:
{
if (JS_IsFunction(ctx, op1))
atom = JS_ATOM_function;
else
goto obj_type;
}
break;
case JS_TAG_NULL:
atom = JS_ATOM_null;
break;
obj_type:
atom = JS_ATOM_object;
break;
case JS_TAG_SYMBOL:
atom = JS_ATOM_symbol;
break;
default:
atom = JS_ATOM_unknown;
break;
}
return atom;
}
static __exception int js_operator_delete(JSContext *ctx, JSValue *sp)
{
JSValue op1, op2;
@@ -15553,17 +15511,6 @@ static JSValue JS_CallInternal_OLD(JSContext *caller_ctx, JSValueConst func_obj,
goto exception;
sp--;
BREAK;
CASE(OP_typeof):
{
JSValue op1;
JSAtom atom;
op1 = sp[-1];
atom = js_operator_typeof(ctx, op1);
JS_FreeValue(ctx, op1);
sp[-1] = JS_AtomToString(ctx, atom);
}
BREAK;
CASE(OP_delete):
sf->cur_pc = pc;
if (js_operator_delete(ctx, sp))
@@ -15622,16 +15569,6 @@ static JSValue JS_CallInternal_OLD(JSContext *caller_ctx, JSValueConst func_obj,
} else {
goto free_and_set_false;
}
#if SHORT_OPCODES
CASE(OP_typeof_is_function):
if (js_operator_typeof(ctx, sp[-1]) == JS_ATOM_function) {
goto free_and_set_true;
} else {
goto free_and_set_false;
}
free_and_set_true:
JS_FreeValue(ctx, sp[-1]);
#endif
set_true:
sp[-1] = JS_TRUE;
BREAK;
@@ -15915,7 +15852,6 @@ enum {
TOK_THIS,
TOK_DELETE,
TOK_VOID,
TOK_TYPEOF,
TOK_NEW,
TOK_IN,
TOK_INSTANCEOF,
@@ -20459,23 +20395,6 @@ static __exception int js_parse_unary(JSParseState *s, int parse_flags)
FALSE);
}
break;
case TOK_TYPEOF:
{
JSFunctionDef *fd;
if (next_token(s))
return -1;
if (js_parse_unary(s, PF_POW_FORBIDDEN))
return -1;
/* reference access should not return an exception, so we
patch the get_var */
fd = s->cur_func;
if (get_prev_opcode(fd) == OP_scope_get_var) {
fd->byte_code.buf[fd->last_opcode_pos] = OP_scope_get_var_undef;
}
emit_op(s, OP_typeof);
parse_flags = 0;
}
break;
case TOK_DELETE:
if (js_parse_delete(s))
return -1;
@@ -25130,48 +25049,6 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s)
}
goto no_change;
#if SHORT_OPCODES
case OP_typeof:
if (OPTIMIZE) {
/* simplify typeof tests */
if (code_match(&cc, pos_next, OP_push_atom_value, M4(OP_strict_eq, OP_strict_neq, OP_eq, OP_neq), -1)) {
if (cc.line_num >= 0) line_num = cc.line_num;
int op1 = (cc.op == OP_strict_eq || cc.op == OP_eq) ? OP_strict_eq : OP_strict_neq;
int op2 = -1;
switch (cc.atom) {
case JS_ATOM_null:
op2 = OP_is_null;
break;
case JS_ATOM_function:
op2 = OP_typeof_is_function;
break;
}
if (op2 >= 0) {
/* transform typeof(s) == "<type>" into is_<type> */
if (op1 == OP_strict_eq) {
add_pc2line_info(s, bc_out.size, line_num);
dbuf_putc(&bc_out, op2);
JS_FreeAtom(ctx, cc.atom);
pos_next = cc.pos;
break;
}
if (op1 == OP_strict_neq && code_match(&cc, cc.pos, OP_if_false, -1)) {
/* transform typeof(s) != "<type>" if_false into is_<type> if_true */
if (cc.line_num >= 0) line_num = cc.line_num;
add_pc2line_info(s, bc_out.size, line_num);
dbuf_putc(&bc_out, op2);
JS_FreeAtom(ctx, cc.atom);
pos_next = cc.pos;
label = cc.label;
op = OP_if_true;
goto has_label;
}
}
}
}
goto no_change;
#endif
default:
no_change:
add_pc2line_info(s, bc_out.size, line_num);
@@ -25873,7 +25750,6 @@ static __exception int js_parse_directives(JSParseState *s)
case TOK_VAR:
case TOK_THIS:
case TOK_DELETE:
case TOK_TYPEOF:
case TOK_NEW:
case TOK_DO:
case TOK_WHILE:

12
test.ce
View File

@@ -287,11 +287,11 @@ function run_tests(package_name, specific_test) {
test_mod = shop.use(mod_path, use_pkg)
var tests = []
if (typeof test_mod == 'function') {
if (is_function(test_mod)) {
tests.push({name: 'main', fn: test_mod})
} else if (typeof test_mod == 'object') {
} else if (is_object(test_mod)) {
for (var k in test_mod) {
if (typeof test_mod[k] == 'function') {
if (is_function(test_mod[k])) {
tests.push({name: k, fn: test_mod[k]})
}
}
@@ -312,9 +312,9 @@ function run_tests(package_name, specific_test) {
try {
var ret = t.fn()
if (typeof ret == 'string') {
if (is_text(ret)) {
throw new Error(ret)
} else if (ret && (typeof ret.message == 'string' || ret instanceof Error)) {
} else if (ret && (is_text(ret.message) || ret instanceof Error)) {
throw ret
}
@@ -330,7 +330,7 @@ function run_tests(package_name, specific_test) {
}
if (e.name) test_entry.error.name = e.name
if (typeof e == 'object' && e.message) {
if (is_object(e) && e.message) {
test_entry.error.message = e.message
}

View File

@@ -20,7 +20,7 @@ function deepCompare(expected, actual, path) {
path = path || ''
if (expected == actual) return { passed: true, messages: [] };
if (typeof expected == 'number' && typeof actual == 'number') {
if (is_number(expected) && is_number(actual)) {
if (isNaN(expected) && isNaN(actual))
return { passed: true, messages: [] };
@@ -160,13 +160,13 @@ var testCases = [
{ name: 'empty_key_value', input: { "": "" } },
{ name: 'small_float', input: 1e-10 },
{ name: 'replacer_multiply', input: { a: 1, b: 2 },
replacer: (key, value) => typeof value == 'number' ? value * 2 : value,
replacer: (key, value) => is_number(value) ? value * 2 : value,
expected: { a: 2, b: 4 } },
{ name: 'replacer_string_append', input: { x: "test", y: 5 },
replacer: (key, value) => key == 'x' ? value + "!" : value,
expected: { x: "test!", y: 5 } },
{ name: 'reviver_multiply', input: { a: 1, b: 2 },
reviver: (key, value) => typeof value == 'number' ? value * 3 : value,
reviver: (key, value) => is_number(value) ? value * 3 : value,
expected: { a: 3, b: 6 } },
{ name: 'reviver_increment', input: { x: "test", y: 10 },
reviver: (key, value) => key == 'y' ? value + 1 : value,

View File

@@ -924,32 +924,93 @@ return {
},
// ============================================================================
// TYPEOF AND TYPE CHECKING
// TYPE CHECKING WITH is_* FUNCTIONS
// ============================================================================
test_typeof_number: function() {
if (typeof 42 != "number") throw "typeof number failed"
if (typeof 3.14 != "number") throw "typeof float failed"
if (typeof -5 != "number") throw "typeof negative failed"
test_is_number: function() {
if (!is_number(42)) throw "is_number 42 failed"
if (!is_number(3.14)) throw "is_number float failed"
if (!is_number(-5)) throw "is_number negative failed"
if (is_number("42")) throw "is_number string should be false"
if (is_number(true)) throw "is_number boolean should be false"
if (is_number(null)) throw "is_number null should be false"
if (is_number({})) throw "is_number object should be false"
if (is_number([])) throw "is_number array should be false"
},
test_typeof_string: function() {
if (typeof "hello" != "string") throw "typeof string failed"
if (typeof "" != "string") throw "typeof empty string failed"
test_is_text: function() {
if (!is_text("hello")) throw "is_text string failed"
if (!is_text("")) throw "is_text empty string failed"
if (is_text(42)) throw "is_text number should be false"
if (is_text(true)) throw "is_text boolean should be false"
if (is_text(null)) throw "is_text null should be false"
if (is_text({})) throw "is_text object should be false"
if (is_text([])) throw "is_text array should be false"
},
test_typeof_boolean: function() {
if (typeof true != "boolean") throw "typeof true failed"
if (typeof false != "boolean") throw "typeof false failed"
test_is_logical: function() {
if (!is_logical(true)) throw "is_logical true failed"
if (!is_logical(false)) throw "is_logical false failed"
if (is_logical(1)) throw "is_logical number should be false"
if (is_logical("true")) throw "is_logical string should be false"
if (is_logical(null)) throw "is_logical null should be false"
if (is_logical({})) throw "is_logical object should be false"
if (is_logical([])) throw "is_logical array should be false"
},
test_typeof_object: function() {
if (typeof {} != "object") throw "typeof object failed"
if (typeof [] != "object") throw "typeof array failed"
test_is_object: function() {
if (!is_object({})) throw "is_object empty object failed"
if (!is_object({a: 1})) throw "is_object object failed"
if (is_object([])) throw "is_object array should be false"
if (is_object(null)) throw "is_object null should be false"
if (is_object(42)) throw "is_object number should be false"
if (is_object("hello")) throw "is_object string should be false"
if (is_object(true)) throw "is_object boolean should be false"
},
test_typeof_function: function() {
if (typeof function(){} != "function") throw "typeof function failed"
test_is_array: function() {
if (!is_array([])) throw "is_array empty array failed"
if (!is_array([1, 2, 3])) throw "is_array array failed"
if (is_array({})) throw "is_array object should be false"
if (is_array(null)) throw "is_array null should be false"
if (is_array(42)) throw "is_array number should be false"
if (is_array("hello")) throw "is_array string should be false"
if (is_array(true)) throw "is_array boolean should be false"
},
test_is_function: function() {
if (!is_function(function(){})) throw "is_function function failed"
var fn = function(x) { return x * 2 }
if (!is_function(fn)) throw "is_function named function failed"
if (is_function({})) throw "is_function object should be false"
if (is_function([])) throw "is_function array should be false"
if (is_function(null)) throw "is_function null should be false"
if (is_function(42)) throw "is_function number should be false"
if (is_function("hello")) throw "is_function string should be false"
if (is_function(true)) throw "is_function boolean should be false"
},
test_is_null: function() {
if (!is_null(null)) throw "is_null null failed"
if (is_null(0)) throw "is_null zero should be false"
if (is_null(false)) throw "is_null false should be false"
if (is_null("")) throw "is_null empty string should be false"
if (is_null({})) throw "is_null object should be false"
if (is_null([])) throw "is_null array should be false"
var x
if (!is_null(x)) throw "is_null undefined variable should be true"
},
test_is_blob: function() {
// Note: blob testing would require actual blob values
// For now, just test that other types return false
if (is_blob(null)) throw "is_blob null should be false"
if (is_blob(42)) throw "is_blob number should be false"
if (is_blob("hello")) throw "is_blob string should be false"
if (is_blob(true)) throw "is_blob boolean should be false"
if (is_blob({})) throw "is_blob object should be false"
if (is_blob([])) throw "is_blob array should be false"
if (is_blob(function(){})) throw "is_blob function should be false"
},
// ============================================================================

View File

@@ -2,10 +2,10 @@ var toml = use('toml')
function deep_equal(a, b) {
if (a == b) return true
if (a == null || b == null) return false
if (typeof a != typeof b) return false
if (is_null(a) || is_null(b)) return false
if ((is_number(a) && !is_number(b)) || (is_text(a) && !is_text(b)) || (is_object(a) && !is_object(b)) || (is_array(a) && !is_array(b)) || (is_blob(a) && !is_blob(b)) || (is_function(a) && !is_function(b)) || (is_logical(a) && !is_logical(b))) return false
if (typeof a == 'object') {
if (is_object(a)) {
var keys_a = array(a)
var keys_b = array(b)
if (keys_a.length != keys_b.length) return false

View File

@@ -12,7 +12,7 @@ function deep_compare(expected, actual, path) {
path = path || ''
if (expected == actual) return { passed: true, messages: [] }
if (typeof expected == 'number' && typeof actual == 'number') {
if (is_number(expected) && is_number(actual)) {
if (isNaN(expected) && isNaN(actual)) return { passed: true, messages: [] }
var diff = number.abs(expected - actual)
if (diff <= EPSILON) return { passed: true, messages: [] }

View File

@@ -60,7 +60,7 @@ function time_record(num = now(),
zone = computer_zone(),
dst = computer_dst())
{
if (typeof num == "object") return num;
if (is_object(num)) return num;
var monthdays = time.monthdays.slice();
var rec = {
@@ -111,9 +111,8 @@ function time_record(num = now(),
function time_number(rec = now())
{
if (typeof rec == "number") return rec;
if (is_number(rec)) return rec;
log.console(typeof rec)
log.console(rec)
log.console(rec.minute)
@@ -157,7 +156,7 @@ function time_text(num = now(),
zone = computer_zone(),
dst = computer_dst())
{
var rec = (typeof num == "number") ? time_record(num, zone, dst) : num;
var rec = is_number(num) ? time_record(num, zone, dst) : num;
zone = rec.zone;
dst = rec.dst;

View File

@@ -2,7 +2,7 @@
// Supports basic TOML features needed for the module system
function parse_toml(text) {
if (typeof text != 'string') return null
if (!is_text(text)) return null
var lines = text.split('\n')
var result = {}
var current_section = result
@@ -141,11 +141,11 @@ function encode_toml(obj) {
var result = []
function encode_value(value) {
if (typeof value == 'string') {
if (is_text(value)) {
return '"' + value.replace(/"/g, '\\"') + '"'
} else if (typeof value == 'boolean') {
} else if (is_logical(value)) {
return value ? 'true' : 'false'
} else if (typeof value == 'number') {
} else if (is_number(value)) {
return text(value)
} else if (isa(value, array)) {
var items = []