From: Lady Date: Sun, 19 Nov 2023 16:05:03 +0000 (-0500) Subject: Move isConcatSpreadable[Object] into object.js X-Git-Url: https://git.ladys.computer/Pisces/commitdiff_plain/beab7268e7673b036222e64aac924f850e2b976e?ds=inline;hp=0fb1e53a1e78a6bf490cd95cf92a744d3ac6171f Move isConcatSpreadable[Object] into object.js This is an object test which is not *necessarily* about collections. --- diff --git a/collection.js b/collection.js index 03326a6..d340709 100644 --- a/collection.js +++ b/collection.js @@ -8,6 +8,7 @@ // file, You can obtain one at . import { call, createCallableFunction } from "./function.js"; +import { isConcatSpreadableObject } from "./object.js"; import { toIndex, type } from "./value.js"; const { prototype: arrayPrototype } = Array; @@ -193,7 +194,6 @@ export const indices = createCallableFunction( "indices", ); - /** * Returns whether the provided object is a collection. * @@ -215,31 +215,13 @@ export const isCollection = ($) => { } else { try { toIndex($.length); // will throw if `length` is not an index - return isConcatSpreadable($); + return isConcatSpreadableObject($); } catch { return false; } } }; -/** - * Returns whether the provided value is spreadable during array - * concatenation. - * - * This is also used to determine which things should be treated as - * collections. - */ -export const isConcatSpreadable = ($) => { - if (type($) !== "object") { - // The provided value is not an object. - return false; - } else { - // The provided value is an object. - const spreadable = $[Symbol.isConcatSpreadable]; - return spreadable !== undefined ? !!spreadable : isArray($); - } -}; - /** * Returns an iterator over the items in the provided value according * to the algorithm of `Array::values`. diff --git a/collection.test.js b/collection.test.js index 779b4ca..c066932 100644 --- a/collection.test.js +++ b/collection.test.js @@ -16,11 +16,7 @@ import { it, spy, } from "./dev-deps.js"; -import { - findIndexedEntry, - isCollection, - isConcatSpreadable, -} from "./collection.js"; +import { findIndexedEntry, isCollection } from "./collection.js"; describe("findIndexedEntry", () => { it("[[Call]] returns undefined if no matching entry exists", () => { @@ -144,40 +140,3 @@ describe("isCollection", () => { ); }); }); - -describe("isConcatSpreadable", () => { - it("[[Call]] returns false for primitives", () => { - assertStrictEquals(isConcatSpreadable("failure"), false); - }); - - it("[[Call]] returns false if [Symbol.isConcatSpreadable] is null or false", () => { - assertStrictEquals( - isConcatSpreadable( - Object.assign([], { [Symbol.isConcatSpreadable]: null }), - ), - false, - ); - assertStrictEquals( - isConcatSpreadable( - Object.assign([], { [Symbol.isConcatSpreadable]: false }), - ), - false, - ); - }); - - it("[[Call]] returns true if [Symbol.isConcatSpreadable] is undefined and the object is an array", () => { - assertStrictEquals( - isConcatSpreadable( - Object.assign([], { [Symbol.isConcatSpreadable]: undefined }), - ), - true, - ); - }); - - it("[[Call]] returns true if [Symbol.isConcatSpreadable] is true", () => { - assertStrictEquals( - isConcatSpreadable({ [Symbol.isConcatSpreadable]: true }), - true, - ); - }); -}); diff --git a/object.js b/object.js index 9c0c973..ee3d51d 100644 --- a/object.js +++ b/object.js @@ -14,6 +14,7 @@ import { toFunctionName, } from "./function.js"; import { + IS_CONCAT_SPREADABLE, ITERATOR, SPECIES, toLength, @@ -810,6 +811,32 @@ export const isArraylikeObject = ($) => { } }; +export const { + /** + * Returns whether the provided value is spreadable during array + * concatenation. + * + * This is also used to determine which things should be treated as + * collections. + */ + isConcatSpreadableObject, +} = (() => { + const { isArray } = Array; + + return { + isConcatSpreadableObject: ($) => { + if (type($) !== "object") { + // The provided value is not an object. + return false; + } else { + // The provided value is an object. + const spreadable = $[IS_CONCAT_SPREADABLE]; + return spreadable !== undefined ? !!spreadable : isArray($); + } + }, + }; +})(); + /** * Returns whether the provided object is extensible. * diff --git a/object.test.js b/object.test.js index fc62be3..a2e718b 100644 --- a/object.test.js +++ b/object.test.js @@ -35,6 +35,7 @@ import { hasOwnProperty, hasProperty, isArraylikeObject, + isConcatSpreadableObject, isExtensibleObject, isUnfrozenObject, isUnsealedObject, @@ -1588,6 +1589,62 @@ describe("isArraylikeObject", () => { }); }); +describe("isConcatSpreadableObject", () => { + it("[[Call]] returns false for primitives", () => { + assertStrictEquals(isConcatSpreadableObject("failure"), false); + }); + + it("[[Call]] returns false if [Symbol.isConcatSpreadable] is null or false", () => { + assertStrictEquals( + isConcatSpreadableObject( + Object.assign([], { [Symbol.isConcatSpreadable]: null }), + ), + false, + ); + assertStrictEquals( + isConcatSpreadableObject( + Object.assign([], { [Symbol.isConcatSpreadable]: false }), + ), + false, + ); + }); + + it("[[Call]] returns true if [Symbol.isConcatSpreadable] is undefined and the object is an array", () => { + assertStrictEquals( + isConcatSpreadableObject( + Object.assign([], { [Symbol.isConcatSpreadable]: undefined }), + ), + true, + ); + }); + + it("[[Call]] returns true if [Symbol.isConcatSpreadable] is true", () => { + assertStrictEquals( + isConcatSpreadableObject({ [Symbol.isConcatSpreadable]: true }), + true, + ); + }); + + it("[[Construct]] throws an error", () => { + assertThrows(() => new isConcatSpreadableObject({})); + }); + + describe(".length", () => { + it("[[Get]] returns the correct length", () => { + assertStrictEquals(isConcatSpreadableObject.length, 1); + }); + }); + + describe(".name", () => { + it("[[Get]] returns the correct name", () => { + assertStrictEquals( + isConcatSpreadableObject.name, + "isConcatSpreadableObject", + ); + }); + }); +}); + describe("isExtensibleObject", () => { it("[[Call]] returns true for extensible objects", () => { assertStrictEquals(isExtensibleObject({}), true);