diff --git a/README.md b/README.md index 8467a52..accf261 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Structured Objects is lightweight and powerful library for handling object in Ja - `toAdded`: Returns a copy of the original object graph with a received node added. - `update`: Updates a node in the object graph. - `toUpdated`: Returns a copy of the original object graph with a received node updated. -- `remove`: Removes a node to the object graph. +- `remove`: Removes a node from the object graph. - `toRemoved`: Returns a copy of the original object graph with a received node removed. - `valuesOf`: Returns all values of the provided property. - `match`: Returns all nodes that match with the provided matcher. diff --git a/src/object-graph/index.test.ts b/src/object-graph/index.test.ts index 1643f4f..28ab643 100644 --- a/src/object-graph/index.test.ts +++ b/src/object-graph/index.test.ts @@ -1,4 +1,4 @@ -import { expect, describe, test } from "vitest"; +import { expect, describe, test, vi } from "vitest"; import { ObjectGraph } from "."; import { shirtsMock, extraShirtsMock, type Shirt } from "./index.mock"; @@ -17,12 +17,14 @@ describe("length", () => { }); describe("get()", () => { - test("throws an error when there is no node with the provided key in the object graph", () => { + test("logs an error when there is no node with the provided key in the object graph", () => { + const consoleErrorSpy = vi.spyOn(console, "error"); const shirtsObjectGraph = new ObjectGraph(shirtsMock, (shirt) => shirt.sku); - expect(() => { - shirtsObjectGraph.get("9"); - }).toThrowError(); + const returnedNode = shirtsObjectGraph.get("9"); + + expect(consoleErrorSpy).toHaveBeenCalled(); + expect(returnedNode).toBeUndefined(); }); test("get a node of the object graph", () => { @@ -30,8 +32,8 @@ describe("get()", () => { const returnedNode = shirtsObjectGraph.get(shirtsMock[0].sku); - expect(returnedNode.color).toBe(shirtsMock[0].color); - expect(returnedNode.size).toBe(shirtsMock[0].size); + expect(returnedNode?.color).toBe(shirtsMock[0].color); + expect(returnedNode?.size).toBe(shirtsMock[0].size); }); }); @@ -57,12 +59,13 @@ describe("copy()", () => { }); describe("add()", () => { - test("throws an error when a node with the same key already exists in the object graph", () => { + test("logs an error when a node with the same key already exists in the object graph", () => { + const consoleErrorSpy = vi.spyOn(console, "error"); const shirtsObjectGraph = new ObjectGraph(shirtsMock, (shirt) => shirt.sku); - expect(() => { - shirtsObjectGraph.add(shirtsMock[0]); - }).toThrowError(); + shirtsObjectGraph.add(shirtsMock[0]); + + expect(consoleErrorSpy).toHaveBeenCalled(); }); test("adds a node to the object graph", () => { @@ -76,39 +79,45 @@ describe("add()", () => { describe("toAdded()", () => { test("get a copy of the original object graph with a received node added", () => { + const consoleErrorSpy = vi.spyOn(console, "error"); const shirtsObjectGraph = new ObjectGraph([], (shirt) => shirt.sku); const copiedShirtsObjectGraph = shirtsObjectGraph.toAdded(shirtsMock[0]); expect(shirtsObjectGraph.length).toBe(0); expect(copiedShirtsObjectGraph.length).toBe(1); - expect(() => { - shirtsObjectGraph.get("1"); - }).toThrowError(); - expect(() => { - copiedShirtsObjectGraph.get("1"); - }).not.toThrowError(); + + const returnedNodeFromCopy = copiedShirtsObjectGraph.get("1"); + + expect(consoleErrorSpy).not.toHaveBeenCalled(); + expect(returnedNodeFromCopy).toBeDefined(); + + const returnedNodeFromOriginal = shirtsObjectGraph.get("1"); + + expect(consoleErrorSpy).toHaveBeenCalled(); + expect(returnedNodeFromOriginal).toBeUndefined(); }); }); describe("update()", () => { - test("throws an error when there is no node with the same key in the object graph", () => { + test("logs an error when there is no node with the same key in the object graph", () => { + const consoleErrorSpy = vi.spyOn(console, "error"); const shirtsObjectGraph = new ObjectGraph(shirtsMock, (shirt) => shirt.sku); - expect(() => { - shirtsObjectGraph.update(extraShirtsMock[0]); - }).toThrowError(); + shirtsObjectGraph.update(extraShirtsMock[0]); + + expect(consoleErrorSpy).toHaveBeenCalled(); }); test("updates a node in the object graph", () => { const shirtToUpdate: Shirt = { sku: "1", color: "red", size: "large" }; const shirtsObjectGraph = new ObjectGraph(shirtsMock, (shirt) => shirt.sku); - expect(shirtsObjectGraph.get("1").size).toBe("small"); + expect(shirtsObjectGraph.get("1")?.size).toBe("small"); shirtsObjectGraph.update(shirtToUpdate); - expect(shirtsObjectGraph.get("1").size).toBe("large"); + expect(shirtsObjectGraph.get("1")?.size).toBe("large"); }); }); @@ -119,49 +128,61 @@ describe("toUpdated()", () => { const copiedShirtsObjectGraph = shirtsObjectGraph.toUpdated(shirtToUpdate); - expect(shirtsObjectGraph.get("1").size).toBe("small"); - expect(copiedShirtsObjectGraph.get("1").size).toBe("large"); + expect(shirtsObjectGraph.get("1")?.size).toBe("small"); + expect(copiedShirtsObjectGraph.get("1")?.size).toBe("large"); }); }); describe("remove()", () => { - test("throws an error when there is no node with the provided key in the object graph", () => { + test("logs an error when there is no node with the provided key in the object graph", () => { + const consoleErrorSpy = vi.spyOn(console, "error"); const shirtsObjectGraph = new ObjectGraph(shirtsMock, (shirt) => shirt.sku); - expect(() => { - shirtsObjectGraph.remove("9"); - }).toThrowError(); + const returnedNode = shirtsObjectGraph.remove("9"); + + expect(consoleErrorSpy).toHaveBeenCalled(); + expect(returnedNode).toBeUndefined(); }); - test("removes a node to the object graph", () => { + test("removes a node from the object graph", () => { + const consoleErrorSpy = vi.spyOn(console, "error"); const shirtsObjectGraph = new ObjectGraph(shirtsMock, (shirt) => shirt.sku); - expect(() => { - shirtsObjectGraph.get("1"); - }).not.toThrowError(); + const returnedNodeFromFirstAttempt = shirtsObjectGraph.get("1"); + + expect(consoleErrorSpy).not.toHaveBeenCalled(); + expect(returnedNodeFromFirstAttempt).toBeDefined(); shirtsObjectGraph.remove("1"); - expect(() => { - shirtsObjectGraph.get("1"); - }).toThrowError(); + expect(consoleErrorSpy).not.toHaveBeenCalled(); + + const returnedNodeFromSecondAttempt = shirtsObjectGraph.get("1"); + + expect(consoleErrorSpy).toHaveBeenCalled(); + expect(returnedNodeFromSecondAttempt).toBeUndefined(); }); }); describe("toRemoved()", () => { test("get a copy of the original object graph with a received node removed", () => { + const consoleErrorSpy = vi.spyOn(console, "error"); const shirtsObjectGraph = new ObjectGraph(shirtsMock, (shirt) => shirt.sku); const copiedShirtsObjectGraph = shirtsObjectGraph.toRemoved("1"); expect(shirtsObjectGraph.length).toBe(8); expect(copiedShirtsObjectGraph.length).toBe(7); - expect(() => { - shirtsObjectGraph.get("1"); - }).not.toThrowError(); - expect(() => { - copiedShirtsObjectGraph.get("1"); - }).toThrowError(); + + const returnedNodeFromOriginal = shirtsObjectGraph.get("1"); + + expect(consoleErrorSpy).not.toHaveBeenCalled(); + expect(returnedNodeFromOriginal).toBeDefined(); + + const returnedNodeFromCopy = copiedShirtsObjectGraph.get("1"); + + expect(consoleErrorSpy).toHaveBeenCalled(); + expect(returnedNodeFromCopy).toBeUndefined(); }); }); diff --git a/src/object-graph/index.ts b/src/object-graph/index.ts index a7b799c..918f16b 100644 --- a/src/object-graph/index.ts +++ b/src/object-graph/index.ts @@ -37,7 +37,7 @@ export class ObjectGraph> { } const nodeValue = this.nodes.get(nodeKey); if (!nodeValue) { - throw new Error("A node with this key does not exist in the object graph"); + console.error("A node with this key does not exist in the object graph"); } return nodeValue; } @@ -65,7 +65,7 @@ export class ObjectGraph> { } const nodeKey = this.keyExtractor(nodeValue); if (this.nodes.get(nodeKey)) { - throw new Error("A node with the same key already exists in the object graph"); + console.error("A node with the same key already exists in the object graph"); } this.nodes.set(nodeKey, nodeValue); } @@ -88,7 +88,7 @@ export class ObjectGraph> { } const nodeKey = this.keyExtractor(nodeValue); if (!this.nodes.get(nodeKey)) { - throw new Error("A node with the provided key does not exist in the object graph"); + console.error("A node with the provided key does not exist in the object graph"); } this.nodes.set(nodeKey, nodeValue); } @@ -103,7 +103,7 @@ export class ObjectGraph> { } /** - * @description Removes a node to the object graph. + * @description Removes a node from the object graph. */ public remove(nodeKey: string) { if (!nodeKey) { @@ -113,7 +113,7 @@ export class ObjectGraph> { throw new TypeError('The parameter "nodeKey" must be a string'); } if (!this.nodes.get(nodeKey)) { - throw new Error("A node with this key does not exist in this object graph"); + console.error("A node with this key does not exist in this object graph"); } this.nodes.delete(nodeKey); }