+ createProxyConstructor.name,
+ "createProxyConstructor",
+ );
+ });
+ });
+
+ describe("~", () => {
+ it("[[Call]] throws an error", () => {
+ assertThrows(() => {
+ createProxyConstructor({})();
+ });
+ });
+
+ it("[[Construct]] produces a proxy", () => {
+ const obj = {};
+ const proxyConstructor = createProxyConstructor({
+ get(O, P, Receiver) {
+ if (P === "etaoin") {
+ return Reflect.get(O, P, Receiver) ?? "success";
+ } else {
+ return Reflect.get(O, P, Receiver);
+ }
+ },
+ }, function () {
+ return obj;
+ });
+ const proxy = new proxyConstructor();
+ assertStrictEquals(proxy.etaoin, "success");
+ obj.etaoin = "shrdlu";
+ assertStrictEquals(proxy.etaoin, "shrdlu");
+ });
+
+ it("[[Construct]] receives the expected new.target", () => {
+ const constructor = function Constructor() {
+ return { name: new.target.name };
+ };
+ assertStrictEquals(
+ new (createProxyConstructor({}, constructor))().name,
+ "Constructor",
+ );
+ assertStrictEquals(
+ new (createProxyConstructor(
+ {},
+ constructor,
+ function NewTarget() {},
+ ))().name,
+ "NewTarget",
+ );
+ });
+ });
+
+ describe("~length", () => {
+ it("[[GetOwnProperty]] has the correct descriptor", () => {
+ assertEquals(
+ Object.getOwnPropertyDescriptor(
+ createProxyConstructor({}),
+ "length",
+ ),
+ {
+ configurable: true,
+ enumerable: false,
+ value: 1,
+ writable: false,
+ },
+ );
+ });
+ });
+
+ describe("~name", () => {
+ it("[[GetOwnProperty]] has the correct descriptor", () => {
+ assertEquals(
+ Object.getOwnPropertyDescriptor(
+ createProxyConstructor({}),
+ "name",
+ ),
+ {
+ configurable: true,
+ enumerable: false,
+ value: "ObjectProxy",
+ writable: false,
+ },
+ );
+ });
+ });
+
+ describe("~prototype", () => {
+ it("[[GetOwnProperty]] has the correct descriptor", () => {
+ assertEquals(
+ Object.getOwnPropertyDescriptor(
+ createProxyConstructor({}),
+ "prototype",
+ ),
+ {
+ configurable: false,
+ enumerable: false,
+ value: undefined,
+ writable: false,
+ },
+ );
+ });
+ });
+
+ describe("~revocable", () => {
+ it("[[Call]] produces a revocable proxy", () => {
+ const obj = {};
+ const proxyConstructor = createProxyConstructor({
+ get(O, P, Receiver) {
+ if (P === "etaoin") {
+ return Reflect.get(O, P, Receiver) ?? "success";
+ } else {
+ return Reflect.get(O, P, Receiver);
+ }
+ },
+ }, function () {
+ return obj;
+ });
+ const { proxy, revoke } = proxyConstructor.revocable();
+ assertStrictEquals(proxy.etaoin, "success");
+ obj.etaoin = "shrdlu";
+ assertStrictEquals(proxy.etaoin, "shrdlu");
+ revoke();
+ assertThrows(() => proxy.etaoin);
+ });
+
+ it("[[Call]] receives the expected new.target", () => {
+ const constructor = function Constructor() {
+ return { name: new.target.name };
+ };
+ assertStrictEquals(
+ createProxyConstructor({}, constructor).revocable().proxy.name,
+ "Constructor",
+ );
+ assertStrictEquals(
+ createProxyConstructor(
+ {},
+ constructor,
+ function NewTarget() {},
+ ).revocable().proxy.name,
+ "NewTarget",
+ );
+ });
+
+ it("[[Construct]] throws an error", () => {
+ assertThrows(() => new (createProxyConstructor({})).revocable());
+ });
+
+ it("[[GetOwnProperty]] has the correct descriptor", () => {
+ const proxyConstructor = createProxyConstructor({});
+ assertEquals(
+ Object.getOwnPropertyDescriptor(proxyConstructor, "revocable"),
+ {
+ configurable: true,
+ enumerable: false,
+ value: proxyConstructor.revocable,
+ writable: true,
+ },