mirror of
https://github.com/brendan-ch/project-inter-server.git
synced 2026-04-17 16:00:32 +00:00
Move all tests to subdirectories underneath code to be tested
This commit is contained in:
201
src/types/__tests__/CircularQueue.test.ts
Normal file
201
src/types/__tests__/CircularQueue.test.ts
Normal file
@@ -0,0 +1,201 @@
|
||||
import { describe, expect, it } from "@jest/globals";
|
||||
import { CircularQueue } from "../CircularQueue";
|
||||
|
||||
interface TestItem {
|
||||
id: number;
|
||||
value: string;
|
||||
}
|
||||
|
||||
describe("CircularQueue", () => {
|
||||
const testItems = {
|
||||
first: { id: 1, value: "first" },
|
||||
second: { id: 2, value: "second" },
|
||||
third: { id: 3, value: "third" },
|
||||
fourth: { id: 4, value: "fourth" },
|
||||
test: { id: 1, value: "test" },
|
||||
apple: { id: 1, value: "apple" },
|
||||
banana: { id: 2, value: "banana" },
|
||||
cherry: { id: 3, value: "cherry" },
|
||||
grape: { id: 5, value: "grape" },
|
||||
orange: { id: 7, value: "orange" },
|
||||
a: { id: 1, value: "a" },
|
||||
b: { id: 2, value: "b" },
|
||||
c: { id: 3, value: "c" },
|
||||
d: { id: 4, value: "d" }
|
||||
};
|
||||
|
||||
const sortingCallbacks = {
|
||||
byId: (a: TestItem, b: TestItem) => a.id - b.id,
|
||||
byValue: (a: TestItem, b: TestItem) => a.value.localeCompare(b.value)
|
||||
};
|
||||
|
||||
const keyExtractors = {
|
||||
id: (item: TestItem) => item.id,
|
||||
value: (item: TestItem) => item.value
|
||||
};
|
||||
|
||||
const createQueueWithItems = (size: number, items: TestItem[], sortingCallback: (a: TestItem, b: TestItem) => number) => {
|
||||
const queue = new CircularQueue<TestItem>(size);
|
||||
items.forEach(item => queue.appendWithSorting(item, sortingCallback));
|
||||
return queue;
|
||||
};
|
||||
|
||||
describe("constructor", () => {
|
||||
it("creates queue with specified size", () => {
|
||||
const queue = new CircularQueue<TestItem>(5);
|
||||
expect(queue).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe("appendWithSorting", () => {
|
||||
it("adds items to the queue with sorting callback", () => {
|
||||
const queue = createQueueWithItems(3, [testItems.third, testItems.first, testItems.second], sortingCallbacks.byId);
|
||||
|
||||
expect(queue.size()).toBe(3);
|
||||
expect(queue.get(0)).toEqual(testItems.first);
|
||||
expect(queue.get(1)).toEqual(testItems.second);
|
||||
expect(queue.get(2)).toEqual(testItems.third);
|
||||
});
|
||||
|
||||
it("overwrites oldest items when queue is full", () => {
|
||||
const queue = createQueueWithItems(2, [testItems.first, testItems.second, testItems.third], sortingCallbacks.byId);
|
||||
|
||||
expect(queue.size()).toBe(2);
|
||||
});
|
||||
|
||||
it("handles appending to empty queue", () => {
|
||||
const queue = createQueueWithItems(3, [testItems.test], sortingCallbacks.byId);
|
||||
|
||||
expect(queue.size()).toBe(1);
|
||||
expect(queue.get(0)).toEqual(testItems.test);
|
||||
});
|
||||
|
||||
it("optimizes append when items are already in order", () => {
|
||||
const queue = new CircularQueue<TestItem>(5);
|
||||
let sortCallCount = 0;
|
||||
|
||||
const trackingSortCallback = (a: TestItem, b: TestItem) => {
|
||||
sortCallCount++;
|
||||
return a.id - b.id;
|
||||
};
|
||||
|
||||
queue.appendWithSorting(testItems.first, trackingSortCallback);
|
||||
expect(sortCallCount).toBe(0);
|
||||
|
||||
queue.appendWithSorting(testItems.second, trackingSortCallback);
|
||||
expect(sortCallCount).toBe(1);
|
||||
|
||||
queue.appendWithSorting(testItems.third, trackingSortCallback);
|
||||
expect(sortCallCount).toBe(2);
|
||||
|
||||
queue.appendWithSorting({ id: 0, value: "zero" }, trackingSortCallback);
|
||||
expect(sortCallCount).toBeGreaterThan(3);
|
||||
|
||||
expect(queue.get(0)).toEqual({ id: 0, value: "zero" });
|
||||
expect(queue.get(1)).toEqual(testItems.first);
|
||||
});
|
||||
});
|
||||
|
||||
describe("popFront", () => {
|
||||
it("removes the oldest item from queue", () => {
|
||||
const queue = createQueueWithItems(3, [testItems.first, testItems.second], sortingCallbacks.byId);
|
||||
|
||||
expect(queue.size()).toBe(2);
|
||||
queue.popFront();
|
||||
expect(queue.size()).toBe(1);
|
||||
expect(queue.get(0)).toEqual(testItems.second);
|
||||
});
|
||||
|
||||
it("handles popping from empty queue", () => {
|
||||
const queue = new CircularQueue<TestItem>(3);
|
||||
|
||||
expect(() => queue.popFront()).not.toThrow();
|
||||
expect(queue.size()).toBe(0);
|
||||
});
|
||||
|
||||
it("handles popping until empty", () => {
|
||||
const queue = createQueueWithItems(2, [testItems.first, testItems.second], sortingCallbacks.byId);
|
||||
|
||||
queue.popFront();
|
||||
expect(queue.size()).toBe(1);
|
||||
queue.popFront();
|
||||
expect(queue.size()).toBe(0);
|
||||
queue.popFront();
|
||||
expect(queue.size()).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("binarySearch", () => {
|
||||
it("finds item using key extractor function", () => {
|
||||
const queue = createQueueWithItems(5, [testItems.apple, testItems.cherry, testItems.grape, testItems.orange], sortingCallbacks.byId);
|
||||
|
||||
const result = queue.binarySearch(5, keyExtractors.id);
|
||||
|
||||
expect(result).toEqual(testItems.grape);
|
||||
});
|
||||
|
||||
it("returns undefined when item not found", () => {
|
||||
const queue = createQueueWithItems(5, [testItems.apple, testItems.cherry, testItems.orange], sortingCallbacks.byId);
|
||||
|
||||
const result = queue.binarySearch(5, keyExtractors.id);
|
||||
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
|
||||
it("finds first item", () => {
|
||||
const queue = createQueueWithItems(5, [testItems.apple, testItems.cherry, testItems.orange], sortingCallbacks.byId);
|
||||
|
||||
const result = queue.binarySearch(1, keyExtractors.id);
|
||||
|
||||
expect(result).toEqual(testItems.apple);
|
||||
});
|
||||
|
||||
it("finds last item", () => {
|
||||
const queue = createQueueWithItems(5, [testItems.apple, testItems.cherry, testItems.orange], sortingCallbacks.byId);
|
||||
|
||||
const result = queue.binarySearch(7, keyExtractors.id);
|
||||
|
||||
expect(result).toEqual(testItems.orange);
|
||||
});
|
||||
|
||||
it("returns undefined for empty queue", () => {
|
||||
const queue = new CircularQueue<TestItem>(5);
|
||||
const result = queue.binarySearch(1, keyExtractors.id);
|
||||
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
|
||||
it("works with string keys", () => {
|
||||
const queue = createQueueWithItems(5, [testItems.apple, testItems.banana, testItems.cherry], sortingCallbacks.byValue);
|
||||
|
||||
const result = queue.binarySearch("banana", keyExtractors.value);
|
||||
|
||||
expect(result).toEqual(testItems.banana);
|
||||
});
|
||||
|
||||
it("maintains sorted order assumption", () => {
|
||||
const queue = createQueueWithItems(5, [testItems.d, testItems.a, testItems.c, testItems.b], sortingCallbacks.byValue);
|
||||
|
||||
expect(queue.binarySearch("a", keyExtractors.value)).toEqual(testItems.a);
|
||||
expect(queue.binarySearch("b", keyExtractors.value)).toEqual(testItems.b);
|
||||
expect(queue.binarySearch("c", keyExtractors.value)).toEqual(testItems.c);
|
||||
expect(queue.binarySearch("d", keyExtractors.value)).toEqual(testItems.d);
|
||||
expect(queue.binarySearch("z", keyExtractors.value)).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe("integration", () => {
|
||||
it("handles appendWithSorting, popFront, and binarySearch together", () => {
|
||||
const queue = createQueueWithItems(3, [testItems.third, testItems.first, testItems.second], sortingCallbacks.byId);
|
||||
|
||||
expect(queue.binarySearch(2, keyExtractors.id)).toEqual(testItems.second);
|
||||
|
||||
queue.popFront();
|
||||
expect(queue.binarySearch(1, keyExtractors.id)).toBeUndefined();
|
||||
expect(queue.binarySearch(2, keyExtractors.id)).toEqual(testItems.second);
|
||||
|
||||
queue.appendWithSorting(testItems.fourth, sortingCallbacks.byId);
|
||||
expect(queue.binarySearch(4, keyExtractors.id)).toEqual(testItems.fourth);
|
||||
});
|
||||
});
|
||||
});
|
||||
45
src/types/__tests__/TupleKeyTests.test.ts
Normal file
45
src/types/__tests__/TupleKeyTests.test.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { describe, expect, it } from "@jest/globals";
|
||||
import { TupleKey } from "../TupleKey";
|
||||
|
||||
describe("TupleKey", () => {
|
||||
it("stores a value copy of the original tuple", () => {
|
||||
const tuple: [string, string] = ["150", "539"];
|
||||
const tupleKey = new TupleKey(...tuple);
|
||||
|
||||
expect(tupleKey.tuple).toEqual(tuple);
|
||||
});
|
||||
|
||||
it("returns a string representation of itself", () => {
|
||||
const tuple: [string, string] = ["150", "539"];
|
||||
const tupleKey = new TupleKey(...tuple);
|
||||
|
||||
expect(`${tupleKey}`).toEqual("150|539");
|
||||
});
|
||||
|
||||
it("supports usage as key in object", () => {
|
||||
const tupleKey1 = new TupleKey("1", "2");
|
||||
const tupleKey2 = new TupleKey("3", "4");
|
||||
|
||||
const sampleObject = {
|
||||
[tupleKey1.toString()]: "value1",
|
||||
[tupleKey2.toString()]: "value2",
|
||||
};
|
||||
|
||||
expect(sampleObject[tupleKey1.toString()]).toEqual("value1");
|
||||
expect(sampleObject[(new TupleKey("1", "2")).toString()]).toEqual("value1");
|
||||
});
|
||||
|
||||
describe("fromExistingStringKey", () => {
|
||||
it("creates a new TupleKey from an existing string key", () => {
|
||||
const strKey = "hello|there";
|
||||
const tupleKey = TupleKey.fromExistingStringKey(strKey);
|
||||
expect(tupleKey.toString()).toEqual(strKey);
|
||||
});
|
||||
|
||||
it("creates an empty tuple if there is no string", () => {
|
||||
const strKey = "";
|
||||
const tupleKey = TupleKey.fromExistingStringKey(strKey);
|
||||
expect(tupleKey.toString()).toEqual(strKey);
|
||||
})
|
||||
})
|
||||
});
|
||||
Reference in New Issue
Block a user