test("length is 2", () => { expect(Proxy.revocable).toHaveLength(2); }); describe("errors", () => { test("constructor argument count", () => { expect(() => { Proxy.revocable(); }).toThrowWithMessage( TypeError, "Expected target argument of Proxy constructor to be object, got undefined" ); expect(() => { Proxy.revocable({}); }).toThrowWithMessage( TypeError, "Expected handler argument of Proxy constructor to be object, got undefined" ); }); test("constructor requires objects", () => { expect(() => { Proxy.revocable(1, {}); }).toThrowWithMessage( TypeError, "Expected target argument of Proxy constructor to be object, got 1" ); expect(() => { Proxy.revocable({}, 1); }).toThrowWithMessage( TypeError, "Expected handler argument of Proxy constructor to be object, got 1" ); }); }); describe("normal behavior", () => { test("returns object with 'proxy' and 'revoke' properties", () => { const revocable = Proxy.revocable( {}, { get() { return 42; }, } ); expect(typeof revocable).toBe("object"); expect(Object.getPrototypeOf(revocable)).toBe(Object.prototype); expect(revocable.hasOwnProperty("proxy")).toBeTrue(); expect(revocable.hasOwnProperty("revoke")).toBeTrue(); expect(typeof revocable.revoke).toBe("function"); // Can't `instanceof Proxy`, but this should do the trick :^) expect(revocable.proxy.foo).toBe(42); }); test("'revoke' function revokes Proxy", () => { const revocable = Proxy.revocable({}, {}); expect(revocable.proxy.foo).toBeUndefined(); expect(revocable.revoke()).toBeUndefined(); expect(() => { revocable.proxy.foo; }).toThrowWithMessage(TypeError, "An operation was performed on a revoked Proxy object"); }); test("'revoke' called multiple times is a noop", () => { const revocable = Proxy.revocable({}, {}); expect(revocable.revoke()).toBeUndefined(); expect(revocable.revoke()).toBeUndefined(); }); });