UNPKG

payload

Version:

Node, React, Headless CMS and Application Framework built on Next.js

120 lines (119 loc) 4.84 kB
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