Skip to content

Commit

Permalink
added misc functions and test them
Browse files Browse the repository at this point in the history
  • Loading branch information
Peter Hovanec committed Nov 5, 2024
1 parent 2df2e43 commit 610e12f
Show file tree
Hide file tree
Showing 3 changed files with 171 additions and 37 deletions.
33 changes: 24 additions & 9 deletions src/ordinalTree/OrdinalNode.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,43 @@


class OrdinalNode {
constructor(value) {
this.value = value;
this.children = [];
this.parent = null;
this.value = value;
this.children = [];
this.parent = null;
}

addChild(childNode) {
childNode.parent = this;
this.children.push( childNode);
childNode.parent = this;
this.children.push(childNode);
}

removeChild(childNode) {
const index = this.children.indexOf(childNode);
if (index > -1) {
this.children.splice(index, 1);
childNode.parent = null;
childNode.parent = null;
}
}

getChildAt(index) {
return this.children[index];
return this.children[index];
}

getChildrenCount() {
return this.children.length;
}

findChild(value) {
return this.children.find((child) => child.value === value) || null;
}

getSiblings() {
if (this.parent) {
return this.parent.children.filter((child) => child !== this);
}
return [];
}


}

export default OrdinalNode;
60 changes: 45 additions & 15 deletions src/ordinalTree/OrdinalTree.js
Original file line number Diff line number Diff line change
@@ -1,53 +1,83 @@


import OrdinalNode from "./OrdinalNode";

class OrdinalTree {
constructor() {
this.root = null;
this.root = null;
}


add(value, parentValue = null) {
const newNode = new OrdinalNode(value);
if (this.root === null) {
this.root = newNode;
this.root = newNode;
} else {
const parent = this.findNode(this.root, parentValue);
if (parent) {
parent.addChild(newNode);
parent.addChild(newNode);
} else {
console.error("Parent not found");
}
}
}


findNode(currentNode, value) {
if (currentNode.value === value) {
return currentNode;
return currentNode;
}

for (const child of currentNode.children) {
const foundNode = this.findNode(child, value);
if (foundNode) {
return foundNode;
return foundNode;
}
}
return null;
return null;
}


traverse(callback) {
const traverseNode = (node) => {
callback(node);
node.children.forEach(traverseNode);
callback(node);
node.children.forEach(traverseNode);
};
if (this.root) {
traverseNode(this.root);
traverseNode(this.root);
}
}


remove(value) {
const nodeToRemove = this.findNode(this.root, value);
if (nodeToRemove && nodeToRemove.parent) {
nodeToRemove.parent.removeChild(nodeToRemove);
} else if (nodeToRemove === this.root) {
this.root = null; // If the root is being removed
}
}

getHeight() {
const heightOfNode = (node) => {
if (!node) return -1;
const heights = node.children.map(heightOfNode);
return 1 + Math.max(-1, ...heights);
};
return heightOfNode(this.root);
}

getAllValues() {
const values = [];
this.traverse((node) => values.push(node.value));
return values;
}

findNodeWithCallback(callback) {
const findNode = (node) => {
if (callback(node)) return node;
for (const child of node.children) {
const foundNode = findNode(child);
if (foundNode) return foundNode;
}
return null;
};
return findNode(this.root);
}
}

export default OrdinalTree;
115 changes: 102 additions & 13 deletions test/ordinal.spec.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@


import { OrdinalTree, OrdinalNode } from "../src/ordinalTree/index";

