]> Lady’s Gitweb - Pisces/blobdiff - object.test.js
Polish binary.js a little bit.
[Pisces] / object.test.js
index da890d38f3aa5cd1f7152706d5b02bd7085a4650..efef4d84c5581a20e415f094c68729ea339489ea 100644 (file)
@@ -22,12 +22,255 @@ import {
   defineOwnProperties,
   deleteOwnProperty,
   frozenCopy,
+  getMethod,
+  getOwnPropertyKeys,
+  getPropertyValue,
+  hasProperty,
+  LazyLoader,
   PropertyDescriptor,
   setPropertyValue,
   toObject,
   toPropertyKey,
 } from "./object.js";
 
+describe("LazyLoader", () => {
+  const symbol = Symbol();
+  const prototype = {};
+  const etaoinMethod = spy(() => "success");
+  const shrdluMethod = spy(() => "success");
+  const cmfwypMethod = spy(() => "success");
+  const vbgkqjMethod = spy(() => "success");
+  const methodsObject = Object.create(
+    prototype,
+    {
+      etaoin: {
+        configurable: false,
+        enumerable: true,
+        value: etaoinMethod,
+        writable: false,
+      },
+      shrdlu: {
+        configurable: true,
+        enumerable: false,
+        value: shrdluMethod,
+        writable: false,
+      },
+      cmfwyp: {
+        configurable: true,
+        enumerable: false,
+        get() {
+          return cmfwypMethod;
+        },
+      },
+      vbgkqj: {
+        configurable: false,
+        enumerable: true,
+        get() {
+          return vbgkqjMethod;
+        },
+        set(_) {},
+      },
+      xzfiflffffi: { configurable: true, enumerable: false, set(_) {} },
+      [symbol]: {
+        configurable: true,
+        enumerable: false,
+        value: "failure",
+        writable: true,
+      },
+    },
+  );
+
+  it("[[Construct]] creates a new object which inherits from the correct prototype", () => {
+    assertStrictEquals(
+      Object.getPrototypeOf(new LazyLoader(methodsObject)),
+      prototype,
+    );
+  });
+
+  it("[[Construct]] creates a new object with the desired properties", () => {
+    assertEquals(
+      Reflect.ownKeys(new LazyLoader(methodsObject)),
+      ["etaoin", "shrdlu", "cmfwyp", "vbgkqj", "xzfiflffffi", symbol],
+    );
+  });
+
+  it("[[Construct]] creates a new object with configurable properties", () => {
+    assertEquals(
+      Object.fromEntries(
+        function* (ll) {
+          for (const key of Reflect.ownKeys(ll)) {
+            yield [
+              key,
+              Object.getOwnPropertyDescriptor(ll, key).configurable,
+            ];
+          }
+        }(new LazyLoader(methodsObject)),
+      ),
+      {
+        etaoin: true,
+        shrdlu: true,
+        cmfwyp: true,
+        vbgkqj: true,
+        xzfiflffffi: true,
+        [symbol]: true,
+      },
+    );
+  });
+
+  it("[[Construct]] creates a new object with the correct enumerability", () => {
+    assertEquals(
+      Object.fromEntries(
+        function* (ll) {
+          for (const key of Reflect.ownKeys(ll)) {
+            yield [
+              key,
+              Object.getOwnPropertyDescriptor(ll, key).enumerable,
+            ];
+          }
+        }(new LazyLoader(methodsObject)),
+      ),
+      {
+        etaoin: true,
+        shrdlu: false,
+        cmfwyp: false,
+        vbgkqj: true,
+        xzfiflffffi: false,
+        [symbol]: false,
+      },
+    );
+  });
+
+  it("[[Construct]] creates a new object with defined getters", () => {
+    assertEquals(
+      Object.fromEntries(
+        function* (ll) {
+          for (const key of Reflect.ownKeys(ll)) {
+            yield [
+              key,
+              Object.getOwnPropertyDescriptor(ll, key).get !== void {},
+            ];
+          }
+        }(new LazyLoader(methodsObject)),
+      ),
+      {
+        etaoin: true,
+        shrdlu: true,
+        cmfwyp: true,
+        vbgkqj: true,
+        xzfiflffffi: true,
+        [symbol]: true,
+      },
+    );
+  });
+
+  it("[[Construct]] creates a new object with defined setters for writable properties only", () => {
+    assertEquals(
+      Object.fromEntries(
+        function* (ll) {
+          for (const key of Reflect.ownKeys(ll)) {
+            yield [
+              key,
+              Object.getOwnPropertyDescriptor(ll, key).set !== void {},
+            ];
+          }
+        }(new LazyLoader(methodsObject)),
+      ),
+      {
+        etaoin: false,
+        shrdlu: false,
+        cmfwyp: false,
+        vbgkqj: false,
+        xzfiflffffi: false,
+        [symbol]: true,
+      },
+    );
+  });
+
+  describe("[[Construct]] creates a new object with correct getter behaviour", () => {
+    const ll = new LazyLoader(methodsObject);
+    ll.etaoin;
+    assertEquals(
+      Object.getOwnPropertyDescriptor(ll, "etaoin"),
+      {
+        configurable: false,
+        enumerable: true,
+        value: "success",
+        writable: false,
+      },
+    );
+    assertSpyCalls(etaoinMethod, 1);
+    assertSpyCall(etaoinMethod, 0, {
+      args: [],
+      self: ll,
+      returned: "success",
+    });
+    ll.shrdlu;
+    assertEquals(
+      Object.getOwnPropertyDescriptor(ll, "shrdlu"),
+      {
+        configurable: true,
+        enumerable: false,
+        value: "success",
+        writable: false,
+      },
+    );
+    assertSpyCalls(shrdluMethod, 1);
+    assertSpyCall(shrdluMethod, 0, {
+      args: [],
+      self: ll,
+      returned: "success",
+    });
+    ll.cmfwyp;
+    assertEquals(
+      Object.getOwnPropertyDescriptor(ll, "cmfwyp"),
+      {
+        configurable: true,
+        enumerable: false,
+        value: "success",
+        writable: false,
+      },
+    );
+    assertSpyCalls(cmfwypMethod, 1);
+    assertSpyCall(cmfwypMethod, 0, {
+      args: [],
+      self: ll,
+      returned: "success",
+    });
+    ll.vbgkqj;
+    assertEquals(
+      Object.getOwnPropertyDescriptor(ll, "vbgkqj"),
+      {
+        configurable: false,
+        enumerable: true,
+        value: "success",
+        writable: false,
+      },
+    );
+    assertSpyCalls(vbgkqjMethod, 1);
+    assertSpyCall(vbgkqjMethod, 0, {
+      args: [],
+      self: ll,
+      returned: "success",
+    });
+    assertThrows(() => ll.xzfiflffffi);
+    assertThrows(() => ll[symbol]);
+  });
+
+  describe("[[Construct]] creates a new object with correct setter behaviour", () => {
+    const ll = new LazyLoader(methodsObject);
+    ll[symbol] = "success";
+    assertEquals(
+      Object.getOwnPropertyDescriptor(ll, symbol),
+      {
+        configurable: true,
+        enumerable: false,
+        value: "success",
+        writable: true,
+      },
+    );
+  });
+});
+
 describe("PropertyDescriptor", () => {
   it("[[Construct]] creates a new PropertyDescriptor", () => {
     assertStrictEquals(
@@ -636,6 +879,80 @@ describe("frozenCopy", () => {
   });
 });
 
+describe("getMethod", () => {
+  it("[[Call]] gets a method", () => {
+    const method = () => {};
+    assertStrictEquals(getMethod({ method }, "method"), method);
+  });
+
+  it("[[Call]] works for values coercible to objects", () => {
+    assertEquals(getMethod("", "toString"), String.prototype.toString);
+  });
+
+  it("[[Call]] throws for null and undefined", () => {
+    assertThrows(() => getMethod(null, "valueOf"));
+    assertThrows(() => getMethod(undefined, "valueOf"));
+  });
+
+  it("[[Call]] throws if the resulting value isn’t callable", () => {
+    assertThrows(() => getMethod({ "failure": true }, "failure"));
+  });
+});
+
+describe("getOwnPropertyKeys", () => {
+  it("[[Call]] gets own (but not inherited) property keys", () => {
+    assertEquals(getOwnPropertyKeys({ success: true }), ["success"]);
+  });
+
+  it("[[Call]] works for values coercible to objects", () => {
+    assertEquals(getOwnPropertyKeys("foo"), ["0", "1", "2", "length"]);
+  });
+
+  it("[[Call]] throws for null and undefined", () => {
+    assertThrows(() => getOwnPropertyKeys(null));
+    assertThrows(() => getOwnPropertyKeys(undefined));
+  });
+});
+
+describe("getPropertyValue", () => {
+  it("[[Call]] gets property values on the provided object", () => {
+    assertStrictEquals(
+      getPropertyValue({ success: true }, "success"),
+      true,
+    );
+  });
+
+  it("[[Call]] works for values coercible to objects", () => {
+    assertStrictEquals(
+      getPropertyValue("", "toString"),
+      String.prototype.toString,
+    );
+  });
+
+  it("[[Call]] throws for null and undefined", () => {
+    assertThrows(() => getPropertyValue(null, "valueOf"));
+    assertThrows(() => getPropertyValue(undefined, "valueOf"));
+  });
+});
+
+describe("hasProperty", () => {
+  it("[[Call]] gets whether a property exists on the provided object", () => {
+    assertStrictEquals(
+      hasProperty({ success: "etaoin" }, "success"),
+      true,
+    );
+  });
+
+  it("[[Call]] works for values coercible to objects", () => {
+    assertStrictEquals(hasProperty("", "toString"), true);
+  });
+
+  it("[[Call]] throws for null and undefined", () => {
+    assertThrows(() => hasProperty(null, "valueOf"));
+    assertThrows(() => hasProperty(undefined, "valueOf"));
+  });
+});
+
 describe("setPropertyValue", () => {
   it("[[Call]] sets the provided property on the provided object", () => {
     const obj = {};
@@ -696,9 +1013,9 @@ describe("toObject", () => {
     assertStrictEquals(toObject(obj), obj);
   });
 
-  it("returns a new object for nullish values", () => {
-    assertEquals(toObject(null), {});
-    assertEquals(toObject(void {}), {});
+  it("throws for nullish values", () => {
+    assertThrows(() => toObject(null));
+    assertThrows(() => toObject(void {}));
   });
 
   it("returns a wrapper object for other primitives", () => {
This page took 0.038578 seconds and 4 git commands to generate.