closes #12
This commit is contained in:
@@ -285,9 +285,14 @@ function load_actor_config(program) {
|
||||
|
||||
var blob = use('blob')
|
||||
|
||||
var blob_stone = blob.prototype.stone
|
||||
var blob_stonep = blob.prototype.stonep;
|
||||
delete blob.prototype.stone;
|
||||
delete blob.prototype.stonep;
|
||||
|
||||
function deepFreeze(object) {
|
||||
if (object instanceof blob)
|
||||
object.stone()
|
||||
blob_stone.call(object);
|
||||
|
||||
// Retrieve the property names defined on object
|
||||
var propNames = Object.keys(object);
|
||||
@@ -307,14 +312,9 @@ function deepFreeze(object) {
|
||||
globalThis.stone = deepFreeze
|
||||
stone.p = function(object)
|
||||
{
|
||||
if (object instanceof blob) {
|
||||
try {
|
||||
object.read_logical(0)
|
||||
return true
|
||||
} catch(e) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if (object instanceof blob)
|
||||
return blob_stonep.call(object)
|
||||
|
||||
return Object.isFrozen(object)
|
||||
}
|
||||
|
||||
|
||||
@@ -371,6 +371,15 @@ static JSValue js_blob_stone(JSContext *ctx, JSValueConst this_val,
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
static JSValue js_blob_stonep(JSContext *ctx, JSValueConst this_val,
|
||||
int argc, JSValueConst *argv) {
|
||||
blob *bd = js2blob(ctx, this_val);
|
||||
if (!bd) {
|
||||
return JS_ThrowTypeError(ctx, "stone: not called on a blob");
|
||||
}
|
||||
return JS_NewBool(ctx, bd->is_stone);
|
||||
}
|
||||
|
||||
// blob.length getter
|
||||
// Return number of bits in the blob
|
||||
static JSValue js_blob_get_length(JSContext *ctx, JSValueConst this_val, int magic) {
|
||||
@@ -402,6 +411,7 @@ static const JSCFunctionListEntry js_blob_funcs[] = {
|
||||
|
||||
// Other methods
|
||||
JS_CFUNC_DEF("stone", 0, js_blob_stone),
|
||||
JS_CFUNC_DEF("stonep", 0, js_blob_stonep),
|
||||
|
||||
// Length property getter
|
||||
JS_CGETSET_DEF("length", js_blob_get_length, NULL),
|
||||
|
||||
@@ -51,7 +51,7 @@ test("Write and read single bit", function() {
|
||||
b.write_bit(0);
|
||||
assertEqual(b.length, 4, "Should have 4 bits after writing");
|
||||
|
||||
b.stone(); // Make it stone to read
|
||||
stone(b); // Make it stone to read
|
||||
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)");
|
||||
@@ -62,7 +62,7 @@ test("Write and read single bit", function() {
|
||||
test("Out of range read throws error", function() {
|
||||
var b = new Blob();
|
||||
b.write_bit(true);
|
||||
b.stone();
|
||||
stone(b);
|
||||
|
||||
var threw = false;
|
||||
try {
|
||||
@@ -88,7 +88,7 @@ test("Write and read numbers", function() {
|
||||
b.write_number(-42);
|
||||
b.write_number(0);
|
||||
b.write_number(1e20);
|
||||
b.stone();
|
||||
stone(b);
|
||||
|
||||
// Read back the numbers
|
||||
assertEqual(b.read_number(0), 3.14159, "First number should match");
|
||||
@@ -103,7 +103,7 @@ test("Write and read text", function() {
|
||||
b.write_text("Hello");
|
||||
b.write_text("World");
|
||||
b.write_text("🎉"); // Unicode test
|
||||
b.stone();
|
||||
stone(b);
|
||||
|
||||
assertEqual(b.read_text(0), "Hello", "First text should match");
|
||||
// Note: We need to know bit positions to read subsequent strings
|
||||
@@ -121,7 +121,7 @@ test("Write and read blobs", function() {
|
||||
b2.write_bit(false);
|
||||
assertEqual(b2.length, 4, "Combined blob should have 4 bits");
|
||||
|
||||
b2.stone();
|
||||
stone(b2);
|
||||
assertEqual(b2.read_logical(0), true);
|
||||
assertEqual(b2.read_logical(1), false);
|
||||
assertEqual(b2.read_logical(2), true);
|
||||
@@ -135,10 +135,10 @@ test("Blob copy constructor", function() {
|
||||
b1.write_bit(false);
|
||||
b1.write_bit(true);
|
||||
b1.write_bit(true);
|
||||
b1.stone();
|
||||
stone(b1);
|
||||
|
||||
var b2 = new Blob(b1);
|
||||
b2.stone(); // Need to stone the copy before reading
|
||||
stone(b2); // Need to stone the copy before reading
|
||||
assertEqual(b2.length, 4, "Copied blob should have same length");
|
||||
assertEqual(b2.read_logical(0), true);
|
||||
assertEqual(b2.read_logical(3), true);
|
||||
@@ -150,10 +150,10 @@ test("Blob partial copy constructor", function() {
|
||||
for (var i = 0; i < 10; i++) {
|
||||
b1.write_bit(i % 2 === 0);
|
||||
}
|
||||
b1.stone();
|
||||
stone(b1);
|
||||
|
||||
var b2 = new Blob(b1, 2, 7); // Copy bits 2-6 (5 bits)
|
||||
b2.stone(); // Need to stone the copy before reading
|
||||
stone(b2); // Need to stone the copy before reading
|
||||
assertEqual(b2.length, 5, "Partial copy should have 5 bits");
|
||||
assertEqual(b2.read_logical(0), true); // bit 2 of original
|
||||
assertEqual(b2.read_logical(2), true); // bit 4 of original
|
||||
@@ -164,8 +164,8 @@ test("Create blob with fill", function() {
|
||||
var b1 = new Blob(8, true); // 8 bits all set to 1
|
||||
var b2 = new Blob(8, false); // 8 bits all set to 0
|
||||
|
||||
b1.stone();
|
||||
b2.stone();
|
||||
stone(b1);
|
||||
stone(b2);
|
||||
|
||||
for (var i = 0; i < 8; i++) {
|
||||
assertEqual(b1.read_logical(i), true, "Bit " + i + " should be true");
|
||||
@@ -182,7 +182,7 @@ test("Create blob with random function", function() {
|
||||
return sequence[index++] ? 1 : 0;
|
||||
});
|
||||
|
||||
b.stone();
|
||||
stone(b);
|
||||
for (var i = 0; i < 5; i++) {
|
||||
assertEqual(b.read_logical(i), sequence[i], "Bit " + i + " should match sequence");
|
||||
}
|
||||
@@ -197,7 +197,7 @@ test("Write pad and check padding", function() {
|
||||
b.write_pad(8); // Pad to 8-bit boundary
|
||||
|
||||
assertEqual(b.length, 8, "Should be padded to 8 bits");
|
||||
b.stone();
|
||||
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");
|
||||
@@ -209,10 +209,10 @@ test("Read blob from stone blob", function() {
|
||||
for (var i = 0; i < 16; i++) {
|
||||
b1.write_bit(i % 3 === 0);
|
||||
}
|
||||
b1.stone();
|
||||
stone(b1);
|
||||
|
||||
var b2 = b1.read_blob(4, 12); // Read bits 4-11 (8 bits)
|
||||
b2.stone(); // Need to stone the read blob before reading from it
|
||||
stone(b2); // Need to stone the read blob before reading from it
|
||||
assertEqual(b2.length, 8, "Read blob should have 8 bits");
|
||||
|
||||
// Check the pattern
|
||||
@@ -224,7 +224,7 @@ test("Read blob from stone blob", function() {
|
||||
test("Stone blob is immutable", function() {
|
||||
var b = new Blob();
|
||||
b.write_bit(true);
|
||||
b.stone();
|
||||
stone(b);
|
||||
|
||||
var threw = false;
|
||||
try {
|
||||
@@ -235,13 +235,18 @@ test("Stone blob is immutable", function() {
|
||||
assert(threw, "Writing to stone blob should throw error");
|
||||
});
|
||||
|
||||
// Test 15: Multiple stone calls
|
||||
test("Multiple stone calls are safe", function() {
|
||||
// Test 15: Multiple stone calls and stone.p check
|
||||
test("Multiple stone calls are safe and stone.p works", function() {
|
||||
var b = new Blob();
|
||||
b.write_bit(true);
|
||||
b.stone();
|
||||
b.stone(); // Should be safe to call again
|
||||
assert(!stone.p(b), "Blob should not be a stone before stone() call");
|
||||
stone(b);
|
||||
assert(stone.p(b), "Blob should be a stone after stone() call");
|
||||
stone(b); // Should be safe to call again
|
||||
assertEqual(b.read_logical(0), true, "Blob data should remain intact");
|
||||
|
||||
// Verify blob.stone is not available
|
||||
assert(b.stone === undefined, "blob.stone should not be available as a method");
|
||||
});
|
||||
|
||||
// Test 16: Invalid constructor arguments
|
||||
@@ -282,11 +287,11 @@ test("Complex data round-trip", function() {
|
||||
b.write_number(-999.999);
|
||||
|
||||
var originalLength = b.length;
|
||||
b.stone();
|
||||
stone(b);
|
||||
|
||||
// Verify we can create a copy
|
||||
var b2 = new Blob(b);
|
||||
b2.stone(); // Need to stone the copy before reading
|
||||
stone(b2); // Need to stone the copy before reading
|
||||
assertEqual(b2.length, originalLength, "Copy should have same length");
|
||||
assertEqual(b2.read_text(0), "Test", "First text should match");
|
||||
});
|
||||
@@ -310,7 +315,7 @@ test("Large blob handling", function() {
|
||||
}
|
||||
|
||||
assertEqual(b.length, testSize, "Should have " + testSize + " bits");
|
||||
b.stone();
|
||||
stone(b);
|
||||
|
||||
// Verify pattern
|
||||
assertEqual(b.read_logical(0), true, "Bit 0 should be true");
|
||||
@@ -372,7 +377,7 @@ test("Non-stone blob read methods should throw", function() {
|
||||
test("Empty text write and read", function() {
|
||||
var b = new Blob();
|
||||
b.write_text("");
|
||||
b.stone();
|
||||
stone(b);
|
||||
assertEqual(b.read_text(0), "", "Empty string should round-trip");
|
||||
});
|
||||
|
||||
@@ -380,7 +385,7 @@ test("Empty text write and read", function() {
|
||||
test("Invalid read positions", function() {
|
||||
var b = new Blob();
|
||||
b.write_number(42);
|
||||
b.stone();
|
||||
stone(b);
|
||||
|
||||
var threw = false;
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user