From: Lady <redacted>
Date: Sat, 23 Jul 2022 19:20:43 +0000 (-0700)
Subject: Add isArraylikeObject
X-Git-Tag: 0.1.1
X-Git-Url: https://git.ladys.computer/Pisces/commitdiff_plain/a63ba5294bd5cc847a192f6737bc386bfe7187f8?ds=inline;hp=f0b1fb387c82349c2db70ae265dc6910b830a906

Add isArraylikeObject

Also renames lengthOfArrayLike 🔜 lengthOfArraylike.
---

diff --git a/collection.js b/collection.js
index 20b6fef..38b048c 100644
--- a/collection.js
+++ b/collection.js
@@ -188,6 +188,20 @@ export const isArrayIndexString = ($) => {
   }
 };
 
+/** Returns whether the provided value is arraylike. */
+export const isArraylikeObject = ($) => {
+  if (type($) !== "object") {
+    return false;
+  } else {
+    try {
+      lengthOfArraylike($); // throws if not arraylike
+      return true;
+    } catch {
+      return false;
+    }
+  }
+};
+
 /**
  * Returns whether the provided object is a collection.
  *
@@ -262,7 +276,7 @@ export const items = makeCallable(Array.prototype.values);
  * This can produce larger lengths than can actually be stored in
  * arrays, because no such restrictions exist on arraylike methods.
  */
-export const lengthOfArrayLike = ({ length }) => toLength(length);
+export const lengthOfArraylike = ({ length }) => toLength(length);
 
 /**
  * Returns the result of mapping the provided value with the provided
diff --git a/collection.test.js b/collection.test.js
index b490572..bdded97 100644
--- a/collection.test.js
+++ b/collection.test.js
@@ -21,10 +21,11 @@ import {
   canonicalNumericIndexString,
   findIndexedEntry,
   isArrayIndexString,
+  isArraylikeObject,
   isCollection,
   isConcatSpreadable,
   isIntegerIndexString,
-  lengthOfArrayLike,
+  lengthOfArraylike,
   toIndex,
   toLength,
 } from "./collection.js";
@@ -163,6 +164,39 @@ describe("isArrayIndexString", () => {
   });
 });
 
+describe("isArraylikeObject", () => {
+  it("[[Call]] returns false for primitives", () => {
+    assertStrictEquals(isArraylikeObject("failure"), false);
+  });
+
+  it("[[Call]] returns false if length throws", () => {
+    assertStrictEquals(
+      isArraylikeObject({
+        get length() {
+          throw void {};
+        },
+      }),
+      false,
+    );
+  });
+
+  it("[[Call]] returns false if length is not a number and cannot be converted to one", () => {
+    assertStrictEquals(isArraylikeObject({ length: 1n }), false);
+  });
+
+  it("[[Call]] returns true if length is convertable to a number", () => {
+    assertStrictEquals(isArraylikeObject({ length: -0 }), true);
+    assertStrictEquals(isArraylikeObject({ length: 1 }), true);
+    assertStrictEquals(isArraylikeObject({ length: -1.25 }), true);
+    assertStrictEquals(
+      isArraylikeObject({ length: 9007199254740992 }),
+      true,
+    );
+    assertStrictEquals(isArraylikeObject({ length: Infinity }), true);
+    assertStrictEquals(isArraylikeObject({ length: "success" }), true);
+  });
+});
+
 describe("isCollection", () => {
   it("[[Call]] returns false for primitives", () => {
     assertStrictEquals(isCollection("failure"), false);
@@ -310,37 +344,37 @@ describe("isIntegerIndexString", () => {
   });
 });
 
-describe("lengthOfArrayLike", () => {
+describe("lengthOfArraylike", () => {
   it("[[Call]] returns the length", () => {
     assertStrictEquals(
-      lengthOfArrayLike({ length: 9007199254740991 }),
+      lengthOfArraylike({ length: 9007199254740991 }),
       9007199254740991,
     );
   });
 
   it("[[Call]] returns a non·nan result", () => {
-    assertStrictEquals(lengthOfArrayLike({ length: NaN }), 0);
-    assertStrictEquals(lengthOfArrayLike({ length: "failure" }), 0);
+    assertStrictEquals(lengthOfArraylike({ length: NaN }), 0);
+    assertStrictEquals(lengthOfArraylike({ length: "failure" }), 0);
   });
 
   it("[[Call]] returns an integral result", () => {
-    assertStrictEquals(lengthOfArrayLike({ length: 0.25 }), 0);
-    assertStrictEquals(lengthOfArrayLike({ length: 1.1 }), 1);
+    assertStrictEquals(lengthOfArraylike({ length: 0.25 }), 0);
+    assertStrictEquals(lengthOfArraylike({ length: 1.1 }), 1);
   });
 
   it("[[Call]] returns a result greater than or equal to zero", () => {
-    assertStrictEquals(lengthOfArrayLike({ length: -0 }), 0);
-    assertStrictEquals(lengthOfArrayLike({ length: -1 }), 0);
-    assertStrictEquals(lengthOfArrayLike({ length: -Infinity }), 0);
+    assertStrictEquals(lengthOfArraylike({ length: -0 }), 0);
+    assertStrictEquals(lengthOfArraylike({ length: -1 }), 0);
+    assertStrictEquals(lengthOfArraylike({ length: -Infinity }), 0);
   });
 
   it("[[Call]] returns a result less than 2 ** 53", () => {
     assertStrictEquals(
-      lengthOfArrayLike({ length: 9007199254740992 }),
+      lengthOfArraylike({ length: 9007199254740992 }),
       9007199254740991,
     );
     assertStrictEquals(
-      lengthOfArrayLike({ length: Infinity }),
+      lengthOfArraylike({ length: Infinity }),
       9007199254740991,
     );
   });