Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 QA (push) Failing after 34s
Build & Deploy / 🏗️ Build (push) Has started running
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Smoke Test (push) Has been cancelled
Build & Deploy / ⚡ Lighthouse (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
120 lines
4.7 KiB
Plaintext
120 lines
4.7 KiB
Plaintext
import { describe, expect, it } from 'vitest';
|
|
import { isolateObjectProperty } from './isolateObjectProperty.js';
|
|
describe('isolateObjectProperty', ()=>{
|
|
describe('basic isolation behavior', ()=>{
|
|
it('should isolate specified property from the original object', ()=>{
|
|
const original = {
|
|
a: 1,
|
|
b: 2
|
|
};
|
|
const proxy = isolateObjectProperty(original, 'a');
|
|
proxy.a = 100;
|
|
expect(proxy.a).toBe(100);
|
|
expect(original.a).toBe(1); // Original unchanged
|
|
});
|
|
it('should share non-isolated properties with the original object', ()=>{
|
|
const original = {
|
|
a: 1,
|
|
b: 2
|
|
};
|
|
const proxy = isolateObjectProperty(original, 'a');
|
|
proxy.b = 200;
|
|
expect(proxy.b).toBe(200);
|
|
expect(original.b).toBe(200); // Original also changed
|
|
});
|
|
it('should support isolating multiple properties', ()=>{
|
|
const original = {
|
|
a: 1,
|
|
b: 2,
|
|
c: 3
|
|
};
|
|
const proxy = isolateObjectProperty(original, [
|
|
'a',
|
|
'b'
|
|
]);
|
|
proxy.a = 100;
|
|
proxy.b = 200;
|
|
expect(proxy.a).toBe(100);
|
|
expect(proxy.b).toBe(200);
|
|
expect(original.a).toBe(1);
|
|
expect(original.b).toBe(2);
|
|
});
|
|
it('should support deleting isolated properties', ()=>{
|
|
const original = {
|
|
a: 1,
|
|
b: 2
|
|
};
|
|
const proxy = isolateObjectProperty(original, 'a');
|
|
delete proxy.a;
|
|
expect('a' in proxy).toBe(false);
|
|
expect('a' in original).toBe(true); // Original still has it
|
|
});
|
|
it('should support "in" operator for isolated properties', ()=>{
|
|
const original = {
|
|
a: 1,
|
|
b: 2
|
|
};
|
|
const proxy = isolateObjectProperty(original, 'a');
|
|
expect('a' in proxy).toBe(true);
|
|
expect('b' in proxy).toBe(true);
|
|
delete proxy.a;
|
|
expect('a' in proxy).toBe(false);
|
|
});
|
|
});
|
|
describe('private field access (Node 24+ compatibility)', ()=>{
|
|
/**
|
|
* Class with private fields to test that the proxy correctly handles
|
|
* getters/setters that access private fields (Node 24+ compatibility).
|
|
*/ class ObjectWithPrivateFields {
|
|
#privateValue;
|
|
constructor(value){
|
|
this.#privateValue = value;
|
|
}
|
|
get value() {
|
|
return this.#privateValue;
|
|
}
|
|
set value(newValue) {
|
|
this.#privateValue = newValue;
|
|
}
|
|
}
|
|
it('should allow reading properties via getters that access private fields when not isolated', ()=>{
|
|
const original = new ObjectWithPrivateFields('secret');
|
|
expect(original.value).toBe('secret');
|
|
});
|
|
it('should allow reading properties via getters that access private fields', ()=>{
|
|
const original = new ObjectWithPrivateFields('secret');
|
|
const proxy = isolateObjectProperty(original, 'nonExistentKey');
|
|
// This would throw "Cannot read private member" if receiver is wrong
|
|
expect(proxy.value).toBe('secret');
|
|
});
|
|
it('should allow writing properties via setters that access private fields', ()=>{
|
|
const original = new ObjectWithPrivateFields('secret');
|
|
const proxy = isolateObjectProperty(original, 'nonExistentKey');
|
|
// This would throw "Cannot write private member" if receiver is wrong
|
|
proxy.value = 'updated';
|
|
expect(proxy.value).toBe('updated');
|
|
expect(original.value).toBe('updated');
|
|
});
|
|
it('should work with Headers-like objects (simulating Request.headers)', ()=>{
|
|
// Simulate a Request-like object with headers
|
|
class MockRequest {
|
|
#headers;
|
|
constructor(){
|
|
this.#headers = new Headers({
|
|
'content-type': 'application/json'
|
|
});
|
|
}
|
|
get headers() {
|
|
return this.#headers;
|
|
}
|
|
}
|
|
const request = new MockRequest();
|
|
const proxy = isolateObjectProperty(request, 'nonExistentKey');
|
|
// This simulates what happens in createLocalReq when checking req.headers
|
|
expect(proxy.headers).toBeInstanceOf(Headers);
|
|
expect(proxy.headers.get('content-type')).toBe('application/json');
|
|
});
|
|
});
|
|
});
|
|
|
|
//# sourceMappingURL=isolateObjectProperty.spec.js.map |