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(); }); });