Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: adjust error handling #8

Merged
merged 1 commit into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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