Skip to content

Commit

Permalink
fix: adjust error handling (#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
luckasnix authored May 29, 2024
1 parent 142b1a8 commit 5eaa3ed
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 48 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
105 changes: 63 additions & 42 deletions src/object-graph/index.test.ts
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -17,21 +17,23 @@ 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<Shirt>(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", () => {
const shirtsObjectGraph = new ObjectGraph<Shirt>(shirtsMock, (shirt) => shirt.sku);

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);
});
});

Expand All @@ -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<Shirt>(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", () => {
Expand All @@ -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) => 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<Shirt>(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<Shirt>(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");
});
});

Expand All @@ -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<Shirt>(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<Shirt>(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<Shirt>(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();
});
});

Expand Down
10 changes: 5 additions & 5 deletions src/object-graph/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export class ObjectGraph<NodeValue extends Record<string, unknown>> {
}
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;
}
Expand Down Expand Up @@ -65,7 +65,7 @@ export class ObjectGraph<NodeValue extends Record<string, unknown>> {
}
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);
}
Expand All @@ -88,7 +88,7 @@ export class ObjectGraph<NodeValue extends Record<string, unknown>> {
}
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);
}
Expand All @@ -103,7 +103,7 @@ export class ObjectGraph<NodeValue extends Record<string, unknown>> {
}

/**
* @description Removes a node to the object graph.
* @description Removes a node from the object graph.
*/
public remove(nodeKey: string) {
if (!nodeKey) {
Expand All @@ -113,7 +113,7 @@ export class ObjectGraph<NodeValue extends Record<string, unknown>> {
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);
}
Expand Down

0 comments on commit 5eaa3ed

Please sign in to comment.