*
* ※ This is effectively an alias for the `Symbol::description`
* getter.
+ *
+ * ☡ This function throws if the provided argument is not a symbol.
*/
export const getSymbolDescription = createCallableFunction(
getOwnPropertyDescriptor(Symbol.prototype, "description").get,
"getSymbolDescription",
);
+
+/**
+ * Returns a string representation of the provided symbol.
+ *
+ * ※ Use `getSymbolDescription` instead if you just want the text
+ * description of a symbol.
+ *
+ * ※ This is effectively an alias for the `Symbol::toString`.
+ *
+ * ☡ This function throws if the provided argument is not a symbol.
+ */
+export const symbolToString = createCallableFunction(
+ Symbol.prototype.toString,
+ "symbolToString",
+);
+
+/**
+ * Returns the value of the provided symbol.
+ *
+ * ※ This is effectively an alias for the `Symbol::valueOf`.
+ *
+ * ☡ This function throws if the provided argument is not a symbol and
+ * does not have a `[[SymbolData]]` slot.
+ */
+export const symbolValue = createCallableFunction(
+ Symbol.prototype.valueOf,
+ "symbolValue",
+);
describe,
it,
} from "./dev-deps.js";
-import { getSymbolDescription } from "./symbol.js";
+import {
+ getSymbolDescription,
+ symbolToString,
+ symbolValue,
+} from "./symbol.js";
describe("getSymbolDescription", () => {
it("[[Call]] returns undefined when the symbol has no description", () => {
);
});
- it("[[Call]] returns the empty string when the symbol has an empty description", () => {
- assertStrictEquals(getSymbolDescription(Symbol("")), "");
- });
-
it("[[Construct]] throws an error", () => {
assertThrows(() => new getSymbolDescription(Symbol()));
});
});
});
});
+
+describe("symbolToString", () => {
+ it('[[Call]] returns "Symbol()" when the symbol has no description', () => {
+ assertStrictEquals(symbolToString(Symbol()), "Symbol()");
+ });
+
+ it('[[Call]] returns "Symbol()" when the symbol has an empty description', () => {
+ assertStrictEquals(symbolToString(Symbol("")), "Symbol()");
+ });
+
+ it('[[Call]] returns "Symbol()" wrapping the description', () => {
+ assertStrictEquals(
+ symbolToString(Symbol("etaoin")),
+ "Symbol(etaoin)",
+ );
+ });
+
+ it("[[Construct]] throws an error", () => {
+ assertThrows(() => new symbolToString(Symbol()));
+ });
+
+ describe(".name", () => {
+ it("[[Get]] returns the correct name", () => {
+ assertStrictEquals(
+ symbolToString.name,
+ "symbolToString",
+ );
+ });
+ });
+});
+
+describe("symbolValue", () => {
+ it("[[Call]] returns the value of a symbol", () => {
+ const symbol = Symbol();
+ assertStrictEquals(symbolValue(symbol), symbol);
+ });
+
+ it("[[Call]] returns the value of a symbol wrapper", () => {
+ const symbol = Symbol();
+ assertStrictEquals(symbolValue(new Object(symbol)), symbol);
+ });
+
+ it("[[Call]] returns the value of a symbol subclass", () => {
+ class SymbolExtension extends Symbol {
+ constructor(symbol) {
+ return Object.setPrototypeOf(
+ new Object(symbol),
+ SymbolExtension.prototype,
+ );
+ }
+ }
+ const symbol = Symbol();
+ assertStrictEquals(
+ symbolValue(new SymbolExtension(symbol)),
+ symbol,
+ );
+ });
+
+ it("[[Construct]] throws an error", () => {
+ assertThrows(() => new symbolValue(Symbol()));
+ });
+
+ describe(".name", () => {
+ it("[[Get]] returns the correct name", () => {
+ assertStrictEquals(
+ symbolValue.name,
+ "symbolValue",
+ );
+ });
+ });
+});