fix all core script syntax issues
This commit is contained in:
247
tests/blob.cm
247
tests/blob.cm
@@ -1,17 +1,12 @@
|
||||
// blob_test.cm
|
||||
var Blob = use('blob');
|
||||
var os = use('os');
|
||||
|
||||
function assert(condition, message) {
|
||||
if (!condition) {
|
||||
throw Error(message || "Assertion failed");
|
||||
}
|
||||
if (!condition) disrupt
|
||||
}
|
||||
|
||||
function assertEqual(actual, expected, message) {
|
||||
if (actual != expected) {
|
||||
throw Error(message || "Expected " + expected + ", got " + actual);
|
||||
}
|
||||
if (actual != expected) disrupt
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -19,12 +14,12 @@ return {
|
||||
var b = Blob();
|
||||
assertEqual(length(b), 0, "Empty blob should have length 0");
|
||||
},
|
||||
|
||||
|
||||
test_create_blob_with_capacity: function() {
|
||||
var b = Blob(100);
|
||||
assertEqual(length(b), 0, "New blob with capacity should still have length 0");
|
||||
},
|
||||
|
||||
|
||||
test_write_and_read_single_bit: function() {
|
||||
var b = Blob();
|
||||
b.write_bit(true);
|
||||
@@ -32,36 +27,39 @@ return {
|
||||
b.write_bit(1);
|
||||
b.write_bit(0);
|
||||
assertEqual(length(b), 4, "Should have 4 bits after writing");
|
||||
|
||||
|
||||
stone(b);
|
||||
assertEqual(b.read_logical(0), true, "First bit should be true");
|
||||
assertEqual(b.read_logical(1), false, "Second bit should be false");
|
||||
assertEqual(b.read_logical(2), true, "Third bit should be true (1)");
|
||||
assertEqual(b.read_logical(3), false, "Fourth bit should be false (0)");
|
||||
},
|
||||
|
||||
|
||||
test_out_of_range_read_throws_error: function() {
|
||||
var b = Blob();
|
||||
var threw = false;
|
||||
b.write_bit(true);
|
||||
stone(b);
|
||||
|
||||
var threw = false;
|
||||
try {
|
||||
b.read_logical(100);
|
||||
} catch (e) {
|
||||
threw = true;
|
||||
}
|
||||
assert(threw, "Out of range read should throw");
|
||||
|
||||
|
||||
threw = false;
|
||||
try {
|
||||
b.read_logical(-1);
|
||||
} catch (e) {
|
||||
var _try1 = function() {
|
||||
b.read_logical(100);
|
||||
} disruption {
|
||||
threw = true;
|
||||
}
|
||||
assert(threw, "Negative index read should throw");
|
||||
_try1();
|
||||
assert(threw, "Out of range read should disrupt");
|
||||
|
||||
threw = false;
|
||||
var _try2 = function() {
|
||||
b.read_logical(-1);
|
||||
} disruption {
|
||||
threw = true;
|
||||
}
|
||||
_try2();
|
||||
assert(threw, "Negative index read should disrupt");
|
||||
},
|
||||
|
||||
|
||||
test_write_and_read_numbers: function() {
|
||||
var b = Blob();
|
||||
b.write_number(3.14159);
|
||||
@@ -69,41 +67,41 @@ return {
|
||||
b.write_number(0);
|
||||
b.write_number(1e20);
|
||||
stone(b);
|
||||
|
||||
|
||||
assertEqual(b.read_number(0), 3.14159, "First number should match");
|
||||
assertEqual(b.read_number(64), -42, "Second number should match");
|
||||
assertEqual(b.read_number(128), 0, "Third number should match");
|
||||
assertEqual(b.read_number(192), 1e20, "Fourth number should match");
|
||||
},
|
||||
|
||||
|
||||
test_write_and_read_text: function() {
|
||||
var b = Blob();
|
||||
b.write_text("Hello");
|
||||
b.write_text("World");
|
||||
b.write_text("🎉");
|
||||
stone(b);
|
||||
|
||||
|
||||
assertEqual(b.read_text(0), "Hello", "First text should match");
|
||||
},
|
||||
|
||||
|
||||
test_write_and_read_blobs: function() {
|
||||
var b1 = Blob();
|
||||
b1.write_bit(true);
|
||||
b1.write_bit(false);
|
||||
b1.write_bit(true);
|
||||
|
||||
|
||||
var b2 = Blob(10);
|
||||
b2.write_blob(b1);
|
||||
b2.write_bit(false);
|
||||
assertEqual(length(b2), 4, "Combined blob should have 4 bits");
|
||||
|
||||
|
||||
stone(b2);
|
||||
assertEqual(b2.read_logical(0), true);
|
||||
assertEqual(b2.read_logical(1), false);
|
||||
assertEqual(b2.read_logical(2), true);
|
||||
assertEqual(b2.read_logical(3), false);
|
||||
},
|
||||
|
||||
|
||||
test_blob_copy_constructor: function() {
|
||||
var b1 = Blob();
|
||||
b1.write_bit(true);
|
||||
@@ -111,98 +109,103 @@ return {
|
||||
b1.write_bit(true);
|
||||
b1.write_bit(true);
|
||||
stone(b1);
|
||||
|
||||
|
||||
var b2 = Blob(b1);
|
||||
stone(b2);
|
||||
assertEqual(length(b2), 4, "Copied blob should have same length");
|
||||
assertEqual(b2.read_logical(0), true);
|
||||
assertEqual(b2.read_logical(3), true);
|
||||
},
|
||||
|
||||
|
||||
test_blob_partial_copy_constructor: function() {
|
||||
var b1 = Blob();
|
||||
for (var i = 0; i < 10; i++) {
|
||||
var i = 0;
|
||||
for (i = 0; i < 10; i++) {
|
||||
b1.write_bit(i % 2 == 0);
|
||||
}
|
||||
stone(b1);
|
||||
|
||||
|
||||
var b2 = Blob(b1, 2, 7);
|
||||
stone(b2);
|
||||
assertEqual(length(b2), 5, "Partial copy should have 5 bits");
|
||||
assertEqual(b2.read_logical(0), true);
|
||||
assertEqual(b2.read_logical(2), true);
|
||||
},
|
||||
|
||||
|
||||
test_create_blob_with_fill: function() {
|
||||
var b1 = Blob(8, true);
|
||||
var b2 = Blob(8, false);
|
||||
|
||||
var i = 0;
|
||||
|
||||
stone(b1);
|
||||
stone(b2);
|
||||
|
||||
for (var i = 0; i < 8; i++) {
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
assertEqual(b1.read_logical(i), true, "Bit " + i + " should be true");
|
||||
assertEqual(b2.read_logical(i), false, "Bit " + i + " should be false");
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
test_create_blob_with_random_function: function() {
|
||||
var sequence = [true, false, true, true, false];
|
||||
var index = 0;
|
||||
|
||||
var i = 0;
|
||||
|
||||
var b = Blob(5, function() {
|
||||
return sequence[index++] ? 1 : 0;
|
||||
});
|
||||
|
||||
|
||||
stone(b);
|
||||
for (var i = 0; i < 5; i++) {
|
||||
for (i = 0; i < 5; i++) {
|
||||
assertEqual(b.read_logical(i), sequence[i], "Bit " + i + " should match sequence");
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
test_write_pad_and_check_padding: function() {
|
||||
var b = Blob();
|
||||
b.write_bit(true);
|
||||
b.write_bit(false);
|
||||
b.write_bit(true);
|
||||
b.write_pad(8);
|
||||
|
||||
|
||||
assertEqual(length(b), 8, "Should be padded to 8 bits");
|
||||
stone(b);
|
||||
|
||||
|
||||
assert(b['pad?'](3, 8), "Should detect valid padding at position 3");
|
||||
assert(!b['pad?'](2, 8), "Should detect invalid padding at position 2");
|
||||
},
|
||||
|
||||
|
||||
test_read_blob_from_stone_blob: function() {
|
||||
var b1 = Blob();
|
||||
for (var i = 0; i < 16; i++) {
|
||||
var i = 0;
|
||||
for (i = 0; i < 16; i++) {
|
||||
b1.write_bit(i % 3 == 0);
|
||||
}
|
||||
stone(b1);
|
||||
|
||||
|
||||
var b2 = b1.read_blob(4, 12);
|
||||
stone(b2);
|
||||
assertEqual(length(b2), 8, "Read blob should have 8 bits");
|
||||
|
||||
|
||||
assertEqual(b2.read_logical(2), true);
|
||||
assertEqual(b2.read_logical(5), true);
|
||||
},
|
||||
|
||||
|
||||
test_stone_blob_is_immutable: function() {
|
||||
var b = Blob();
|
||||
var threw = false;
|
||||
b.write_bit(true);
|
||||
stone(b);
|
||||
|
||||
var threw = false;
|
||||
try {
|
||||
|
||||
var _try = function() {
|
||||
b.write_bit(false);
|
||||
} catch (e) {
|
||||
} disruption {
|
||||
threw = true;
|
||||
}
|
||||
assert(threw, "Writing to stone blob should throw error");
|
||||
_try();
|
||||
assert(threw, "Writing to stone blob should disrupt");
|
||||
},
|
||||
|
||||
|
||||
test_multiple_stone_calls_are_safe: function() {
|
||||
var b = Blob();
|
||||
b.write_bit(true);
|
||||
@@ -211,149 +214,161 @@ return {
|
||||
assert(stone.p(b), "Blob should be a stone after stone() call");
|
||||
stone(b);
|
||||
assertEqual(b.read_logical(0), true, "Blob data should remain intact");
|
||||
|
||||
|
||||
assert(b.stone == null, "blob.stone should not be available as a method");
|
||||
},
|
||||
|
||||
|
||||
test_invalid_constructor_arguments: function() {
|
||||
var threw = false;
|
||||
try {
|
||||
var _try = function() {
|
||||
var b = Blob("invalid");
|
||||
} catch (e) {
|
||||
} disruption {
|
||||
threw = true;
|
||||
}
|
||||
assert(threw, "Invalid constructor arguments should throw");
|
||||
_try();
|
||||
assert(threw, "Invalid constructor arguments should disrupt");
|
||||
},
|
||||
|
||||
|
||||
test_write_bit_validation: function() {
|
||||
var b = Blob();
|
||||
var threw = false;
|
||||
b.write_bit(0);
|
||||
b.write_bit(1);
|
||||
|
||||
var threw = false;
|
||||
try {
|
||||
|
||||
var _try = function() {
|
||||
b.write_bit(2);
|
||||
} catch (e) {
|
||||
} disruption {
|
||||
threw = true;
|
||||
}
|
||||
assert(threw, "write_bit with value 2 should throw");
|
||||
_try();
|
||||
assert(threw, "write_bit with value 2 should disrupt");
|
||||
},
|
||||
|
||||
|
||||
test_complex_data_round_trip: function() {
|
||||
var b = Blob();
|
||||
|
||||
|
||||
b.write_text("Test");
|
||||
b.write_number(123.456);
|
||||
b.write_bit(true);
|
||||
b.write_bit(false);
|
||||
b.write_number(-999.999);
|
||||
|
||||
|
||||
var originalLength = length(b);
|
||||
stone(b);
|
||||
|
||||
|
||||
var b2 = Blob(b);
|
||||
stone(b2);
|
||||
assertEqual(length(b2), originalLength, "Copy should have same length");
|
||||
assertEqual(b2.read_text(0), "Test", "First text should match");
|
||||
},
|
||||
|
||||
|
||||
test_zero_capacity_blob: function() {
|
||||
var b = Blob(0);
|
||||
assertEqual(length(b), 0, "Zero capacity blob should have length 0");
|
||||
b.write_bit(true);
|
||||
assertEqual(length(b), 1, "Should expand when writing");
|
||||
},
|
||||
|
||||
|
||||
test_large_blob_handling: function() {
|
||||
var b = Blob();
|
||||
var testSize = 1000;
|
||||
|
||||
for (var i = 0; i < testSize; i++) {
|
||||
var i = 0;
|
||||
|
||||
for (i = 0; i < testSize; i++) {
|
||||
b.write_bit(i % 7 == 0);
|
||||
}
|
||||
|
||||
|
||||
assertEqual(length(b), testSize, "Should have " + testSize + " bits");
|
||||
stone(b);
|
||||
|
||||
|
||||
assertEqual(b.read_logical(0), true, "Bit 0 should be true");
|
||||
assertEqual(b.read_logical(7), true, "Bit 7 should be true");
|
||||
assertEqual(b.read_logical(14), true, "Bit 14 should be true");
|
||||
assertEqual(b.read_logical(15), false, "Bit 15 should be false");
|
||||
},
|
||||
|
||||
|
||||
test_non_stone_blob_read_methods_should_throw: function() {
|
||||
var b = Blob();
|
||||
var threw = false;
|
||||
b.write_bit(true);
|
||||
b.write_number(42);
|
||||
b.write_text("test");
|
||||
|
||||
var threw = false;
|
||||
try {
|
||||
|
||||
threw = false;
|
||||
var _try1 = function() {
|
||||
b.read_logical(0);
|
||||
} catch (e) {
|
||||
} disruption {
|
||||
threw = true;
|
||||
}
|
||||
assert(threw, "read_logical on non-stone blob should throw");
|
||||
|
||||
_try1();
|
||||
assert(threw, "read_logical on non-stone blob should disrupt");
|
||||
|
||||
threw = false;
|
||||
try {
|
||||
var _try2 = function() {
|
||||
b.read_number(0);
|
||||
} catch (e) {
|
||||
} disruption {
|
||||
threw = true;
|
||||
}
|
||||
assert(threw, "read_number on non-stone blob should throw");
|
||||
|
||||
_try2();
|
||||
assert(threw, "read_number on non-stone blob should disrupt");
|
||||
|
||||
threw = false;
|
||||
try {
|
||||
var _try3 = function() {
|
||||
b.read_text(0);
|
||||
} catch (e) {
|
||||
} disruption {
|
||||
threw = true;
|
||||
}
|
||||
assert(threw, "read_text on non-stone blob should throw");
|
||||
|
||||
_try3();
|
||||
assert(threw, "read_text on non-stone blob should disrupt");
|
||||
|
||||
threw = false;
|
||||
try {
|
||||
var _try4 = function() {
|
||||
b.read_blob(0, 10);
|
||||
} catch (e) {
|
||||
} disruption {
|
||||
threw = true;
|
||||
}
|
||||
assert(threw, "read_blob on non-stone blob should throw");
|
||||
|
||||
_try4();
|
||||
assert(threw, "read_blob on non-stone blob should disrupt");
|
||||
|
||||
threw = false;
|
||||
try {
|
||||
var _try5 = function() {
|
||||
b['pad?'](0, 8);
|
||||
} catch (e) {
|
||||
} disruption {
|
||||
threw = true;
|
||||
}
|
||||
assert(threw, "pad? on non-stone blob should throw");
|
||||
_try5();
|
||||
assert(threw, "pad? on non-stone blob should disrupt");
|
||||
},
|
||||
|
||||
|
||||
test_empty_text_write_and_read: function() {
|
||||
var b = Blob();
|
||||
b.write_text("");
|
||||
stone(b);
|
||||
assertEqual(b.read_text(0), "", "Empty string should round-trip");
|
||||
},
|
||||
|
||||
|
||||
test_invalid_read_positions: function() {
|
||||
var b = Blob();
|
||||
var threw = false;
|
||||
b.write_number(42);
|
||||
stone(b);
|
||||
|
||||
var threw = false;
|
||||
try {
|
||||
b.read_number(-10);
|
||||
} catch (e) {
|
||||
threw = true;
|
||||
}
|
||||
assert(threw, "Negative position should throw");
|
||||
|
||||
|
||||
threw = false;
|
||||
try {
|
||||
b.read_number(1000);
|
||||
} catch (e) {
|
||||
var _try1 = function() {
|
||||
b.read_number(-10);
|
||||
} disruption {
|
||||
threw = true;
|
||||
}
|
||||
assert(threw, "Position beyond length should throw");
|
||||
_try1();
|
||||
assert(threw, "Negative position should disrupt");
|
||||
|
||||
threw = false;
|
||||
var _try2 = function() {
|
||||
b.read_number(1000);
|
||||
} disruption {
|
||||
threw = true;
|
||||
}
|
||||
_try2();
|
||||
assert(threw, "Position beyond length should disrupt");
|
||||
}
|
||||
}
|
||||
|
||||
10
tests/cat.cm
10
tests/cat.cm
@@ -3,23 +3,21 @@ var time = use('time')
|
||||
|
||||
return {
|
||||
test_cat: function() {
|
||||
// Create temp file
|
||||
var tmp = "cat_test.tmp"
|
||||
var f = fd.open(tmp, 'w')
|
||||
fd.write(f, "Hello world")
|
||||
fd.close(f)
|
||||
|
||||
|
||||
var st = time.number()
|
||||
var f2 = fd.open(tmp, 'r')
|
||||
var stat = fd.fstat(f2)
|
||||
var data = fd.read(f2, stat.size);
|
||||
fd.close(f2)
|
||||
log.console(`cat took ${time.number()-st}`)
|
||||
|
||||
// fd.read returns a blob, read it as text
|
||||
|
||||
stone(data)
|
||||
if (data.read_text(0) != "Hello world") throw "Data mismatch"
|
||||
|
||||
if (data.read_text(0) != "Hello world") disrupt
|
||||
|
||||
fd.unlink(tmp)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,27 +4,28 @@ var blob = use('blob')
|
||||
|
||||
return {
|
||||
test_chunkread: function() {
|
||||
// Create temp file
|
||||
var tmp = "chunk_test.tmp"
|
||||
var f = fd.open(tmp, 'w')
|
||||
var bigdata = ""
|
||||
for(var i=0; i<100; i++) bigdata += "HelloWorld" // 1000 bytes
|
||||
var i = 0
|
||||
var chunk = null
|
||||
for (i = 0; i < 100; i++) bigdata += "HelloWorld"
|
||||
fd.write(f, bigdata)
|
||||
fd.close(f)
|
||||
|
||||
|
||||
var data = blob()
|
||||
var st = time.number()
|
||||
var f2 = fd.open(tmp, 'r')
|
||||
var chunksize = 1024 // reduced for test
|
||||
|
||||
while(true) {
|
||||
var chunk = fd.read(f2, chunksize);
|
||||
var chunksize = 1024
|
||||
|
||||
while (true) {
|
||||
chunk = fd.read(f2, chunksize);
|
||||
data.write_blob(chunk);
|
||||
if (length(chunk) < chunksize * 8) break;
|
||||
if (length(chunk) < chunksize * 8) break;
|
||||
}
|
||||
fd.close(f2)
|
||||
log.console(`read took ${time.number()-st}`)
|
||||
|
||||
|
||||
fd.unlink(tmp)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
return {
|
||||
test_disrupt: function() {
|
||||
throw 1
|
||||
disrupt
|
||||
}
|
||||
}
|
||||
|
||||
122
tests/fit.cm
122
tests/fit.cm
@@ -2,186 +2,186 @@ var fit = use("fit");
|
||||
|
||||
return {
|
||||
and_12_10: function() {
|
||||
if (fit.and(12, 10) != 8) throw "fit.and(12, 10) expected 8";
|
||||
if (fit.and(12, 10) != 8) disrupt
|
||||
},
|
||||
and_16_2: function() {
|
||||
if (fit.and(16, 2) != 0) throw "fit.and(16, 2) expected 0";
|
||||
if (fit.and(16, 2) != 0) disrupt
|
||||
},
|
||||
and_15_3: function() {
|
||||
if (fit.and(15, 3) != 3) throw "fit.and(15, 3) expected 3";
|
||||
if (fit.and(15, 3) != 3) disrupt
|
||||
},
|
||||
and_13_3: function() {
|
||||
if (fit.and(13, 3) != 1) throw "fit.and(13, 3) expected 1";
|
||||
if (fit.and(13, 3) != 1) disrupt
|
||||
},
|
||||
and_string_input: function() {
|
||||
if (fit.and("10", 3) != null) throw "fit.and('10', 3) expected null";
|
||||
if (fit.and("10", 3) != null) disrupt
|
||||
},
|
||||
or_12_10: function() {
|
||||
if (fit.or(12, 10) != 14) throw "fit.or(12, 10) expected 14";
|
||||
if (fit.or(12, 10) != 14) disrupt
|
||||
},
|
||||
or_16_2: function() {
|
||||
if (fit.or(16, 2) != 18) throw "fit.or(16, 2) expected 18";
|
||||
if (fit.or(16, 2) != 18) disrupt
|
||||
},
|
||||
or_15_3: function() {
|
||||
if (fit.or(15, 3) != 15) throw "fit.or(15, 3) expected 15";
|
||||
if (fit.or(15, 3) != 15) disrupt
|
||||
},
|
||||
or_13_3: function() {
|
||||
if (fit.or(13, 3) != 15) throw "fit.or(13, 3) expected 15";
|
||||
if (fit.or(13, 3) != 15) disrupt
|
||||
},
|
||||
xor_12_10: function() {
|
||||
if (fit.xor(12, 10) != 6) throw "fit.xor(12, 10) expected 6";
|
||||
if (fit.xor(12, 10) != 6) disrupt
|
||||
},
|
||||
xor_16_2: function() {
|
||||
if (fit.xor(16, 2) != 18) throw "fit.xor(16, 2) expected 18";
|
||||
if (fit.xor(16, 2) != 18) disrupt
|
||||
},
|
||||
xor_15_3: function() {
|
||||
if (fit.xor(15, 3) != 12) throw "fit.xor(15, 3) expected 12";
|
||||
if (fit.xor(15, 3) != 12) disrupt
|
||||
},
|
||||
xor_13_3: function() {
|
||||
if (fit.xor(13, 3) != 14) throw "fit.xor(13, 3) expected 14";
|
||||
if (fit.xor(13, 3) != 14) disrupt
|
||||
},
|
||||
xor_float_input: function() {
|
||||
if (fit.xor(13.01, 3) != null) throw "fit.xor(13.01, 3) expected null";
|
||||
if (fit.xor(13.01, 3) != null) disrupt
|
||||
},
|
||||
left_12_10: function() {
|
||||
if (fit.left(12, 10) != 12288) throw "fit.left(12, 10) expected 12288";
|
||||
if (fit.left(12, 10) != 12288) disrupt
|
||||
},
|
||||
left_16_2: function() {
|
||||
if (fit.left(16, 2) != 64) throw "fit.left(16, 2) expected 64";
|
||||
if (fit.left(16, 2) != 64) disrupt
|
||||
},
|
||||
left_15_53: function() {
|
||||
if (fit.left(15, 53) != -9007199254740992) throw "fit.left(15, 53) expected -9007199254740992";
|
||||
if (fit.left(15, 53) != -9007199254740992) disrupt
|
||||
},
|
||||
right_12_10: function() {
|
||||
if (fit.right(12, 10) != 0) throw "fit.right(12, 10) expected 0";
|
||||
if (fit.right(12, 10) != 0) disrupt
|
||||
},
|
||||
right_19_2: function() {
|
||||
if (fit.right(19, 2) != 4) throw "fit.right(19, 2) expected 4";
|
||||
if (fit.right(19, 2) != 4) disrupt
|
||||
},
|
||||
right_large: function() {
|
||||
if (fit.right(-9007199254740992, 53) != 7) throw "fit.right(-9007199254740992, 53) expected 7";
|
||||
if (fit.right(-9007199254740992, 53) != 7) disrupt
|
||||
},
|
||||
right_signed: function() {
|
||||
if (fit.right_signed(-2, 1) != -1) throw "fit.right_signed(-2, 1) expected -1";
|
||||
if (fit.right_signed(-2, 1) != -1) disrupt
|
||||
},
|
||||
mask_0: function() {
|
||||
if (fit.mask(0) != 0) throw "fit.mask(0) expected 0";
|
||||
if (fit.mask(0) != 0) disrupt
|
||||
},
|
||||
mask_1: function() {
|
||||
if (fit.mask(1) != 1) throw "fit.mask(1) expected 1";
|
||||
if (fit.mask(1) != 1) disrupt
|
||||
},
|
||||
mask_3: function() {
|
||||
if (fit.mask(3) != 7) throw "fit.mask(3) expected 7";
|
||||
if (fit.mask(3) != 7) disrupt
|
||||
},
|
||||
mask_8: function() {
|
||||
if (fit.mask(8) != 255) throw "fit.mask(8) expected 255";
|
||||
if (fit.mask(8) != 255) disrupt
|
||||
},
|
||||
mask_16: function() {
|
||||
if (fit.mask(16) != 65535) throw "fit.mask(16) expected 65535";
|
||||
if (fit.mask(16) != 65535) disrupt
|
||||
},
|
||||
mask_32: function() {
|
||||
if (fit.mask(32) != 4294967295) throw "fit.mask(32) expected 4294967295";
|
||||
if (fit.mask(32) != 4294967295) disrupt
|
||||
},
|
||||
mask_55: function() {
|
||||
if (fit.mask(55) != 36028797018963967) throw "fit.mask(55) expected 36028797018963967";
|
||||
if (fit.mask(55) != 36028797018963967) disrupt
|
||||
},
|
||||
mask_56: function() {
|
||||
if (fit.mask(56) != -1) throw "fit.mask(56) expected -1";
|
||||
if (fit.mask(56) != -1) disrupt
|
||||
},
|
||||
mask_57: function() {
|
||||
if (fit.mask(57) != null) throw "fit.mask(57) expected null";
|
||||
if (fit.mask(57) != null) disrupt
|
||||
},
|
||||
mask_neg1: function() {
|
||||
if (fit.mask(-1) != -2) throw "fit.mask(-1) expected -2";
|
||||
if (fit.mask(-1) != -2) disrupt
|
||||
},
|
||||
mask_neg3: function() {
|
||||
if (fit.mask(-3) != -8) throw "fit.mask(-3) expected -8";
|
||||
if (fit.mask(-3) != -8) disrupt
|
||||
},
|
||||
mask_neg8: function() {
|
||||
if (fit.mask(-8) != -256) throw "fit.mask(-8) expected -256";
|
||||
if (fit.mask(-8) != -256) disrupt
|
||||
},
|
||||
mask_neg16: function() {
|
||||
if (fit.mask(-16) != -65536) throw "fit.mask(-16) expected -65536";
|
||||
if (fit.mask(-16) != -65536) disrupt
|
||||
},
|
||||
mask_neg32: function() {
|
||||
if (fit.mask(-32) != -4294967296) throw "fit.mask(-32) expected -4294967296";
|
||||
if (fit.mask(-32) != -4294967296) disrupt
|
||||
},
|
||||
mask_neg55: function() {
|
||||
if (fit.mask(-55) != -36028797018963968) throw "fit.mask(-55) expected -36028797018963968";
|
||||
if (fit.mask(-55) != -36028797018963968) disrupt
|
||||
},
|
||||
mask_neg56: function() {
|
||||
if (fit.mask(-56) != 0) throw "fit.mask(-56) expected 0";
|
||||
if (fit.mask(-56) != 0) disrupt
|
||||
},
|
||||
not_0: function() {
|
||||
if (fit.not(0) != -1) throw "fit.not(0) expected -1";
|
||||
if (fit.not(0) != -1) disrupt
|
||||
},
|
||||
not_1: function() {
|
||||
if (fit.not(1) != -2) throw "fit.not(1) expected -2";
|
||||
if (fit.not(1) != -2) disrupt
|
||||
},
|
||||
not_neg1: function() {
|
||||
if (fit.not(-1) != 0) throw "fit.not(-1) expected 0";
|
||||
if (fit.not(-1) != 0) disrupt
|
||||
},
|
||||
ones_neg1: function() {
|
||||
if (fit.ones(-1) != 56) throw "fit.ones(-1) expected 56";
|
||||
if (fit.ones(-1) != 56) disrupt
|
||||
},
|
||||
ones_0: function() {
|
||||
if (fit.ones(0) != 0) throw "fit.ones(0) expected 0";
|
||||
if (fit.ones(0) != 0) disrupt
|
||||
},
|
||||
ones_8: function() {
|
||||
if (fit.ones(8) != 1) throw "fit.ones(8) expected 1";
|
||||
if (fit.ones(8) != 1) disrupt
|
||||
},
|
||||
ones_18: function() {
|
||||
if (fit.ones(18) != 2) throw "fit.ones(18) expected 2";
|
||||
if (fit.ones(18) != 2) disrupt
|
||||
},
|
||||
ones_255: function() {
|
||||
if (fit.ones(255) != 8) throw "fit.ones(255) expected 8";
|
||||
if (fit.ones(255) != 8) disrupt
|
||||
},
|
||||
zeros_neg1: function() {
|
||||
if (fit.zeros(-1) != 0) throw "fit.zeros(-1) expected 0";
|
||||
if (fit.zeros(-1) != 0) disrupt
|
||||
},
|
||||
zeros_0: function() {
|
||||
if (fit.zeros(0) != 56) throw "fit.zeros(0) expected 56";
|
||||
if (fit.zeros(0) != 56) disrupt
|
||||
},
|
||||
zeros_1: function() {
|
||||
if (fit.zeros(1) != 55) throw "fit.zeros(1) expected 55";
|
||||
if (fit.zeros(1) != 55) disrupt
|
||||
},
|
||||
zeros_2: function() {
|
||||
if (fit.zeros(2) != 54) throw "fit.zeros(2) expected 54";
|
||||
if (fit.zeros(2) != 54) disrupt
|
||||
},
|
||||
zeros_1024: function() {
|
||||
if (fit.zeros(1024) != 45) throw "fit.zeros(1024) expected 45";
|
||||
if (fit.zeros(1024) != 45) disrupt
|
||||
},
|
||||
rotate_1_1: function() {
|
||||
if (fit.rotate(1, 1) != 2) throw "fit.rotate(1, 1) expected 2";
|
||||
if (fit.rotate(1, 1) != 2) disrupt
|
||||
},
|
||||
rotate_neg2_1: function() {
|
||||
if (fit.rotate(-2, 1) != -3) throw "fit.rotate(-2, 1) expected -3";
|
||||
if (fit.rotate(-2, 1) != -3) disrupt
|
||||
},
|
||||
rotate_full: function() {
|
||||
if (fit.rotate(1, 56) != 1) throw "fit.rotate(1, 56) expected 1";
|
||||
if (fit.rotate(1, 56) != 1) disrupt
|
||||
},
|
||||
rotate_right: function() {
|
||||
if (fit.rotate(1, -1) != 1 << 55) throw "fit.rotate(1, -1) expected 1 << 55";
|
||||
if (fit.rotate(1, -1) != 1 << 55) disrupt
|
||||
},
|
||||
reverse_neg: function() {
|
||||
if (fit.reverse(-36028797018963968) != 1) throw "fit.reverse(-36028797018963968) expected 1";
|
||||
if (fit.reverse(-36028797018963968) != 1) disrupt
|
||||
},
|
||||
reverse_pi: function() {
|
||||
if (fit.reverse(3141592653589793) != 2334719610726733) throw "fit.reverse(3141592653589793) expected 2334719610726733";
|
||||
if (fit.reverse(3141592653589793) != 2334719610726733) disrupt
|
||||
},
|
||||
and_out_of_range: function() {
|
||||
if (fit.and(1 << 56, 1) != null) throw "fit.and with out-of-range expected null";
|
||||
if (fit.and(1 << 56, 1) != null) disrupt
|
||||
},
|
||||
left_negative_shift: function() {
|
||||
if (fit.left(1, -1) != null) throw "fit.left with negative shift expected null";
|
||||
if (fit.left(1, -1) != null) disrupt
|
||||
},
|
||||
left_large_shift: function() {
|
||||
if (fit.left(1, 100) != null) throw "fit.left with large shift expected null";
|
||||
if (fit.left(1, 100) != null) disrupt
|
||||
},
|
||||
right_negative_shift: function() {
|
||||
if (fit.right(1, -1) != null) throw "fit.right with negative shift expected null";
|
||||
if (fit.right(1, -1) != null) disrupt
|
||||
},
|
||||
mask_float: function() {
|
||||
if (fit.mask(3.5) != null) throw "fit.mask with float expected null";
|
||||
if (fit.mask(3.5) != null) disrupt
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,5 +3,5 @@ var http = use('http')
|
||||
return function() {
|
||||
var url = "http://example.com"
|
||||
var b2 = http.fetch(url)
|
||||
if (length(b2) == 0) throw "Empty response"
|
||||
if (length(b2) == 0) disrupt
|
||||
}
|
||||
18
tests/kim.cm
18
tests/kim.cm
@@ -6,34 +6,34 @@ return {
|
||||
var input = "Hello, World!";
|
||||
var encoded = kim.encode(input);
|
||||
var decoded = kim.decode(encoded);
|
||||
if (input != decoded) throw "ASCII encoding/decoding failed"
|
||||
if (input != decoded) disrupt
|
||||
},
|
||||
|
||||
|
||||
unicode_multilingual: function() {
|
||||
var input = "Hello, 世界! 🌍 Привет мир";
|
||||
var encoded = kim.encode(input);
|
||||
var decoded = kim.decode(encoded);
|
||||
if (input != decoded) throw "Unicode multilingual encoding/decoding failed"
|
||||
if (input != decoded) disrupt
|
||||
},
|
||||
|
||||
|
||||
empty_string: function() {
|
||||
var input = " ";
|
||||
var encoded = kim.encode(input);
|
||||
var decoded = kim.decode(encoded);
|
||||
if (input != decoded) throw "Empty string encoding/decoding failed"
|
||||
if (input != decoded) disrupt
|
||||
},
|
||||
|
||||
|
||||
mixed_unicode_ranges: function() {
|
||||
var input = "αβγδε АБВГД 你好 😀😎🎉 ∑∏∫";
|
||||
var encoded = kim.encode(input);
|
||||
var decoded = kim.decode(encoded);
|
||||
if (input != decoded) throw "Mixed Unicode ranges encoding/decoding failed"
|
||||
if (input != decoded) disrupt
|
||||
},
|
||||
|
||||
|
||||
high_codepoints: function() {
|
||||
var input = "🌍🌎🌏🗺️🧭";
|
||||
var encoded = kim.encode(input);
|
||||
var decoded = kim.decode(encoded);
|
||||
if (input != decoded) throw "High codepoints encoding/decoding failed"
|
||||
if (input != decoded) disrupt
|
||||
}
|
||||
}
|
||||
|
||||
116
tests/miniz.cm
116
tests/miniz.cm
@@ -8,79 +8,99 @@ return {
|
||||
var SOURCE_PATH = "miniz_source.txt"
|
||||
var ENTRY_PATH = "sample/hello.txt"
|
||||
var PAYLOAD = "Miniz integration test payload."
|
||||
|
||||
function write_text_file(path, text) {
|
||||
var source_blob = null
|
||||
var writer = null
|
||||
var zip_blob = null
|
||||
var reader = null
|
||||
var extracted_blob = null
|
||||
var extracted_text = null
|
||||
|
||||
function write_text_file(path, txt) {
|
||||
var handle = fd.open(path, "w")
|
||||
fd.write(handle, text)
|
||||
fd.write(handle, txt)
|
||||
fd.close(handle)
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
var _run = function() {
|
||||
write_text_file(SOURCE_PATH, PAYLOAD)
|
||||
var source_blob = fd.slurp(SOURCE_PATH)
|
||||
var writer = miniz.write(ZIP_PATH)
|
||||
source_blob = fd.slurp(SOURCE_PATH)
|
||||
writer = miniz.write(ZIP_PATH)
|
||||
writer.add_file(ENTRY_PATH, source_blob)
|
||||
writer = null
|
||||
|
||||
var zip_blob = fd.slurp(ZIP_PATH)
|
||||
var reader = miniz.read(zip_blob)
|
||||
|
||||
|
||||
zip_blob = fd.slurp(ZIP_PATH)
|
||||
reader = miniz.read(zip_blob)
|
||||
|
||||
if (!reader.exists(ENTRY_PATH))
|
||||
throw "entry missing in archive"
|
||||
|
||||
var extracted_blob = reader.slurp(ENTRY_PATH)
|
||||
var extracted_text = utf8.decode(extracted_blob)
|
||||
|
||||
disrupt
|
||||
|
||||
extracted_blob = reader.slurp(ENTRY_PATH)
|
||||
extracted_text = utf8.decode(extracted_blob)
|
||||
|
||||
if (extracted_text != PAYLOAD)
|
||||
throw "extracted text mismatch"
|
||||
} finally {
|
||||
try { fd.unlink(ZIP_PATH) } catch(e) {}
|
||||
try { fd.unlink(SOURCE_PATH) } catch(e) {}
|
||||
}
|
||||
disrupt
|
||||
} disruption {}
|
||||
_run()
|
||||
|
||||
var _clean1 = function() { fd.unlink(ZIP_PATH) } disruption {}
|
||||
_clean1()
|
||||
var _clean2 = function() { fd.unlink(SOURCE_PATH) } disruption {}
|
||||
_clean2()
|
||||
},
|
||||
|
||||
|
||||
list_and_count: function() {
|
||||
var ZIP_PATH = "miniz_list_test.zip"
|
||||
var ENTRY1 = "file1.txt"
|
||||
var ENTRY2 = "dir/file2.txt"
|
||||
|
||||
try {
|
||||
var writer = miniz.write(ZIP_PATH)
|
||||
var writer = null
|
||||
var zip_blob = null
|
||||
var reader = null
|
||||
var listed = null
|
||||
|
||||
var _run = function() {
|
||||
writer = miniz.write(ZIP_PATH)
|
||||
writer.add_file(ENTRY1, utf8.encode("content1"))
|
||||
writer.add_file(ENTRY2, utf8.encode("content2"))
|
||||
writer = null
|
||||
|
||||
var zip_blob = fd.slurp(ZIP_PATH)
|
||||
var reader = miniz.read(zip_blob)
|
||||
|
||||
var listed = reader.list()
|
||||
|
||||
zip_blob = fd.slurp(ZIP_PATH)
|
||||
reader = miniz.read(zip_blob)
|
||||
|
||||
listed = reader.list()
|
||||
if (length(listed) != reader.count())
|
||||
throw "list/count mismatch"
|
||||
disrupt
|
||||
if (length(listed) != 2)
|
||||
throw "unexpected entry count"
|
||||
} finally {
|
||||
try { fd.unlink(ZIP_PATH) } catch(e) {}
|
||||
}
|
||||
disrupt
|
||||
} disruption {}
|
||||
_run()
|
||||
|
||||
var _clean = function() { fd.unlink(ZIP_PATH) } disruption {}
|
||||
_clean()
|
||||
},
|
||||
|
||||
|
||||
exists_check: function() {
|
||||
var ZIP_PATH = "miniz_exists_test.zip"
|
||||
var ENTRY_PATH = "existing.txt"
|
||||
|
||||
try {
|
||||
var writer = miniz.write(ZIP_PATH)
|
||||
var writer = null
|
||||
var zip_blob = null
|
||||
var reader = null
|
||||
|
||||
var _run = function() {
|
||||
writer = miniz.write(ZIP_PATH)
|
||||
writer.add_file(ENTRY_PATH, utf8.encode("data"))
|
||||
writer = null
|
||||
|
||||
var zip_blob = fd.slurp(ZIP_PATH)
|
||||
var reader = miniz.read(zip_blob)
|
||||
|
||||
|
||||
zip_blob = fd.slurp(ZIP_PATH)
|
||||
reader = miniz.read(zip_blob)
|
||||
|
||||
if (!reader.exists(ENTRY_PATH))
|
||||
throw "existing entry not found"
|
||||
disrupt
|
||||
if (reader.exists("nonexistent.txt"))
|
||||
throw "nonexistent entry reported as existing"
|
||||
} finally {
|
||||
try { fd.unlink(ZIP_PATH) } catch(e) {}
|
||||
}
|
||||
disrupt
|
||||
} disruption {}
|
||||
_run()
|
||||
|
||||
var _clean = function() { fd.unlink(ZIP_PATH) } disruption {}
|
||||
_clean()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,26 +8,34 @@ function stone_if_needed(b) { if (!stone.p(b)) stone(b) }
|
||||
|
||||
function bytes_to_blob(bytes) {
|
||||
var b = blob()
|
||||
for (var i = 0; i < length(bytes); i++) {
|
||||
var byte = bytes[i]
|
||||
for (var bit = 7; bit >= 0; bit--) b.write_bit((byte >> bit) & 1)
|
||||
var i = 0
|
||||
var byte = null
|
||||
var bit = null
|
||||
for (i = 0; i < length(bytes); i++) {
|
||||
byte = bytes[i]
|
||||
for (bit = 7; bit >= 0; bit--) b.write_bit((byte >> bit) & 1)
|
||||
}
|
||||
stone(b)
|
||||
return b
|
||||
}
|
||||
|
||||
function deepCompare(expected, actual, path) {
|
||||
path = path || ''
|
||||
function deepCompare(expected, actual, _path) {
|
||||
var diff = null
|
||||
var messages = null
|
||||
var expKeys = null
|
||||
var actKeys = null
|
||||
var i = 0
|
||||
var 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);
|
||||
|
||||
diff = abs(expected - actual);
|
||||
if (diff <= EPSILON)
|
||||
return { passed: true, messages: [] };
|
||||
|
||||
|
||||
return {
|
||||
passed: false,
|
||||
messages: [
|
||||
@@ -41,7 +49,7 @@ function deepCompare(expected, actual, path) {
|
||||
stone_if_needed(expected); stone_if_needed(actual)
|
||||
if (length(expected) != length(actual))
|
||||
return { passed: false, messages: [`blob length mismatch at ${path}: ${length(expected)} vs ${length(actual)}`] }
|
||||
for (var i = 0; i < length(expected); i++) {
|
||||
for (i = 0; i < length(expected); i++) {
|
||||
if (expected.read_logical(i) != actual.read_logical(i))
|
||||
return { passed: false, messages: [`blob bit mismatch at ${path}[${i}]`] }
|
||||
}
|
||||
@@ -54,7 +62,7 @@ function deepCompare(expected, actual, path) {
|
||||
passed: false,
|
||||
messages: [`Array length mismatch at ${path}: expected ${length(expected)}, got ${length(actual)}`]
|
||||
};
|
||||
var messages = [];
|
||||
messages = [];
|
||||
arrfor(expected, function(val, i) {
|
||||
var result = deepCompare(val, actual[i], `${path}[${i}]`);
|
||||
if (!result.passed)
|
||||
@@ -64,17 +72,17 @@ function deepCompare(expected, actual, path) {
|
||||
}
|
||||
|
||||
if (is_object(expected) && is_object(actual)) {
|
||||
var expKeys = sort(array(expected))
|
||||
var actKeys = sort(array(actual))
|
||||
expKeys = sort(array(expected))
|
||||
actKeys = sort(array(actual))
|
||||
if (JSON.stringify(expKeys) != JSON.stringify(actKeys))
|
||||
return {
|
||||
passed: false,
|
||||
messages: [`Object keys mismatch at ${path}: expected ${expKeys}, got ${actKeys}`]
|
||||
};
|
||||
var messages = [];
|
||||
messages = [];
|
||||
arrfor(expKeys, function(key) {
|
||||
var result = deepCompare(expected[key], actual[key], `${path}.${key}`);
|
||||
if (!result.passed)
|
||||
if (!result.passed)
|
||||
messages = array(messages, result.messages)
|
||||
})
|
||||
return { passed: length(messages) == 0, messages: messages };
|
||||
@@ -89,26 +97,32 @@ function deepCompare(expected, actual, path) {
|
||||
function makeTest(test) {
|
||||
return function() {
|
||||
var encoded = test.replacer ? nota.encode(test.input, test.replacer) : nota.encode(test.input);
|
||||
if (!is_blob(encoded)){
|
||||
throw "encode() should return blob";
|
||||
var decoded = null
|
||||
var expected = null
|
||||
var key = null
|
||||
var compareResult = null
|
||||
if (!is_blob(encoded)) {
|
||||
disrupt
|
||||
}
|
||||
|
||||
var decoded = test.reviver ? nota.decode(encoded, test.reviver) : nota.decode(encoded);
|
||||
var expected = test.expected || test.input;
|
||||
decoded = test.reviver ? nota.decode(encoded, test.reviver) : nota.decode(encoded);
|
||||
expected = test.expected || test.input;
|
||||
if (expected && (expected.private || expected.system)) {
|
||||
var key = expected.private ? 'private' : 'system';
|
||||
key = expected.private ? 'private' : 'system';
|
||||
expected = { [key]: expected[key] };
|
||||
}
|
||||
|
||||
var compareResult = deepCompare(expected, decoded);
|
||||
compareResult = deepCompare(expected, decoded);
|
||||
if (!compareResult.passed) {
|
||||
throw text(compareResult.messages, '; ');
|
||||
disrupt
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var testarr = []
|
||||
for (var i = 0; i < 500; i++) {
|
||||
var i = 0
|
||||
var t = null
|
||||
for (i = 0; i < 500; i++) {
|
||||
push(testarr, 1)
|
||||
}
|
||||
|
||||
@@ -172,8 +186,8 @@ var testCases = [
|
||||
];
|
||||
|
||||
var tests = {};
|
||||
for (var i = 0; i < length(testCases); i++) {
|
||||
var t = testCases[i];
|
||||
for (i = 0; i < length(testCases); i++) {
|
||||
t = testCases[i];
|
||||
tests[t.name] = makeTest(t);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,28 +2,17 @@ var time = use('time');
|
||||
|
||||
return {
|
||||
test_overling: function() {
|
||||
// Ported from overling.ce
|
||||
// Note: This test spawns actors and waits for them.
|
||||
// In a sync function test, we can't easily wait for async actor events unless we block/poll.
|
||||
// However, the new test runner might expect sync return or a promise (not available yet?).
|
||||
// For now, we'll just spawn them to ensure no immediate crashes.
|
||||
// Full async testing might require a different approach or `dmon.poll` style loop if events are exposed.
|
||||
// Assuming for now that we just verify strict logical errors.
|
||||
|
||||
var underlingCount = 0;
|
||||
var targetCount = 3;
|
||||
|
||||
// Spawn several underlings
|
||||
for (var i = 0; i < targetCount; i++) {
|
||||
var i = 0;
|
||||
|
||||
for (i = 0; i < targetCount; i++) {
|
||||
$start(function(greet) {
|
||||
underlingCount++;
|
||||
log.console("Underling spawned: " + underlingCount);
|
||||
}, "tests/underling_actor", ["test" + i]);
|
||||
}
|
||||
|
||||
// We can't easily wait here without a loop that yields, but this is a single threaded JS env usually.
|
||||
// If $delay is async, we return immediately.
|
||||
|
||||
|
||||
log.console("Spawned " + targetCount + " underlings (async)");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,17 +20,10 @@ return {
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
var st = time.number()
|
||||
var actor
|
||||
|
||||
// This test depends on 'tests/comments' which we created as 'comments.cm'
|
||||
// but 'comments.cm' wraps the actor logic in a function.
|
||||
// The original 'comments.ce' was an actor script.
|
||||
// We should probably restore 'comments.ce' as 'comments_actor.ce' for this test to work if it relies on spawning it.
|
||||
// But 'comments.cm' (the new test file) also has the logic.
|
||||
// We need an actor file for $start to work with.
|
||||
|
||||
var actor = null
|
||||
|
||||
$start(e => {
|
||||
if (actor) return
|
||||
actor = e.actor
|
||||
@@ -39,9 +32,9 @@ return {
|
||||
log.console(reason)
|
||||
else
|
||||
log.console(result)
|
||||
|
||||
|
||||
log.console(`took ${time.number()-st} secs`)
|
||||
});
|
||||
}, "tests/comments_actor") // We will create this next
|
||||
}, "tests/comments_actor")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,247 +1,241 @@
|
||||
return {
|
||||
// Array conversion tests
|
||||
test_array_basic: function() {
|
||||
var arr1 = ["Hello", " ", "World"]
|
||||
var result1 = text(arr1)
|
||||
if (result1 != "Hello World") throw "Basic array concat failed"
|
||||
if (result1 != "Hello World") disrupt
|
||||
},
|
||||
|
||||
test_array_separator: function() {
|
||||
var arr2 = ["one", "two", "three"]
|
||||
var result2 = text(arr2, ", ")
|
||||
if (result2 != "one, two, three") throw "Array with separator failed"
|
||||
if (result2 != "one, two, three") disrupt
|
||||
},
|
||||
|
||||
test_array_codepoints: function() {
|
||||
var arr3 = [72, 101, 108, 108, 111]
|
||||
var result3 = text(arr3)
|
||||
if (result3 != "Hello") throw "Codepoints failed"
|
||||
if (result3 != "Hello") disrupt
|
||||
},
|
||||
|
||||
test_array_mixed: function() {
|
||||
var arr4 = ["Hi", 32, "there", 33]
|
||||
var result4 = text(arr4)
|
||||
if (result4 != "Hi there!") throw "Mixed array failed"
|
||||
if (result4 != "Hi there!") disrupt
|
||||
},
|
||||
|
||||
// Radix tests
|
||||
test_radix_10: function() {
|
||||
var result = text(12, 10)
|
||||
if (result != "12") throw "Radix 10 failed"
|
||||
if (result != "12") disrupt
|
||||
},
|
||||
|
||||
test_radix_8: function() {
|
||||
var result = text(12, 8)
|
||||
if (result != "14") throw "Radix 8 failed"
|
||||
if (result != "14") disrupt
|
||||
},
|
||||
|
||||
test_radix_16: function() {
|
||||
var result = text(12, 16)
|
||||
if (result != "c") throw "Radix 16 failed"
|
||||
if (result != "c") disrupt
|
||||
},
|
||||
|
||||
test_radix_2: function() {
|
||||
var result = text(12, 2)
|
||||
if (result != "1100") throw "Radix 2 failed"
|
||||
if (result != "1100") disrupt
|
||||
},
|
||||
|
||||
test_radix_32: function() {
|
||||
var result = text(12, 32)
|
||||
if (result != "c") throw "Radix 32 failed"
|
||||
if (result != "c") disrupt
|
||||
},
|
||||
|
||||
test_radix_hex_large: function() {
|
||||
var result = text(255, 16)
|
||||
if (result != "ff") throw "Radix 16 large failed"
|
||||
if (result != "ff") disrupt
|
||||
},
|
||||
|
||||
test_radix_negative: function() {
|
||||
var result = text(-42, 10)
|
||||
if (result != "-42") throw "Radix negative failed"
|
||||
if (result != "-42") disrupt
|
||||
},
|
||||
|
||||
test_radix_36: function() {
|
||||
var result = text(100, 36)
|
||||
if (result != "2s") throw "Radix 36 failed"
|
||||
if (result != "2s") disrupt
|
||||
},
|
||||
|
||||
// Formatted number tests
|
||||
test_format_n: function() {
|
||||
var result = text(123456789.1, "n")
|
||||
if (result != "123456789.1") throw "Format n failed"
|
||||
if (result != "123456789.1") disrupt
|
||||
},
|
||||
|
||||
test_format_spaced_decimal: function() {
|
||||
var result = text(123456789.1, "3s4")
|
||||
if (result != "123 456 789.1000") throw "Format 3s4 failed"
|
||||
if (result != "123 456 789.1000") disrupt
|
||||
},
|
||||
|
||||
test_format_s: function() {
|
||||
var result = text(123456789.1, "s")
|
||||
if (result != "123 456 789.1") throw "Format s failed"
|
||||
if (result != "123 456 789.1") disrupt
|
||||
},
|
||||
|
||||
test_format_d2: function() {
|
||||
var result = text(123456789.1, "d2")
|
||||
if (result != "123,456,789.10") throw "Format d2 failed"
|
||||
if (result != "123,456,789.10") disrupt
|
||||
},
|
||||
|
||||
test_format_4d0: function() {
|
||||
var result = text(123456789.1, "4d0")
|
||||
if (result != "1,2345,6789.1") throw "Format 4d0 failed"
|
||||
if (result != "1,2345,6789.1") disrupt
|
||||
},
|
||||
|
||||
test_format_e: function() {
|
||||
var result = text(123456789.1, "e")
|
||||
if (result != "1.234567891e+8") throw "Format e failed"
|
||||
if (result != "1.234567891e+8") disrupt
|
||||
},
|
||||
|
||||
test_format_e4: function() {
|
||||
var result = text(123456789.1, "e4")
|
||||
if (result != "1.2346e+8") throw "Format e4 failed"
|
||||
if (result != "1.2346e+8") disrupt
|
||||
},
|
||||
|
||||
test_format_i: function() {
|
||||
var result = text(123456789.1, "i")
|
||||
if (result != "123456789") throw "Format i failed"
|
||||
if (result != "123456789") disrupt
|
||||
},
|
||||
|
||||
test_format_8b: function() {
|
||||
var result = text(123456789.1, "8b")
|
||||
if (result != "111_01011011_11001101_00010101") throw "Format 8b failed"
|
||||
if (result != "111_01011011_11001101_00010101") disrupt
|
||||
},
|
||||
|
||||
test_format_o: function() {
|
||||
var result = text(123456789.1, "o")
|
||||
if (result != "726746425") throw "Format o failed"
|
||||
if (result != "726746425") disrupt
|
||||
},
|
||||
|
||||
test_format_h: function() {
|
||||
var result = text(123456789.1, "h")
|
||||
if (result != "75BCD15") throw "Format h failed"
|
||||
if (result != "75BCD15") disrupt
|
||||
},
|
||||
|
||||
test_format_t: function() {
|
||||
var result = text(123456789.1, "t")
|
||||
if (result != "3NQK8N") throw "Format t failed"
|
||||
if (result != "3NQK8N") disrupt
|
||||
},
|
||||
|
||||
// Integer formatting tests
|
||||
test_int_4b8: function() {
|
||||
var result = text(12, "4b8")
|
||||
if (result != "0000_1100") throw "Int format 4b8 failed"
|
||||
if (result != "0000_1100") disrupt
|
||||
},
|
||||
|
||||
test_int_o3: function() {
|
||||
var result = text(12, "o3")
|
||||
if (result != "014") throw "Int format o3 failed"
|
||||
if (result != "014") disrupt
|
||||
},
|
||||
|
||||
test_int_h4: function() {
|
||||
var result = text(12, "h4")
|
||||
if (result != "000C") throw "Int format h4 failed"
|
||||
if (result != "000C") disrupt
|
||||
},
|
||||
|
||||
test_int_t2: function() {
|
||||
var result = text(12, "t2")
|
||||
if (result != "0C") throw "Int format t2 failed"
|
||||
if (result != "0C") disrupt
|
||||
},
|
||||
|
||||
test_int_h_negative: function() {
|
||||
var result = text(-15, "h")
|
||||
if (result != "-F") throw "Int format negative h failed"
|
||||
if (result != "-F") disrupt
|
||||
},
|
||||
|
||||
test_int_b_zero: function() {
|
||||
var result = text(0, "b")
|
||||
if (result != "0") throw "Int format zero b failed"
|
||||
if (result != "0") disrupt
|
||||
},
|
||||
|
||||
// Substring tests
|
||||
test_substr_start: function() {
|
||||
var str = "miskatonic"
|
||||
var result = text(str, 0, 3)
|
||||
if (result != "mis") throw "Substr start failed"
|
||||
if (result != "mis") disrupt
|
||||
},
|
||||
|
||||
test_substr_middle: function() {
|
||||
var str = "miskatonic"
|
||||
var result = text(str, 3, 6)
|
||||
if (result != "kat") throw "Substr middle failed"
|
||||
if (result != "kat") disrupt
|
||||
},
|
||||
|
||||
test_substr_to_end: function() {
|
||||
var str = "miskatonic"
|
||||
var result = text(str, 5, null)
|
||||
if (result != "tonic") throw "Substr to end failed"
|
||||
if (result != "tonic") disrupt
|
||||
},
|
||||
|
||||
test_substr_negative_to: function() {
|
||||
var str = "miskatonic"
|
||||
var result = text(str, 0, -4)
|
||||
if (result != "miskat") throw "Substr negative to failed"
|
||||
if (result != "miskat") disrupt
|
||||
},
|
||||
|
||||
test_substr_negative_from: function() {
|
||||
var str = "miskatonic"
|
||||
var result = text(str, -3, null)
|
||||
if (result != "nic") throw "Substr negative from failed"
|
||||
if (result != "nic") disrupt
|
||||
},
|
||||
|
||||
test_substr_empty_range: function() {
|
||||
var str = "miskatonic"
|
||||
var result = text(str, 0, 0)
|
||||
if (result != "") throw "Substr empty range failed"
|
||||
if (result != "") disrupt
|
||||
},
|
||||
|
||||
test_substr_past_end: function() {
|
||||
var str = "miskatonic"
|
||||
var result = text(str, 10, null)
|
||||
if (result != "") throw "Substr past end failed"
|
||||
if (result != "") disrupt
|
||||
},
|
||||
|
||||
test_substr_out_of_bounds: function() {
|
||||
var str = "miskatonic"
|
||||
var result = text(str, 11, null)
|
||||
if (result != null) throw "Substr out of bounds failed"
|
||||
if (result != null) disrupt
|
||||
},
|
||||
|
||||
test_substr_invalid_range: function() {
|
||||
var str = "miskatonic"
|
||||
var result = text(str, 2, 1)
|
||||
if (result != null) throw "Substr invalid range failed"
|
||||
if (result != null) disrupt
|
||||
},
|
||||
|
||||
// Edge cases
|
||||
test_empty_array: function() {
|
||||
var result = text([])
|
||||
if (result != "") throw "Empty array test failed"
|
||||
if (result != "") disrupt
|
||||
},
|
||||
|
||||
test_single_element: function() {
|
||||
var result = text([42])
|
||||
if (result != "42") throw "Single element array test failed"
|
||||
if (result != "42") disrupt
|
||||
},
|
||||
|
||||
test_identity: function() {
|
||||
var result = text("hello")
|
||||
if (result != "hello") throw "Text identity test failed"
|
||||
if (result != "hello") disrupt
|
||||
},
|
||||
|
||||
test_invalid_format: function() {
|
||||
var result = text(123, "xyz")
|
||||
if (result != null) throw "Invalid format test failed"
|
||||
if (result != null) disrupt
|
||||
},
|
||||
|
||||
test_tiny_number: function() {
|
||||
var tiny = 0.0000001
|
||||
var result = text(tiny, "n")
|
||||
if (search(result, 'e', 0) == null) throw "Tiny number format failed"
|
||||
if (search(result, 'e', 0) == null) disrupt
|
||||
},
|
||||
|
||||
test_huge_number: function() {
|
||||
var huge = 1e22
|
||||
var result = text(huge, "n")
|
||||
if (search(result, 'e', 0) == null) throw "Huge number format failed"
|
||||
if (search(result, 'e', 0) == null) disrupt
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,24 @@
|
||||
var toml = use('toml')
|
||||
|
||||
function deep_equal(a, b) {
|
||||
var keys_a = null
|
||||
var keys_b = null
|
||||
var i = 0
|
||||
if (a == b) return true
|
||||
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 (is_object(a)) {
|
||||
var keys_a = array(a)
|
||||
var keys_b = array(b)
|
||||
keys_a = array(a)
|
||||
keys_b = array(b)
|
||||
if (length(keys_a) != length(keys_b)) return false
|
||||
|
||||
for (var i = 0; i < length(keys_a); i++) {
|
||||
|
||||
for (i = 0; i < length(keys_a); i++) {
|
||||
if (!deep_equal(a[keys_a[i]], b[keys_a[i]])) return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -25,7 +28,7 @@ function test_roundtrip(obj, name) {
|
||||
if (!deep_equal(obj, decoded)) {
|
||||
log.console(name + " - Original:", obj)
|
||||
log.console(name + " - Round-trip:", decoded)
|
||||
throw name + " round-trip failed"
|
||||
disrupt
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +82,7 @@ return {
|
||||
port: 8080
|
||||
},
|
||||
beta: {
|
||||
ip: "192.168.1.2",
|
||||
ip: "192.168.1.2",
|
||||
port: 8081
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
var cmds = {
|
||||
stop: $stop,
|
||||
disrupt: _ => {
|
||||
$delay(_ => { throw Error() }, 0.5)
|
||||
$delay(_ => { disrupt }, 0.5)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
try {
|
||||
var _try = function() {
|
||||
var u = use('tests/use')
|
||||
} catch(e) {
|
||||
log.console(e)
|
||||
} disruption {
|
||||
log.console("disruption caught")
|
||||
}
|
||||
_try()
|
||||
|
||||
@@ -7,14 +7,18 @@ 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 || ''
|
||||
function deep_compare(expected, actual, _path) {
|
||||
var diff = null
|
||||
var msgs = null
|
||||
var expKeys = null
|
||||
var actKeys = null
|
||||
var i = 0
|
||||
var 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)
|
||||
diff = abs(expected - actual)
|
||||
if (diff <= EPSILON) return { passed: true, messages: [] }
|
||||
return { passed: false, messages: [`Value mismatch at ${path}: ${expected} vs ${actual} (diff ${diff})`] }
|
||||
}
|
||||
@@ -33,7 +37,7 @@ function deep_compare(expected, actual, path) {
|
||||
if (is_array(expected) && is_array(actual)) {
|
||||
if (length(expected) != length(actual))
|
||||
return { passed: false, messages: [`Array length mismatch at ${path}: ${length(expected)} vs ${length(actual)}`] }
|
||||
var msgs = []
|
||||
msgs = []
|
||||
arrfor(array(expected), function(i) {
|
||||
var res = deep_compare(expected[i], actual[i], `${path}[${i}]`)
|
||||
if (!res.passed) array(msgs, res.messages)
|
||||
@@ -42,11 +46,11 @@ function deep_compare(expected, actual, path) {
|
||||
}
|
||||
|
||||
if (is_object(expected) && is_object(actual)) {
|
||||
var expKeys = sort(array(expected))
|
||||
var actKeys = sort(array(actual))
|
||||
expKeys = sort(array(expected))
|
||||
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 = []
|
||||
msgs = []
|
||||
arrfor(expKeys, function(k) {
|
||||
var res = deep_compare(expected[k], actual[k], `${path}.${k}`)
|
||||
if (!res.passed) array(msgs, res.messages)
|
||||
@@ -58,7 +62,10 @@ function deep_compare(expected, actual, path) {
|
||||
}
|
||||
|
||||
var testarr = []
|
||||
for (var i = 0; i < 500; i++) { push(testarr, 1) }
|
||||
var i = 0
|
||||
var t = null
|
||||
var name = null
|
||||
for (i = 0; i < 500; i++) { push(testarr, 1) }
|
||||
|
||||
var testCases = [
|
||||
{ name: 'zero', input: 0 },
|
||||
@@ -84,7 +91,7 @@ var testCases = [
|
||||
|
||||
{ name: 'empty_string', input: '' },
|
||||
{ name: 'string_cat', input: 'cat' },
|
||||
{ name: 'string_unicode', input: 'U+1F4A9 「うんち絵文字」 «💩»' },
|
||||
{ name: 'string_unicode', input: 'U+1F4A9 「うんち絵文字」 «💩»' },
|
||||
|
||||
{ name: 'large_array', input: testarr },
|
||||
|
||||
@@ -106,19 +113,19 @@ var testCases = [
|
||||
function make_test(t) {
|
||||
return function() {
|
||||
var enc = wota.encode(t.input)
|
||||
if (!is_blob(enc)) throw 'encode() should return a blob'
|
||||
if (!is_blob(enc)) disrupt
|
||||
|
||||
var dec = wota.decode(enc)
|
||||
|
||||
var cmp = deep_compare(t.input, dec)
|
||||
if (!cmp.passed) throw text(cmp.messages, '; ')
|
||||
if (!cmp.passed) disrupt
|
||||
}
|
||||
}
|
||||
|
||||
var tests = {}
|
||||
for (var i = 0; i < length(testCases); i++) {
|
||||
var t = testCases[i]
|
||||
var name = t.name || ('case_' + i)
|
||||
for (i = 0; i < length(testCases); i++) {
|
||||
t = testCases[i]
|
||||
name = t.name || ('case_' + i)
|
||||
tests[name] = make_test(t)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user