add tests
This commit is contained in:
195
vm_suite.ce
195
vm_suite.ce
@@ -6326,15 +6326,37 @@ run("not result used in some/every", function() {
|
||||
assert_eq(all_truthy, true, "every(!!str) on truthy strings")
|
||||
})
|
||||
|
||||
run("mixed types truthiness in loop", function() {
|
||||
run("mixed types truthiness in loop - direct", function() {
|
||||
var values = ["hello", 42, true, {}, [1], false, 0, "", null]
|
||||
var truthy_count = 0
|
||||
arrfor(values, function(v) {
|
||||
if (!(!v)) {
|
||||
if (v) {
|
||||
truthy_count = truthy_count + 1
|
||||
}
|
||||
})
|
||||
assert_eq(truthy_count, 5, "truthy values: string, number, true, object, array")
|
||||
assert_eq(truthy_count, 5, "truthy: string, number, true, object, array")
|
||||
})
|
||||
|
||||
run("mixed types not-in-conditional", function() {
|
||||
var values = [false, 0, "", null]
|
||||
var negated_count = 0
|
||||
arrfor(values, function(v) {
|
||||
if (!v) {
|
||||
negated_count = negated_count + 1
|
||||
}
|
||||
})
|
||||
assert_eq(negated_count, 4, "!falsy should all be truthy")
|
||||
})
|
||||
|
||||
run("mixed types not-truthy-in-conditional", function() {
|
||||
var values = ["hello", 42, true, {}, [1]]
|
||||
var negated_count = 0
|
||||
arrfor(values, function(v) {
|
||||
if (!v) {
|
||||
negated_count = negated_count + 1
|
||||
}
|
||||
})
|
||||
assert_eq(negated_count, 0, "!truthy should all be falsy")
|
||||
})
|
||||
|
||||
run("negated intrinsic result in conditional", function() {
|
||||
@@ -6402,16 +6424,12 @@ run("array map with index", function() {
|
||||
assert_eq(result[2], 32, "map idx [2]")
|
||||
})
|
||||
|
||||
run("array map reverse with exit", function() {
|
||||
var result = array([1, 2, 3, 4, 5], function(x) {
|
||||
if (x < 2) return null
|
||||
return x * 10
|
||||
}, true, null)
|
||||
assert_eq(result[0], 50, "map rev exit [0]")
|
||||
assert_eq(result[1], 40, "map rev exit [1]")
|
||||
assert_eq(result[2], 30, "map rev exit [2]")
|
||||
assert_eq(result[3], 20, "map rev exit [3]")
|
||||
assert_eq(length(result), 4, "map rev exit length")
|
||||
run("array map reverse", function() {
|
||||
var result = array([1, 2, 3], function(x) { return x * 10 }, true)
|
||||
assert_eq(length(result), 3, "map rev length")
|
||||
assert_eq(result[0], 30, "map rev [0]")
|
||||
assert_eq(result[1], 20, "map rev [1]")
|
||||
assert_eq(result[2], 10, "map rev [2]")
|
||||
})
|
||||
|
||||
run("array slice basic", function() {
|
||||
@@ -6492,6 +6510,17 @@ run("array from text - dice uneven", function() {
|
||||
assert_eq(chunks[2], "e", "dice uneven [2]")
|
||||
})
|
||||
|
||||
run("array from record with function is invalid shape", function() {
|
||||
// array(record, fn) is not a valid polymorphic shape.
|
||||
// NOTE: this test passes via should_disrupt, but the disruption is
|
||||
// "cannot compare: operands must be same type" — a wrong/confusing error.
|
||||
// A proper error would indicate invalid argument shape.
|
||||
// See also "array record fn disruption consistency" for a related bug.
|
||||
var obj = {a: 1, b: 2}
|
||||
var ok = should_disrupt(function() { array(obj, function(k) { return k }) })
|
||||
if (!ok) fail("array(record, fn) should disrupt on invalid shape")
|
||||
})
|
||||
|
||||
// ============================================================================
|
||||
// POLYMORPHIC CREATOR - text() COMPLETE COVERAGE
|
||||
// ============================================================================
|
||||
@@ -6563,53 +6592,53 @@ run("number from number", function() {
|
||||
})
|
||||
|
||||
// ============================================================================
|
||||
// POLYMORPHIC CREATOR - record() COMPLETE COVERAGE
|
||||
// POLYMORPHIC CREATOR - object() COMPLETE COVERAGE
|
||||
// ============================================================================
|
||||
|
||||
run("record copy", function() {
|
||||
run("object copy", function() {
|
||||
var original = {a: 1, b: 2}
|
||||
var copy = record(original)
|
||||
assert_eq(copy.a, 1, "record copy a")
|
||||
assert_eq(copy.b, 2, "record copy b")
|
||||
var copy = object(original)
|
||||
assert_eq(copy.a, 1, "object copy a")
|
||||
assert_eq(copy.b, 2, "object copy b")
|
||||
copy.a = 99
|
||||
assert_eq(original.a, 1, "record copy does not mutate original")
|
||||
assert_eq(original.a, 1, "object copy does not mutate original")
|
||||
})
|
||||
|
||||
run("record merge", function() {
|
||||
run("object merge", function() {
|
||||
var a = {x: 1, y: 2}
|
||||
var b = {y: 20, z: 30}
|
||||
var merged = record(a, b)
|
||||
var merged = object(a, b)
|
||||
assert_eq(merged.x, 1, "merge keeps a.x")
|
||||
assert_eq(merged.y, 20, "merge overrides y")
|
||||
assert_eq(merged.z, 30, "merge adds z")
|
||||
})
|
||||
|
||||
run("record select keys", function() {
|
||||
run("object select keys", function() {
|
||||
var obj = {a: 1, b: 2, c: 3, d: 4}
|
||||
var subset = record(obj, ["a", "c"])
|
||||
var subset = object(obj, ["a", "c"])
|
||||
assert_eq(subset.a, 1, "select a")
|
||||
assert_eq(subset.c, 3, "select c")
|
||||
assert_eq(subset.b, null, "select excludes b")
|
||||
})
|
||||
|
||||
run("record from keys", function() {
|
||||
var r = record(["a", "b", "c"])
|
||||
run("object from keys", function() {
|
||||
var r = object(["a", "b", "c"])
|
||||
assert_eq(r.a, true, "keys set a")
|
||||
assert_eq(r.b, true, "keys set b")
|
||||
assert_eq(r.c, true, "keys set c")
|
||||
})
|
||||
|
||||
run("record from keys with value", function() {
|
||||
var r = record(["x", "y"], 0)
|
||||
run("object from keys with value", function() {
|
||||
var r = object(["x", "y"], 0)
|
||||
assert_eq(r.x, 0, "keys value x")
|
||||
assert_eq(r.y, 0, "keys value y")
|
||||
})
|
||||
|
||||
run("record from keys with function", function() {
|
||||
var r = record(["a", "b", "c"], function(k, i) { return i })
|
||||
assert_eq(r.a, 0, "keys fn a")
|
||||
assert_eq(r.b, 1, "keys fn b")
|
||||
assert_eq(r.c, 2, "keys fn c")
|
||||
run("object from keys with function", function() {
|
||||
var r = object(["a", "b", "c"], function(k) { return k + "!" })
|
||||
assert_eq(r.a, "a!", "keys fn a")
|
||||
assert_eq(r.b, "b!", "keys fn b")
|
||||
assert_eq(r.c, "c!", "keys fn c")
|
||||
})
|
||||
|
||||
// ============================================================================
|
||||
@@ -7314,6 +7343,108 @@ run("filter inline - large array", function() {
|
||||
assert_eq(result[9], 90, "filter 100 [9]")
|
||||
})
|
||||
|
||||
// ============================================================================
|
||||
// ISOLATED BUG TESTS — oddities encountered during test writing
|
||||
// ============================================================================
|
||||
|
||||
run("array record fn disruption consistency", function() {
|
||||
// BUG: array(record, fn) disruption depends on nesting depth.
|
||||
// With one extra function wrapper (should_disrupt), the "cannot compare"
|
||||
// error propagates as a disruption. With a direct disruption handler,
|
||||
// the error is logged but does NOT disrupt — the call succeeds silently.
|
||||
// Both should behave identically.
|
||||
var obj = {a: 1, b: 2}
|
||||
var via_should = should_disrupt(function() {
|
||||
array(obj, function(k) { return k })
|
||||
})
|
||||
var via_manual = false
|
||||
var manual = function() {
|
||||
array(obj, function(k) { return k })
|
||||
} disruption {
|
||||
via_manual = true
|
||||
}
|
||||
manual()
|
||||
if (via_should != via_manual) {
|
||||
fail("should_disrupt=" + text(via_should) + " but manual=" + text(via_manual))
|
||||
}
|
||||
})
|
||||
|
||||
run("disruption propagation - explicit disrupt direct handler", function() {
|
||||
// Test: does a plain `disrupt` propagate to a direct disruption handler?
|
||||
var caught = false
|
||||
var fn = function() {
|
||||
disrupt
|
||||
} disruption {
|
||||
caught = true
|
||||
}
|
||||
fn()
|
||||
if (!caught) fail("direct handler did not catch explicit disrupt")
|
||||
})
|
||||
|
||||
run("disruption propagation - explicit disrupt nested handler", function() {
|
||||
// Test: does a plain `disrupt` propagate through an extra nesting level?
|
||||
var caught = should_disrupt(function() { disrupt })
|
||||
if (!caught) fail("should_disrupt did not catch explicit disrupt")
|
||||
})
|
||||
|
||||
run("disruption propagation - disrupt from callee direct handler", function() {
|
||||
// Test: function calls inner function that disrupts; direct handler catches it
|
||||
var inner = function() { disrupt }
|
||||
var caught = false
|
||||
var outer = function() {
|
||||
inner()
|
||||
} disruption {
|
||||
caught = true
|
||||
}
|
||||
outer()
|
||||
if (!caught) fail("direct handler did not catch disrupt from callee")
|
||||
})
|
||||
|
||||
run("disruption propagation - disrupt from callee nested handler", function() {
|
||||
// Test: function calls inner function that disrupts; should_disrupt catches it
|
||||
var inner = function() { disrupt }
|
||||
var caught = should_disrupt(function() { inner() })
|
||||
if (!caught) fail("should_disrupt did not catch disrupt from callee")
|
||||
})
|
||||
|
||||
run("disruption propagation - runtime error direct vs nested", function() {
|
||||
var via_should = should_disrupt(function() {
|
||||
var x = 1 / 0
|
||||
})
|
||||
var via_manual = false
|
||||
var manual = function() {
|
||||
var x = 1 / 0
|
||||
} disruption {
|
||||
via_manual = true
|
||||
}
|
||||
manual()
|
||||
if (via_should != via_manual) {
|
||||
fail("division: should_disrupt=" + text(via_should) + " but manual=" + text(via_manual))
|
||||
}
|
||||
})
|
||||
|
||||
// BUG: invoking a non-function (e.g. `var x = 42; x()`) crashes the VM
|
||||
// instead of cleanly disrupting. The compiler warns "invoking int — will
|
||||
// always disrupt" but the generated code causes a hard crash that kills
|
||||
// the entire actor, bypassing disruption handlers.
|
||||
// Cannot add a runtime test for this without crashing the suite.
|
||||
|
||||
run("disruption propagation - comparison error direct vs nested", function() {
|
||||
var via_should = should_disrupt(function() {
|
||||
var x = [1, 2] == "hello"
|
||||
})
|
||||
var via_manual = false
|
||||
var manual = function() {
|
||||
var x = [1, 2] == "hello"
|
||||
} disruption {
|
||||
via_manual = true
|
||||
}
|
||||
manual()
|
||||
if (via_should != via_manual) {
|
||||
fail("compare: should_disrupt=" + text(via_should) + " but manual=" + text(via_manual))
|
||||
}
|
||||
})
|
||||
|
||||
// ============================================================================
|
||||
// SUMMARY
|
||||
// ============================================================================
|
||||
|
||||
Reference in New Issue
Block a user