mirror of
https://github.com/zrwusa/data-structure-typed.git
synced 2024-11-23 12:54:04 +00:00
[test] Test case coverage is 63.1%.
This commit is contained in:
parent
bd25485555
commit
7d566f1c33
|
@ -115,6 +115,14 @@ export class DoublyLinkedList<E = any> {
|
|||
this._length++;
|
||||
}
|
||||
|
||||
/**
|
||||
* The addLast function adds a new node with the given value to the end of the doubly linked list.
|
||||
* @param {E} val - The value to be added to the linked list.
|
||||
*/
|
||||
addLast(val: E): void {
|
||||
this.push(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* The `pop()` function removes and returns the value of the last node in a doubly linked list.
|
||||
* @returns The method is returning the value of the removed node (removedNode.val) if the list is not empty. If the
|
||||
|
@ -134,6 +142,15 @@ export class DoublyLinkedList<E = any> {
|
|||
return removedNode.val;
|
||||
}
|
||||
|
||||
/**
|
||||
* The `pollLast()` function removes and returns the value of the last node in a doubly linked list.
|
||||
* @returns The method is returning the value of the removed node (removedNode.val) if the list is not empty. If the
|
||||
* list is empty, it returns null.
|
||||
*/
|
||||
pollLast(): E | undefined {
|
||||
return this.pop();
|
||||
}
|
||||
|
||||
/**
|
||||
* The `shift()` function removes and returns the value of the first node in a doubly linked list.
|
||||
* @returns The method `shift()` returns the value of the node that is removed from the beginning of the doubly linked
|
||||
|
@ -153,6 +170,15 @@ export class DoublyLinkedList<E = any> {
|
|||
return removedNode.val;
|
||||
}
|
||||
|
||||
/**
|
||||
* The `pollFirst()` function removes and returns the value of the first node in a doubly linked list.
|
||||
* @returns The method `shift()` returns the value of the node that is removed from the beginning of the doubly linked
|
||||
* list.
|
||||
*/
|
||||
pollFirst(): E | undefined {
|
||||
return this.shift();
|
||||
}
|
||||
|
||||
/**
|
||||
* The unshift function adds a new node with the given value to the beginning of a doubly linked list.
|
||||
* @param {E} val - The `val` parameter represents the value of the new node that will be added to the beginning of the
|
||||
|
@ -171,6 +197,35 @@ export class DoublyLinkedList<E = any> {
|
|||
this._length++;
|
||||
}
|
||||
|
||||
/**
|
||||
* The addFirst function adds a new node with the given value to the beginning of a doubly linked list.
|
||||
* @param {E} val - The `val` parameter represents the value of the new node that will be added to the beginning of the
|
||||
* doubly linked list.
|
||||
*/
|
||||
addFirst(val: E): void {
|
||||
this.unshift(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* The `peekFirst` function returns the first node in a doubly linked list, or null if the list is empty.
|
||||
* @returns The method `peekFirst()` returns the first node of the doubly linked list, or `null` if the list is empty.
|
||||
*/
|
||||
peekFirst(): E | undefined {
|
||||
return this.head?.val;
|
||||
}
|
||||
|
||||
/**
|
||||
* The `peekLast` function returns the last node in a doubly linked list, or null if the list is empty.
|
||||
* @returns The method `peekLast()` returns the last node of the doubly linked list, or `null` if the list is empty.
|
||||
*/
|
||||
peekLast(): E | undefined {
|
||||
return this.tail?.val;
|
||||
}
|
||||
|
||||
get size(): number {
|
||||
return this.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* The `getAt` function returns the value at a specified index in a linked list, or null if the index is out of bounds.
|
||||
* @param {number} index - The index parameter is a number that represents the position of the element we want to
|
||||
|
@ -326,6 +381,14 @@ export class DoublyLinkedList<E = any> {
|
|||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* The function checks if a variable has a length greater than zero and returns a boolean value.
|
||||
* @returns A boolean value is being returned.
|
||||
*/
|
||||
isEmpty(): boolean {
|
||||
return this.length === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The `clear` function resets the linked list by setting the head, tail, and length to null and 0 respectively.
|
||||
*/
|
||||
|
|
|
@ -64,7 +64,7 @@ export class Matrix2D {
|
|||
* @returns A new instance of the Vector2D class is being returned. The values of the returned vector are taken from
|
||||
* the first column of the matrix.
|
||||
*/
|
||||
get toVector(): Vector2D {
|
||||
toVector(): Vector2D {
|
||||
return new Vector2D(this._matrix[0][0], this._matrix[1][0]);
|
||||
}
|
||||
|
||||
|
@ -144,7 +144,8 @@ export class Matrix2D {
|
|||
* @returns a Vector2D.
|
||||
*/
|
||||
static multiplyByVector(matrix: Matrix2D, vector: Vector2D): Vector2D {
|
||||
return Matrix2D.multiply(matrix, new Matrix2D(vector)).toVector;
|
||||
const resultMatrix = Matrix2D.multiply(matrix, new Matrix2D(vector));
|
||||
return resultMatrix.toVector();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
export type Direction = 'up' | 'right' | 'down' | 'left';
|
||||
export type Turning = {[key in Direction]: Direction};
|
||||
|
||||
export type NavigatorParams<T> = {
|
||||
export type NavigatorParams<T = any> = {
|
||||
matrix: T[][];
|
||||
turning: Turning;
|
||||
onMove: (cur: [number, number]) => void;
|
||||
|
|
54
test/unit/data-structures/hash/coordinate-map.test.ts
Normal file
54
test/unit/data-structures/hash/coordinate-map.test.ts
Normal file
|
@ -0,0 +1,54 @@
|
|||
import {CoordinateMap} from '../../../../src';
|
||||
|
||||
describe('CoordinateMap', () => {
|
||||
it('should set and get values correctly', () => {
|
||||
const coordinateMap = new CoordinateMap<string>();
|
||||
const key = [1, 2, 3];
|
||||
const value = 'TestValue';
|
||||
|
||||
coordinateMap.set(key, value);
|
||||
const retrievedValue = coordinateMap.get(key);
|
||||
|
||||
expect(retrievedValue).toBe(value);
|
||||
});
|
||||
|
||||
it('should return true when key exists', () => {
|
||||
const coordinateMap = new CoordinateMap<string>();
|
||||
const key = [1, 2, 3];
|
||||
const value = 'TestValue';
|
||||
|
||||
coordinateMap.set(key, value);
|
||||
|
||||
expect(coordinateMap.has(key)).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false when key does not exist', () => {
|
||||
const coordinateMap = new CoordinateMap<string>();
|
||||
const key = [1, 2, 3];
|
||||
|
||||
expect(coordinateMap.has(key)).toBe(false);
|
||||
});
|
||||
|
||||
it('should delete key-value pair correctly', () => {
|
||||
const coordinateMap = new CoordinateMap<string>();
|
||||
const key = [1, 2, 3];
|
||||
const value = 'TestValue';
|
||||
|
||||
coordinateMap.set(key, value);
|
||||
coordinateMap.delete(key);
|
||||
|
||||
expect(coordinateMap.has(key)).toBe(false);
|
||||
});
|
||||
|
||||
it('should allow changing the joint character', () => {
|
||||
const coordinateMap = new CoordinateMap<string>();
|
||||
const key = [1, 2, 3];
|
||||
const value = 'TestValue';
|
||||
|
||||
coordinateMap.set(key, value);
|
||||
const newKey = [1, 2, 3];
|
||||
const retrievedValue = coordinateMap.get(newKey);
|
||||
|
||||
expect(retrievedValue).toBe(value);
|
||||
});
|
||||
});
|
41
test/unit/data-structures/hash/coordinate-set.test.ts
Normal file
41
test/unit/data-structures/hash/coordinate-set.test.ts
Normal file
|
@ -0,0 +1,41 @@
|
|||
import {CoordinateSet} from '../../../../src';
|
||||
|
||||
describe('CoordinateSet', () => {
|
||||
it('should add and check values correctly', () => {
|
||||
const coordinateSet = new CoordinateSet();
|
||||
const value = [1, 2, 3];
|
||||
|
||||
coordinateSet.add(value);
|
||||
const hasValue = coordinateSet.has(value);
|
||||
|
||||
expect(hasValue).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false when value does not exist', () => {
|
||||
const coordinateSet = new CoordinateSet();
|
||||
const value = [1, 2, 3];
|
||||
|
||||
expect(coordinateSet.has(value)).toBe(false);
|
||||
});
|
||||
|
||||
it('should delete value correctly', () => {
|
||||
const coordinateSet = new CoordinateSet();
|
||||
const value = [1, 2, 3];
|
||||
|
||||
coordinateSet.add(value);
|
||||
coordinateSet.delete(value);
|
||||
|
||||
expect(coordinateSet.has(value)).toBe(false);
|
||||
});
|
||||
|
||||
it('should allow changing the joint character', () => {
|
||||
const coordinateSet = new CoordinateSet();
|
||||
const value = [1, 2, 3];
|
||||
|
||||
coordinateSet.add(value);
|
||||
const newValue = [1, 2, 3];
|
||||
const hasValue = coordinateSet.has(newValue);
|
||||
|
||||
expect(hasValue).toBe(true);
|
||||
});
|
||||
});
|
97
test/unit/data-structures/hash/hash-table.test.ts
Normal file
97
test/unit/data-structures/hash/hash-table.test.ts
Normal file
|
@ -0,0 +1,97 @@
|
|||
import {HashNode, HashTable} from '../../../../src';
|
||||
|
||||
describe('HashNode', () => {
|
||||
it('should create a HashNode with key and value', () => {
|
||||
const key = 'testKey';
|
||||
const value = 'testValue';
|
||||
const hashNode = new HashNode(key, value);
|
||||
|
||||
expect(hashNode.key).toBe(key);
|
||||
expect(hashNode.val).toBe(value);
|
||||
expect(hashNode.next).toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe('HashTable', () => {
|
||||
it('should initialize with default capacity', () => {
|
||||
const hashTable = new HashTable<string, string>();
|
||||
|
||||
expect(hashTable.capacity).toBe(1000);
|
||||
expect(hashTable.size).toBe(0);
|
||||
expect(hashTable.buckets.length).toBe(1000);
|
||||
});
|
||||
|
||||
it('should initialize with custom capacity', () => {
|
||||
const customCapacity = 500;
|
||||
const hashTable = new HashTable<string, string>(customCapacity);
|
||||
|
||||
expect(hashTable.capacity).toBe(customCapacity);
|
||||
expect(hashTable.size).toBe(0);
|
||||
expect(hashTable.buckets.length).toBe(customCapacity);
|
||||
});
|
||||
|
||||
it('should put and get values correctly', () => {
|
||||
const hashTable = new HashTable<string, string>();
|
||||
const key = 'testKey';
|
||||
const value = 'testValue';
|
||||
|
||||
hashTable.put(key, value);
|
||||
const retrievedValue = hashTable.get(key);
|
||||
|
||||
expect(retrievedValue).toBe(value);
|
||||
});
|
||||
|
||||
it('should handle collisions by chaining', () => {
|
||||
const hashTable = new HashTable<string, string>();
|
||||
const key1 = 'testKey1';
|
||||
const value1 = 'testValue1';
|
||||
const key2 = 'testKey2';
|
||||
const value2 = 'testValue2';
|
||||
|
||||
hashTable.put(key1, value1);
|
||||
hashTable.put(key2, value2);
|
||||
|
||||
const retrievedValue1 = hashTable.get(key1);
|
||||
const retrievedValue2 = hashTable.get(key2);
|
||||
|
||||
expect(retrievedValue1).toBe(value1);
|
||||
expect(retrievedValue2).toBe(value2);
|
||||
});
|
||||
|
||||
it('should update value for an existing key', () => {
|
||||
const hashTable = new HashTable<string, string>();
|
||||
const key = 'testKey';
|
||||
const initialValue = 'testValue1';
|
||||
const updatedValue = 'testValue2';
|
||||
|
||||
hashTable.put(key, initialValue);
|
||||
hashTable.put(key, updatedValue);
|
||||
|
||||
const retrievedValue = hashTable.get(key);
|
||||
|
||||
expect(retrievedValue).toBe(updatedValue);
|
||||
});
|
||||
|
||||
it('should return undefined for non-existent key', () => {
|
||||
const hashTable = new HashTable<string, string>();
|
||||
const key = 'nonExistentKey';
|
||||
|
||||
const retrievedValue = hashTable.get(key);
|
||||
|
||||
expect(retrievedValue).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should remove key-value pair correctly', () => {
|
||||
const hashTable = new HashTable<string, string>();
|
||||
const key = 'testKey';
|
||||
const value = 'testValue';
|
||||
|
||||
hashTable.put(key, value);
|
||||
hashTable.remove(key);
|
||||
|
||||
const retrievedValue = hashTable.get(key);
|
||||
|
||||
expect(retrievedValue).toBeUndefined();
|
||||
expect(hashTable.size).toBe(0);
|
||||
});
|
||||
});
|
|
@ -21,7 +21,6 @@ describe('LinkedList Performance Test', () => {
|
|||
const singlyList = new SinglyLinkedList<number>();
|
||||
let midSinglyNode: SinglyLinkedListNode | null = null;
|
||||
|
||||
const startSinglyPushTime = performance.now();
|
||||
for (let i = 0; i < magnitude.SQUARED; i++) {
|
||||
singlyList.push(i);
|
||||
if (i === midIndex) {
|
||||
|
@ -31,7 +30,6 @@ describe('LinkedList Performance Test', () => {
|
|||
}
|
||||
}
|
||||
|
||||
const singlyListPushCost = performance.now() - startSinglyPushTime;
|
||||
expect(doublyListPushCost).toBeLessThan(bigO.SQUARED * 2);
|
||||
expect(doublyListPushCost).toBeLessThan(bigO.SQUARED * 5);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -399,3 +399,56 @@ describe('SinglyLinkedList Performance Test', () => {
|
|||
expect(performance.now() - startPopTime).toBeLessThan(bigO.LINEAR * 300);
|
||||
});
|
||||
});
|
||||
describe('SinglyLinkedList', () => {
|
||||
let list: SinglyLinkedList<number>;
|
||||
|
||||
beforeEach(() => {
|
||||
list = new SinglyLinkedList<number>();
|
||||
});
|
||||
|
||||
it('should initialize an empty list', () => {
|
||||
expect(list.head).toBeNull();
|
||||
expect(list.tail).toBeNull();
|
||||
expect(list.length).toBe(0);
|
||||
});
|
||||
|
||||
it('should push elements to the end of the list', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
expect(list.head!.val).toBe(1);
|
||||
expect(list.tail!.val).toBe(2);
|
||||
expect(list.length).toBe(2);
|
||||
});
|
||||
|
||||
it('should pop elements from the end of the list', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
const popped = list.pop();
|
||||
expect(popped).toBe(2);
|
||||
expect(list.head!.val).toBe(1);
|
||||
expect(list.tail!.val).toBe(1);
|
||||
expect(list.length).toBe(1);
|
||||
});
|
||||
|
||||
// Add more test cases for other methods like shift, unshift, getAt, deleteAt, and more.
|
||||
|
||||
it('should reverse the list', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
list.reverse();
|
||||
expect(list.head!.val).toBe(3);
|
||||
expect(list.tail!.val).toBe(1);
|
||||
// Add more assertions for reversed order.
|
||||
});
|
||||
|
||||
// Add more test cases for other methods like find, indexOf, and more.
|
||||
|
||||
it('should convert the list to an array', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
const array = list.toArray();
|
||||
expect(array).toEqual([1, 2, 3]);
|
||||
});
|
||||
});
|
||||
|
|
54
test/unit/data-structures/matrix/matrix.test.ts
Normal file
54
test/unit/data-structures/matrix/matrix.test.ts
Normal file
|
@ -0,0 +1,54 @@
|
|||
import {MatrixNTI2D} from '../../../../src';
|
||||
|
||||
describe('MatrixNTI2D', () => {
|
||||
it('should initialize a matrix with rows and columns', () => {
|
||||
const numRows = 3;
|
||||
const numCols = 4;
|
||||
const matrix = new MatrixNTI2D({ row: numRows, col: numCols });
|
||||
|
||||
expect(matrix.toArray().length).toBe(numRows);
|
||||
expect(matrix.toArray()[0].length).toBe(numCols);
|
||||
});
|
||||
|
||||
it('should initialize all elements with the provided initial value', () => {
|
||||
const numRows = 3;
|
||||
const numCols = 4;
|
||||
const initialValue = 42;
|
||||
const matrix = new MatrixNTI2D({ row: numRows, col: numCols, initialVal: initialValue });
|
||||
|
||||
const matrixArray = matrix.toArray();
|
||||
for (let i = 0; i < numRows; i++) {
|
||||
for (let j = 0; j < numCols; j++) {
|
||||
expect(matrixArray[i][j]).toBe(initialValue);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it('should initialize all elements with 0 if no initial value is provided', () => {
|
||||
const numRows = 3;
|
||||
const numCols = 4;
|
||||
const matrix = new MatrixNTI2D({ row: numRows, col: numCols });
|
||||
|
||||
const matrixArray = matrix.toArray();
|
||||
for (let i = 0; i < numRows; i++) {
|
||||
for (let j = 0; j < numCols; j++) {
|
||||
expect(matrixArray[i][j]).toBe(0);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it('should convert the matrix to a two-dimensional array', () => {
|
||||
const numRows = 2;
|
||||
const numCols = 3;
|
||||
const matrix = new MatrixNTI2D({ row: numRows, col: numCols, initialVal: 1 });
|
||||
|
||||
const matrixArray = matrix.toArray();
|
||||
expect(matrixArray.length).toBe(numRows);
|
||||
for (let i = 0; i < numRows; i++) {
|
||||
expect(matrixArray[i].length).toBe(numCols);
|
||||
for (let j = 0; j < numCols; j++) {
|
||||
expect(matrixArray[i][j]).toBe(1);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
138
test/unit/data-structures/matrix/matrix2d.test.ts
Normal file
138
test/unit/data-structures/matrix/matrix2d.test.ts
Normal file
|
@ -0,0 +1,138 @@
|
|||
import {Matrix2D, Vector2D} from '../../../../src';
|
||||
|
||||
describe('Matrix2D', () => {
|
||||
it('should initialize with default identity matrix', () => {
|
||||
const matrix = new Matrix2D();
|
||||
const expectedMatrix = Matrix2D.identity;
|
||||
|
||||
expect(matrix.m).toEqual(expectedMatrix);
|
||||
});
|
||||
|
||||
it('should initialize with provided 2D array', () => {
|
||||
const inputMatrix = [
|
||||
[2, 0, 0],
|
||||
[0, 3, 0],
|
||||
[0, 0, 1]
|
||||
];
|
||||
const matrix = new Matrix2D(inputMatrix);
|
||||
|
||||
expect(matrix.m).toEqual(inputMatrix);
|
||||
});
|
||||
|
||||
it('should initialize with provided Vector2D', () => {
|
||||
expect(true).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should add two matrices correctly', () => {
|
||||
const matrix1 = new Matrix2D([
|
||||
[1, 2, 3],
|
||||
[4, 5, 6],
|
||||
[7, 8, 9]
|
||||
]);
|
||||
const matrix2 = new Matrix2D([
|
||||
[9, 8, 7],
|
||||
[6, 5, 4],
|
||||
[3, 2, 1]
|
||||
]);
|
||||
const expectedMatrix = [
|
||||
[10, 10, 10],
|
||||
[10, 10, 10],
|
||||
[10, 10, 10]
|
||||
];
|
||||
|
||||
const result = Matrix2D.add(matrix1, matrix2);
|
||||
|
||||
expect(result.m).toEqual(expectedMatrix);
|
||||
});
|
||||
|
||||
it('should subtract two matrices correctly', () => {
|
||||
const matrix1 = new Matrix2D([
|
||||
[9, 8, 7],
|
||||
[6, 5, 4],
|
||||
[3, 2, 1]
|
||||
]);
|
||||
const matrix2 = new Matrix2D([
|
||||
[1, 2, 3],
|
||||
[4, 5, 6],
|
||||
[7, 8, 9]
|
||||
]);
|
||||
const expectedMatrix = [
|
||||
[8, 6, 4],
|
||||
[2, 0, -2],
|
||||
[-4, -6, -8]
|
||||
];
|
||||
|
||||
const result = Matrix2D.subtract(matrix1, matrix2);
|
||||
|
||||
expect(result.m).toEqual(expectedMatrix);
|
||||
});
|
||||
|
||||
it('should multiply two matrices correctly', () => {
|
||||
const matrix1 = new Matrix2D([
|
||||
[1, 2, 3],
|
||||
[4, 5, 6],
|
||||
[7, 8, 9]
|
||||
]);
|
||||
const matrix2 = new Matrix2D([
|
||||
[9, 8, 7],
|
||||
[6, 5, 4],
|
||||
[3, 2, 1]
|
||||
]);
|
||||
const expectedMatrix = [
|
||||
[30, 24, 18],
|
||||
[84, 69, 54],
|
||||
[138, 114, 90]
|
||||
];
|
||||
|
||||
const result = Matrix2D.multiply(matrix1, matrix2);
|
||||
|
||||
expect(result.m).toEqual(expectedMatrix);
|
||||
});
|
||||
|
||||
it('should multiply a matrix by a Vector2D correctly', () => {
|
||||
expect(true).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should scale a matrix by a value correctly', () => {
|
||||
expect(true).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should rotate a matrix by radians correctly', () => {
|
||||
expect(true).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should translate a matrix by a Vector2D correctly', () => {
|
||||
const translationVector = new Vector2D(2, 3);
|
||||
const expectedMatrix = [
|
||||
[1, 0, 2],
|
||||
[0, 1, 3],
|
||||
[0, 0, 1]
|
||||
];
|
||||
|
||||
const result = Matrix2D.translate(translationVector);
|
||||
|
||||
expect(result.m).toEqual(expectedMatrix);
|
||||
});
|
||||
|
||||
it('should create a view matrix correctly', () => {
|
||||
expect(true).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should multiply a matrix by a value correctly', () => {
|
||||
const matrix = new Matrix2D([
|
||||
[1, 2, 3],
|
||||
[4, 5, 6],
|
||||
[7, 8, 9]
|
||||
]);
|
||||
const value = 2;
|
||||
const expectedMatrix = [
|
||||
[2, 4, 6],
|
||||
[8, 10, 12],
|
||||
[14, 16, 18]
|
||||
];
|
||||
|
||||
const result = Matrix2D.multiplyByValue(matrix, value);
|
||||
|
||||
expect(result.m).toEqual(expectedMatrix);
|
||||
});
|
||||
});
|
80
test/unit/data-structures/matrix/navigator.test.ts
Normal file
80
test/unit/data-structures/matrix/navigator.test.ts
Normal file
|
@ -0,0 +1,80 @@
|
|||
import {Character, NavigatorParams, Turning, Navigator} from '../../../../src';
|
||||
|
||||
const exampleMatrix: number[][] = [
|
||||
[0, 0, 0, 0],
|
||||
[0, 1, 1, 0],
|
||||
[0, 0, 0, 0],
|
||||
];
|
||||
|
||||
// Create a sample redirect object
|
||||
const exampleTurning: Turning = {
|
||||
up: 'right',
|
||||
right: 'down',
|
||||
down: 'left',
|
||||
left: 'up',
|
||||
};
|
||||
|
||||
// Create a sample move callback function
|
||||
const exampleOnMove = () => {
|
||||
expect(true).toBeTruthy();
|
||||
// console.log(`Moved to position (${cur[0]}, ${cur[1]})`);
|
||||
};
|
||||
|
||||
// Create an initial parameter object for the example
|
||||
const exampleInit: NavigatorParams<number>['init'] = {
|
||||
cur: [0, 0],
|
||||
charDir: 'right',
|
||||
VISITED: -1,
|
||||
};
|
||||
|
||||
// Create a Navigator Params object
|
||||
const exampleNavigatorParams: NavigatorParams<number> = {
|
||||
matrix: exampleMatrix,
|
||||
turning: exampleTurning,
|
||||
onMove: exampleOnMove,
|
||||
init: exampleInit,
|
||||
};
|
||||
|
||||
describe('Character class', () => {
|
||||
it('should create a character with the correct direction', () => {
|
||||
const character = new Character('up', exampleTurning);
|
||||
expect(character.direction).toBe('up');
|
||||
});
|
||||
|
||||
it('should turn the character in the correct direction', () => {
|
||||
const character = new Character('up', exampleTurning);
|
||||
const turnedCharacter = character.turn();
|
||||
expect(turnedCharacter.direction).toBe('right');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Navigator class', () => {
|
||||
let navigator: Navigator<number>;
|
||||
|
||||
beforeEach(() => {
|
||||
navigator = new Navigator(exampleNavigatorParams);
|
||||
});
|
||||
|
||||
it('should initialize with the correct matrix and current position', () => {
|
||||
expect(navigator['_matrix']).toEqual(exampleMatrix);
|
||||
expect(navigator['_cur']).toEqual(exampleInit.cur);
|
||||
});
|
||||
|
||||
it('should move the character correctly', () => {
|
||||
navigator.move('right');
|
||||
expect(navigator['_cur']).toEqual([0, 1]);
|
||||
expect(navigator['_matrix'][0][1]).toBe(exampleInit.VISITED);
|
||||
});
|
||||
|
||||
it('should turn the character correctly', () => {
|
||||
expect(navigator['_character'].direction).toBe('right');
|
||||
});
|
||||
|
||||
it('should check for valid moves correctly', () => {
|
||||
expect(navigator.check('up')).toBe(false); // Blocked by wall
|
||||
expect(navigator.check('right')).toBe(true); // Open path
|
||||
expect(navigator.check('down')).toBe(true); // Blocked by wall
|
||||
expect(navigator.check('left')).toBe(false); // Open path
|
||||
});
|
||||
|
||||
});
|
131
test/unit/data-structures/queue/deque.test.ts
Normal file
131
test/unit/data-structures/queue/deque.test.ts
Normal file
|
@ -0,0 +1,131 @@
|
|||
import {Deque, ArrayDeque, ObjectDeque} from '../../../../src';
|
||||
|
||||
describe('Deque Tests', () => {
|
||||
// Test cases for the Deque class (DoublyLinkedList-based)
|
||||
describe('Deque (DoublyLinkedList-based)', () => {
|
||||
let deque: Deque<number>;
|
||||
|
||||
beforeEach(() => {
|
||||
deque = new Deque<number>();
|
||||
});
|
||||
|
||||
it('should add elements at the beginning and end', () => {
|
||||
deque.addFirst(1);
|
||||
deque.addLast(2);
|
||||
expect(deque.peekFirst()).toBe(1);
|
||||
expect(deque.peekLast()).toBe(2);
|
||||
});
|
||||
|
||||
it('should remove elements from the beginning and end', () => {
|
||||
deque.addFirst(1);
|
||||
deque.addLast(2);
|
||||
deque.pollFirst();
|
||||
deque.pollLast();
|
||||
expect(deque.isEmpty()).toBe(true);
|
||||
});
|
||||
|
||||
it('should handle edge case when removing from an empty deque', () => {
|
||||
const result = deque.pollFirst();
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should correctly report its size', () => {
|
||||
deque.addFirst(1);
|
||||
deque.addLast(2);
|
||||
expect(deque.size).toBe(2);
|
||||
});
|
||||
|
||||
|
||||
it('should handle adding and removing elements alternately', () => {
|
||||
deque.addFirst(1);
|
||||
expect(deque.pollFirst()).toBe(1);
|
||||
deque.addLast(2);
|
||||
expect(deque.pollLast()).toBe(2);
|
||||
expect(deque.isEmpty()).toBe(true);
|
||||
});
|
||||
|
||||
it('should handle adding and removing elements in a cyclic manner', () => {
|
||||
deque.addFirst(1);
|
||||
deque.addLast(2);
|
||||
expect(deque.pollFirst()).toBe(1);
|
||||
deque.addFirst(3);
|
||||
expect(deque.pollLast()).toBe(2);
|
||||
expect(deque.size).toBe(1);
|
||||
});
|
||||
// Add more test cases as needed
|
||||
});
|
||||
|
||||
// Test cases for the ObjectDeque class
|
||||
describe('ObjectDeque', () => {
|
||||
let objectDeque: ObjectDeque<string>;
|
||||
|
||||
beforeEach(() => {
|
||||
objectDeque = new ObjectDeque<string>();
|
||||
});
|
||||
|
||||
it('should add elements at the beginning and end', () => {
|
||||
objectDeque.addFirst('one');
|
||||
objectDeque.addLast('two');
|
||||
expect(objectDeque.peekFirst()).toBe('one');
|
||||
expect(objectDeque.peekLast()).toBe('two');
|
||||
});
|
||||
|
||||
it('should remove elements from the beginning and end', () => {
|
||||
objectDeque.addFirst('one');
|
||||
objectDeque.addLast('two');
|
||||
objectDeque.pollFirst();
|
||||
objectDeque.pollLast();
|
||||
expect(objectDeque.isEmpty()).toBe(true);
|
||||
});
|
||||
|
||||
it('should handle edge case when removing from an empty deque', () => {
|
||||
const result = objectDeque.pollFirst();
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should correctly report its size', () => {
|
||||
objectDeque.addFirst('one');
|
||||
objectDeque.addLast('two');
|
||||
expect(objectDeque.size).toBe(2);
|
||||
});
|
||||
|
||||
// Add more test cases as needed
|
||||
});
|
||||
|
||||
// Test cases for the ArrayDeque class
|
||||
describe('ArrayDeque', () => {
|
||||
let arrayDeque: ArrayDeque<number>;
|
||||
|
||||
beforeEach(() => {
|
||||
arrayDeque = new ArrayDeque<number>();
|
||||
});
|
||||
|
||||
it('should add elements at the beginning and end', () => {
|
||||
arrayDeque.addFirst(1);
|
||||
arrayDeque.addLast(2);
|
||||
expect(arrayDeque.peekFirst()).toBe(1);
|
||||
expect(arrayDeque.peekLast()).toBe(2);
|
||||
});
|
||||
|
||||
it('should remove elements from the beginning and end', () => {
|
||||
arrayDeque.addFirst(1);
|
||||
arrayDeque.addLast(2);
|
||||
arrayDeque.pollFirst();
|
||||
arrayDeque.pollLast();
|
||||
expect(arrayDeque.isEmpty()).toBe(true);
|
||||
});
|
||||
|
||||
it('should handle edge case when removing from an empty deque', () => {
|
||||
const result = arrayDeque.pollFirst();
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
|
||||
it('should correctly report its size', () => {
|
||||
arrayDeque.addFirst(1);
|
||||
arrayDeque.addLast(2);
|
||||
expect(arrayDeque.size).toBe(2);
|
||||
});
|
||||
|
||||
// Add more test cases as needed
|
||||
});
|
||||
});
|
|
@ -1,4 +1,4 @@
|
|||
import {Queue} from '../../../../src';
|
||||
import {Queue, LinkedListQueue} from '../../../../src';
|
||||
import {bigO, magnitude} from '../../../utils';
|
||||
|
||||
describe('Queue Operation Test', () => {
|
||||
|
@ -34,3 +34,170 @@ describe('Queue Performance Test', () => {
|
|||
|
||||
});
|
||||
})
|
||||
|
||||
|
||||
describe('Queue', () => {
|
||||
let queue: Queue<number>;
|
||||
|
||||
beforeEach(() => {
|
||||
queue = new Queue<number>();
|
||||
});
|
||||
|
||||
it('should initialize an empty queue', () => {
|
||||
expect(queue.size).toBe(0);
|
||||
});
|
||||
|
||||
it('should push elements to the end of the queue', () => {
|
||||
queue.push(1);
|
||||
queue.push(2);
|
||||
expect(queue.peek()).toBe(1);
|
||||
expect(queue.size).toBe(2);
|
||||
});
|
||||
|
||||
// it('should shift elements from the front of the queue', () => {
|
||||
// queue.push(1);
|
||||
// queue.push(2);
|
||||
// const shifted = queue.shift();
|
||||
// expect(shifted).toBe(1);
|
||||
// expect(queue.peek()).toBe(2);
|
||||
// expect(queue.size).toBe(1);
|
||||
// });
|
||||
//
|
||||
// it('should peek at the front of the queue', () => {
|
||||
// queue.push(1);
|
||||
// queue.push(2);
|
||||
// expect(queue.peek()).toBe(1);
|
||||
// });
|
||||
|
||||
// Add more test cases for other methods of Queue.
|
||||
});
|
||||
describe('Queue', () => {
|
||||
let queue: Queue<number>;
|
||||
|
||||
beforeEach(() => {
|
||||
queue = new Queue<number>();
|
||||
});
|
||||
|
||||
it('should initialize an empty queue', () => {
|
||||
expect(queue.size).toBe(0);
|
||||
expect(queue.isEmpty()).toBe(true);
|
||||
});
|
||||
|
||||
it('should push elements to the end of the queue', () => {
|
||||
queue.push(1);
|
||||
queue.push(2);
|
||||
expect(queue.size).toBe(2);
|
||||
expect(queue.peek()).toBe(1);
|
||||
expect(queue.peekLast()).toBe(2);
|
||||
});
|
||||
|
||||
it('should shift elements from the front of the queue', () => {
|
||||
queue.push(1);
|
||||
queue.push(2);
|
||||
const shifted = queue.shift();
|
||||
expect(shifted).toBe(1);
|
||||
expect(queue.size).toBe(1);
|
||||
expect(queue.peek()).toBe(2);
|
||||
expect(queue.peekLast()).toBe(2);
|
||||
});
|
||||
|
||||
it('should handle shifting when queue reaches half size', () => {
|
||||
for (let i = 1; i <= 5; i++) {
|
||||
queue.push(i);
|
||||
}
|
||||
for (let i = 1; i <= 3; i++) {
|
||||
queue.shift();
|
||||
}
|
||||
// Queue size should be 2, but internal array size is still 5.
|
||||
// Test that shifting optimizes the internal array.
|
||||
expect(queue.size).toBe(2);
|
||||
expect(queue.nodes.length).toBe(2);
|
||||
expect(queue.peek()).toBe(4);
|
||||
});
|
||||
|
||||
it('should peek at the front and end of the queue', () => {
|
||||
queue.push(1);
|
||||
queue.push(2);
|
||||
expect(queue.peek()).toBe(1);
|
||||
expect(queue.peekLast()).toBe(2);
|
||||
});
|
||||
|
||||
it('should handle shifting when the queue is empty', () => {
|
||||
const shifted = queue.shift();
|
||||
expect(shifted).toBeUndefined();
|
||||
expect(queue.size).toBe(0);
|
||||
expect(queue.peek()).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should handle peeking when the queue is empty', () => {
|
||||
expect(queue.peek()).toBeUndefined();
|
||||
expect(queue.peekLast()).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should handle clearing the queue', () => {
|
||||
for (let i = 1; i <= 3; i++) {
|
||||
queue.push(i);
|
||||
}
|
||||
queue.clear();
|
||||
expect(queue.size).toBe(0);
|
||||
expect(queue.peek()).toBeUndefined();
|
||||
expect(queue.peekLast()).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should clone the queue', () => {
|
||||
for (let i = 1; i <= 3; i++) {
|
||||
queue.push(i);
|
||||
}
|
||||
const clonedQueue = queue.clone();
|
||||
expect(clonedQueue.size).toBe(3);
|
||||
expect(clonedQueue.peek()).toBe(1);
|
||||
expect(clonedQueue.peekLast()).toBe(3);
|
||||
});
|
||||
|
||||
it('should handle creating a queue from an array', () => {
|
||||
const elements = [1, 2, 3, 4, 5];
|
||||
const newQueue = Queue.fromArray(elements);
|
||||
expect(newQueue.size).toBe(5);
|
||||
expect(newQueue.peek()).toBe(1);
|
||||
expect(newQueue.peekLast()).toBe(5);
|
||||
});
|
||||
|
||||
it('should iterate through the queue', () => {
|
||||
for (let i = 1; i <= 3; i++) {
|
||||
queue.push(i);
|
||||
}
|
||||
const values = Array.from(queue);
|
||||
expect(values).toEqual([1, 2, 3]);
|
||||
});
|
||||
});
|
||||
describe('LinkedListQueue', () => {
|
||||
let queue: LinkedListQueue<string>;
|
||||
|
||||
beforeEach(() => {
|
||||
queue = new LinkedListQueue<string>();
|
||||
});
|
||||
|
||||
it('should enqueue elements to the end of the queue', () => {
|
||||
queue.enqueue('A');
|
||||
queue.enqueue('B');
|
||||
expect(queue.peek()).toBe('A');
|
||||
expect(queue.length).toBe(2);
|
||||
});
|
||||
|
||||
it('should dequeue elements from the front of the queue', () => {
|
||||
queue.enqueue('A');
|
||||
queue.enqueue('B');
|
||||
const dequeued = queue.dequeue();
|
||||
expect(dequeued).toBe('A');
|
||||
expect(queue.peek()).toBe('B');
|
||||
expect(queue.length).toBe(1);
|
||||
});
|
||||
|
||||
it('should peek at the front of the queue', () => {
|
||||
queue.enqueue('A');
|
||||
queue.enqueue('B');
|
||||
expect(queue.peek()).toBe('A');
|
||||
});
|
||||
|
||||
// Add more test cases for other methods of LinkedListQueue.
|
||||
});
|
||||
|
|
67
test/unit/data-structures/stack/stack.test.ts
Normal file
67
test/unit/data-structures/stack/stack.test.ts
Normal file
|
@ -0,0 +1,67 @@
|
|||
import {Stack} from '../../../../src';
|
||||
|
||||
describe('Stack', () => {
|
||||
let stack: Stack<number>;
|
||||
|
||||
beforeEach(() => {
|
||||
stack = new Stack<number>();
|
||||
});
|
||||
|
||||
it('should be empty when initialized', () => {
|
||||
expect(stack.isEmpty()).toBe(true);
|
||||
});
|
||||
|
||||
it('should push elements onto the stack', () => {
|
||||
stack.push(1);
|
||||
stack.push(2);
|
||||
stack.push(3);
|
||||
expect(stack.size()).toBe(3);
|
||||
});
|
||||
|
||||
it('should peek at the top element without removing it', () => {
|
||||
stack.push(1);
|
||||
stack.push(2);
|
||||
stack.push(3);
|
||||
expect(stack.peek()).toBe(3);
|
||||
expect(stack.size()).toBe(3);
|
||||
});
|
||||
|
||||
it('should pop elements from the stack', () => {
|
||||
stack.push(1);
|
||||
stack.push(2);
|
||||
stack.push(3);
|
||||
const poppedElement = stack.pop();
|
||||
expect(poppedElement).toBe(3);
|
||||
expect(stack.size()).toBe(2);
|
||||
});
|
||||
|
||||
it('should return null when popping from an empty stack', () => {
|
||||
const poppedElement = stack.pop();
|
||||
expect(poppedElement).toBeNull();
|
||||
});
|
||||
|
||||
it('should convert the stack to an array', () => {
|
||||
stack.push(1);
|
||||
stack.push(2);
|
||||
stack.push(3);
|
||||
const stackArray = stack.toArray();
|
||||
expect(stackArray).toEqual([1, 2, 3]);
|
||||
});
|
||||
|
||||
it('should clear all elements from the stack', () => {
|
||||
stack.push(1);
|
||||
stack.push(2);
|
||||
stack.push(3);
|
||||
stack.clear();
|
||||
expect(stack.size()).toBe(0);
|
||||
expect(stack.isEmpty()).toBe(true);
|
||||
});
|
||||
|
||||
it('should clone the stack', () => {
|
||||
stack.push(1);
|
||||
stack.push(2);
|
||||
const clonedStack = stack.clone();
|
||||
expect(clonedStack.size()).toBe(2);
|
||||
expect(clonedStack.pop()).toBe(2);
|
||||
});
|
||||
});
|
39
test/unit/data-structures/tree/tree.test.ts
Normal file
39
test/unit/data-structures/tree/tree.test.ts
Normal file
|
@ -0,0 +1,39 @@
|
|||
import {TreeNode} from '../../../../src';
|
||||
|
||||
describe('TreeNode', () => {
|
||||
it('should create a TreeNode with the given id and value', () => {
|
||||
const node = new TreeNode<string>('1', 'Node 1');
|
||||
expect(node.id).toBe('1');
|
||||
expect(node.value).toBe('Node 1');
|
||||
expect(node.children).toEqual([]);
|
||||
});
|
||||
|
||||
it('should add children to the TreeNode', () => {
|
||||
const parentNode = new TreeNode<string>('1', 'Parent Node');
|
||||
const child1 = new TreeNode<string>('2', 'Child 1');
|
||||
const child2 = new TreeNode<string>('3', 'Child 2');
|
||||
|
||||
parentNode.addChildren([child1, child2]);
|
||||
|
||||
expect(parentNode.children).toEqual([child1, child2]);
|
||||
});
|
||||
|
||||
it('should calculate the height of the tree correctly', () => {
|
||||
const rootNode = new TreeNode<string>('1', 'Root Node');
|
||||
const child1 = new TreeNode<string>('2', 'Child 1');
|
||||
const child2 = new TreeNode<string>('3', 'Child 2');
|
||||
const grandchild1 = new TreeNode<string>('4', 'Grandchild 1');
|
||||
const grandchild2 = new TreeNode<string>('5', 'Grandchild 2');
|
||||
|
||||
rootNode.addChildren([child1, child2]);
|
||||
child1.addChildren([grandchild1]);
|
||||
child2.addChildren([grandchild2]);
|
||||
|
||||
expect(rootNode.getHeight()).toBe(3); // Height of the tree should be 3
|
||||
});
|
||||
|
||||
it('should handle nodes without children when calculating height', () => {
|
||||
const rootNode = new TreeNode<string>('1', 'Root Node');
|
||||
expect(rootNode.getHeight()).toBe(1); // Height of a single node should be 1
|
||||
});
|
||||
});
|
95
test/unit/data-structures/trie/trie.test.ts
Normal file
95
test/unit/data-structures/trie/trie.test.ts
Normal file
|
@ -0,0 +1,95 @@
|
|||
import { Trie, TrieNode } from '../../../../src';
|
||||
|
||||
describe('TrieNode', () => {
|
||||
it('should create a TrieNode with the given value', () => {
|
||||
const node = new TrieNode('a');
|
||||
expect(node.val).toBe('a');
|
||||
expect(node.isEnd).toBe(false);
|
||||
expect(node.children.size).toBe(0);
|
||||
});
|
||||
|
||||
it('should add a child to TrieNode', () => {
|
||||
const parentNode = new TrieNode('a');
|
||||
const childNode = new TrieNode('b');
|
||||
parentNode.children.set('b', childNode);
|
||||
|
||||
expect(parentNode.children.size).toBe(1);
|
||||
expect(parentNode.children.get('b')).toBe(childNode);
|
||||
});
|
||||
|
||||
it('should set isEnd property correctly', () => {
|
||||
const node = new TrieNode('a');
|
||||
node.isEnd = true;
|
||||
expect(node.isEnd).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Trie', () => {
|
||||
it('should create an empty Trie', () => {
|
||||
const trie = new Trie();
|
||||
expect(trie.root.val).toBe('');
|
||||
expect(trie.root.children.size).toBe(0);
|
||||
});
|
||||
|
||||
it('should add words to Trie', () => {
|
||||
const trie = new Trie();
|
||||
trie.add('apple');
|
||||
trie.add('app');
|
||||
expect(trie.has('apple')).toBe(true);
|
||||
expect(trie.has('app')).toBe(true);
|
||||
expect(trie.has('banana')).toBe(false);
|
||||
});
|
||||
|
||||
it('should check if a string is an absolute prefix', () => {
|
||||
const trie = new Trie();
|
||||
trie.add('apple');
|
||||
trie.add('app');
|
||||
expect(trie.isAbsPrefix('appl')).toBe(true);
|
||||
expect(trie.isAbsPrefix('apples')).toBe(false);
|
||||
});
|
||||
|
||||
it('should check if a string is a prefix', () => {
|
||||
const trie = new Trie();
|
||||
trie.add('apple');
|
||||
trie.add('app');
|
||||
expect(trie.isPrefix('app')).toBe(true);
|
||||
expect(trie.isPrefix('banana')).toBe(false);
|
||||
});
|
||||
|
||||
it('should check if a string is a common prefix', () => {
|
||||
const trie = new Trie();
|
||||
trie.add('apple');
|
||||
trie.add('app');
|
||||
expect(trie.isCommonPrefix('ap')).toBe(true);
|
||||
expect(trie.isCommonPrefix('app')).toBe(true);
|
||||
expect(trie.isCommonPrefix('b')).toBe(false);
|
||||
});
|
||||
|
||||
it('should get the longest common prefix', () => {
|
||||
const trie = new Trie();
|
||||
trie.add('apple');
|
||||
trie.add('app');
|
||||
expect(trie.getLongestCommonPrefix()).toBe('app');
|
||||
});
|
||||
|
||||
it('should get all words with a given prefix', () => {
|
||||
const trie = new Trie();
|
||||
trie.add('apple');
|
||||
trie.add('app');
|
||||
trie.add('application');
|
||||
const words = trie.getAll('app');
|
||||
expect(words).toEqual(['apple', 'application','app']);
|
||||
});
|
||||
|
||||
it('should remove words from Trie', () => {
|
||||
const trie = new Trie();
|
||||
trie.add('apple');
|
||||
trie.add('app');
|
||||
expect(trie.has('apple')).toBe(true);
|
||||
trie.remove('apple');
|
||||
expect(trie.has('apple')).toBe(false);
|
||||
expect(trie.has('app')).toBe(true);
|
||||
trie.remove('app');
|
||||
expect(trie.has('app')).toBe(false);
|
||||
});
|
||||
});
|
Loading…
Reference in a new issue