describe("OrdinalTree", () => {
let tree;

beforeEach(() => {
tree = new OrdinalTree();
tree = new OrdinalTree();
});

it("should create a tree with a root node", () => {
Expand All @@ -19,21 +17,19 @@ describe("OrdinalTree", () => {
tree.add("Root");
tree.add("Child 1", "Root");
tree.add("Child 2", "Root");

expect(tree.root.children.length).toBe(2);
expect(tree.root.children[0].value).toBe("Child 1");
expect(tree.root.children[1].value).toBe("Child 2");
expect(tree.root.children[0].value).toBe("Child 1");
expect(tree.root.children[1].value).toBe("Child 2");
});



it("should retrieve a child at a specific index", () => {
tree.add("Root");
tree.add("Child 1", "Root");
tree.add("Child 2", "Root");

const childAtIndex = tree.root.getChildAt(1);
expect(childAtIndex.value).toBe("Child 2");
const childAtIndex = tree.root.getChildAt(1);
expect(childAtIndex.value).toBe("Child 2");
});

it("should add grandchildren to a child node", () => {
Expand Down Expand Up @@ -69,7 +65,7 @@ describe("OrdinalTree", () => {

tree.traverse((node) => values.push(node.value));

expect(values).toEqual(["Root", "Child 1", "Child 2"]);
expect(values).toEqual(["Root", "Child 1", "Child 2"]);
});

it("should remove a child node", () => {
Expand All @@ -82,14 +78,65 @@ describe("OrdinalTree", () => {

tree.root.removeChild(child1);
expect(tree.root.children.length).toBe(1);
expect(tree.root.children[0].value).toBe("Child 2");
expect(tree.root.children[0].value).toBe("Child 2");
});

// Tests for new functions

it("should remove a node from the tree", () => {
tree.add("Root");
tree.add("Child 1", "Root");
tree.add("Child 2", "Root");

expect(tree.root.children.length).toBe(2);
tree.remove("Child 1");
expect(tree.root.children.length).toBe(1);
expect(tree.root.children[0].value).toBe("Child 2");
});

it("should set root to null if the root is removed", () => {
tree.add("Root");
expect(tree.root.value).toBe("Root");
tree.remove("Root");
expect(tree.root).toBeNull();
});

it("should get the height of the tree", () => {
tree.add("Root");
tree.add("Child 1", "Root");
tree.add("Child 2", "Root");
tree.add("Grandchild 1", "Child 1");

expect(tree.getHeight()).toBe(2); // Height should be 2
});

it("should get all values in the tree", () => {
tree.add("Root");
tree.add("Child 1", "Root");
tree.add("Child 2", "Root");

const allValues = tree.getAllValues();
expect(allValues).toEqual(["Root", "Child 1", "Child 2"]);
});

it("should find a node with a callback", () => {
tree.add("Root");
tree.add("Child 1", "Root");
tree.add("Child 2", "Root");

const foundNode = tree.findNodeWithCallback(
(node) => node.value === "Child 1"
);
expect(foundNode).toBeTruthy();
expect(foundNode.value).toBe("Child 1");
});
});

describe("OrdinalNode", () => {
let node;

beforeEach(() => {
node = new OrdinalNode("Test Node");
node = new OrdinalNode("Test Node");
});

it("should initialize a node with the correct value", () => {
Expand All @@ -116,4 +163,46 @@ describe("OrdinalNode", () => {
expect(node.children.length).toBe(0);
expect(childNode.parent).toBeNull();
});

it("should get the number of children", () => {
const childNode1 = new OrdinalNode("Child 1");
const childNode2 = new OrdinalNode("Child 2");
node.addChild(childNode1);
node.addChild(childNode2);

expect(node.getChildrenCount()).toBe(2);
});

it("should find a child by value", () => {
const childNode = new OrdinalNode("Child Node");
node.addChild(childNode);

const foundChild = node.findChild("Child Node");
expect(foundChild).toBe(childNode);
});

it("should return null when child is not found", () => {
const childNode = new OrdinalNode("Child Node");
node.addChild(childNode);

const foundChild = node.findChild("Non-existing Child");
expect(foundChild).toBeNull();
});

it("should get siblings", () => {
const siblingNode1 = new OrdinalNode("Sibling 1");
const siblingNode2 = new OrdinalNode("Sibling 2");
const childNode = new OrdinalNode("Child");

node.addChild(siblingNode1);
node.addChild(childNode);
node.addChild(siblingNode2);

const siblings = childNode.getSiblings();
expect(siblings.length).toBe(2);
expect(siblings).toContain(siblingNode1);
expect(siblings).toContain(siblingNode2);
});


});

0 comments on commit 610e12f

Please sign in to comment.