Reworked LinkedList and Queue
- Reworked LinkedList and Queue - Written tests for LinkedList and Queue
This commit is contained in:
parent
a2f0b4584f
commit
4f8670c657
@ -12,14 +12,13 @@ export class ApplicationContext
|
||||
|
||||
/**
|
||||
* Called like:
|
||||
*
|
||||
* ```
|
||||
* const registerPlayerInfo = this.applicationContext.getLatestValue(ContextVariableType.REGISTER_PLAYER_REQUEST).getValue<IRegisterPlayerRequestData>();
|
||||
*
|
||||
* const activePlayerSessionId = this.applicationContext.getLatestValue(ContextVariableType.SESSION_ID).getValue<string>();
|
||||
*
|
||||
* const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION).getValue<IGetRaidConfigurationRequestData>();
|
||||
* @param type
|
||||
* @returns
|
||||
* ```
|
||||
*/
|
||||
public getLatestValue(type: ContextVariableType): ContextVariable
|
||||
{
|
||||
@ -27,18 +26,21 @@ export class ApplicationContext
|
||||
{
|
||||
return this.variables.get(type)?.getTail()?.getValue();
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public getValues(type: ContextVariableType): ContextVariable[]
|
||||
{
|
||||
if (this.variables.has(type))
|
||||
{
|
||||
return this.variables.get(type).toList();
|
||||
}
|
||||
const res: ContextVariable[] = [];
|
||||
|
||||
return undefined;
|
||||
for (const value of this.variables.get(type).values())
|
||||
{
|
||||
res.push(value);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
public addValue(type: ContextVariableType, value: any): void
|
||||
@ -53,12 +55,12 @@ export class ApplicationContext
|
||||
list = new LinkedList<ContextVariable>();
|
||||
}
|
||||
|
||||
if (list.getSize() >= ApplicationContext.holderMaxSize)
|
||||
if (list.length >= ApplicationContext.holderMaxSize)
|
||||
{
|
||||
list.removeFirst();
|
||||
list.shift();
|
||||
}
|
||||
|
||||
list.add(new ContextVariable(value, type));
|
||||
list.append(new ContextVariable(value, type));
|
||||
this.variables.set(type, list);
|
||||
}
|
||||
|
||||
|
@ -127,14 +127,14 @@ export class ImporterUtil
|
||||
directoriesToRead.enqueueAll(directories.map((d) => `${filepath}${d}`));
|
||||
filesToProcess.enqueueAll(files.map((f) => new VisitNode(filepath, f)));
|
||||
|
||||
while (!directoriesToRead.isEmpty())
|
||||
while (directoriesToRead.length !== 0)
|
||||
{
|
||||
const directory = directoriesToRead.dequeue();
|
||||
filesToProcess.enqueueAll(this.vfs.getFiles(directory).map((f) => new VisitNode(`${directory}/`, f)));
|
||||
directoriesToRead.enqueueAll(this.vfs.getDirs(directory).map((d) => `${directory}/${d}`));
|
||||
}
|
||||
|
||||
while (!filesToProcess.isEmpty())
|
||||
while (filesToProcess.length !== 0)
|
||||
{
|
||||
const fileNode = filesToProcess.dequeue();
|
||||
if (this.vfs.getFileExtension(fileNode.fileName) === "json")
|
||||
|
@ -1,231 +1,317 @@
|
||||
import { LinkedListNode } from "./Nodes";
|
||||
|
||||
export class LinkedList<T>
|
||||
{
|
||||
private head: LinkedListNode<T>;
|
||||
private tail: LinkedListNode<T>;
|
||||
private head?: LinkedListNode<T>;
|
||||
private tail?: LinkedListNode<T>;
|
||||
private _length: number;
|
||||
|
||||
public add(t: T): void
|
||||
public get length(): number
|
||||
{
|
||||
return this._length;
|
||||
}
|
||||
|
||||
private set length(value: number)
|
||||
{
|
||||
this._length = value;
|
||||
}
|
||||
|
||||
constructor()
|
||||
{
|
||||
this.length = 0;
|
||||
this.head = this.tail = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an element to the start of the list.
|
||||
*/
|
||||
public prepend(value: T): void
|
||||
{
|
||||
const node = new LinkedListNode(value);
|
||||
this.length++;
|
||||
|
||||
if (!this.head)
|
||||
{
|
||||
const node = new LinkedListNode(t);
|
||||
this.head = node;
|
||||
this.tail = node;
|
||||
this.head = this.tail = node;
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
node.next = this.head;
|
||||
this.head.prev = node;
|
||||
this.head = node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an element at the given index to the list.
|
||||
*/
|
||||
public insertAt(value: T, idx: number): void
|
||||
{
|
||||
if (idx < 0 || idx > this.length)
|
||||
{
|
||||
let ref = this.head;
|
||||
let next = this.head.getNextNode();
|
||||
while (next)
|
||||
{
|
||||
ref = next;
|
||||
next = ref.getNextNode();
|
||||
}
|
||||
const node = new LinkedListNode(t, ref);
|
||||
ref.setNextNode(node);
|
||||
this.tail = node;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public addRange(list: T[]): void
|
||||
{
|
||||
for (const item of list)
|
||||
if (idx === 0)
|
||||
{
|
||||
this.add(item);
|
||||
this.prepend(value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public getHead(): LinkedListNode<T>
|
||||
{
|
||||
return this.head;
|
||||
}
|
||||
|
||||
public getTail(): LinkedListNode<T>
|
||||
{
|
||||
return this.tail;
|
||||
}
|
||||
|
||||
public isEmpty(): boolean
|
||||
{
|
||||
return this.head === undefined || this.head === null;
|
||||
}
|
||||
|
||||
public getSize(): number
|
||||
{
|
||||
let size = 0;
|
||||
let next = this.head;
|
||||
while (next)
|
||||
if (idx === this.length)
|
||||
{
|
||||
size++;
|
||||
next = next.getNextNode();
|
||||
this.append(value);
|
||||
return;
|
||||
}
|
||||
|
||||
let ref = this.head;
|
||||
for (let i = 0; i <= idx; ++i)
|
||||
{
|
||||
ref = ref.next;
|
||||
}
|
||||
|
||||
const node = new LinkedListNode(value);
|
||||
this.length++;
|
||||
|
||||
node.next = ref;
|
||||
node.prev = ref.prev;
|
||||
ref.prev = node;
|
||||
|
||||
if (node.prev)
|
||||
{
|
||||
node.prev.next = node;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
public removeFirst(): LinkedListNode<T>
|
||||
/**
|
||||
* Adds an element to the end of the list.
|
||||
*/
|
||||
public append(value: T): void
|
||||
{
|
||||
if (!this.head)
|
||||
{
|
||||
return undefined;
|
||||
}
|
||||
const node = new LinkedListNode(value);
|
||||
this.length++;
|
||||
|
||||
const node = this.head;
|
||||
if (this.head.getNextNode())
|
||||
{
|
||||
this.head = this.head.getNextNode();
|
||||
this.head.setPreviousNode(undefined);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.head = undefined;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
public removeLast(): LinkedListNode<T>
|
||||
{
|
||||
if (!this.tail)
|
||||
{
|
||||
return undefined;
|
||||
this.head = this.tail = node;
|
||||
return;
|
||||
}
|
||||
|
||||
const node = this.tail;
|
||||
if (this.tail.getPreviousNode())
|
||||
node.prev = this.tail;
|
||||
this.tail.next = node;
|
||||
this.tail = this.tail.next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first element's value.
|
||||
*/
|
||||
public getHead(): T
|
||||
{
|
||||
return this.head?.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the element from the list at the given index and returns it's value.
|
||||
*/
|
||||
public get(idx: number): T
|
||||
{
|
||||
if (idx < 0 || idx >= this.length)
|
||||
{
|
||||
this.tail = this.tail.getPreviousNode();
|
||||
this.tail.setNextNode(undefined);
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
if (idx === 0)
|
||||
{
|
||||
return this.getHead();
|
||||
}
|
||||
|
||||
if (idx === this.length - 1)
|
||||
{
|
||||
return this.getTail();
|
||||
}
|
||||
|
||||
for (const [index, value] of this.entries())
|
||||
{
|
||||
if (idx === index)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last element's value.
|
||||
*/
|
||||
public getTail(): T
|
||||
{
|
||||
return this.tail?.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds and removes the first element from a list that has a value equal to the given value, returns it's value if it successfully removed it.
|
||||
*/
|
||||
public remove(value: T): T
|
||||
{
|
||||
let ref = this.head;
|
||||
for (let i = 0; ref && i < this.length; ++i)
|
||||
{
|
||||
if (ref.value === value)
|
||||
{
|
||||
break;
|
||||
}
|
||||
ref = ref.next;
|
||||
}
|
||||
|
||||
if (!ref)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.length--;
|
||||
|
||||
if (this.length === 0)
|
||||
{
|
||||
const out = this.head.value;
|
||||
this.head = this.tail = undefined;
|
||||
return out;
|
||||
}
|
||||
|
||||
if (ref.prev)
|
||||
{
|
||||
ref.prev.next = ref.next;
|
||||
}
|
||||
if (ref.next)
|
||||
{
|
||||
ref.next.prev = ref.prev;
|
||||
}
|
||||
|
||||
if (ref === this.head)
|
||||
{
|
||||
this.head = ref.next;
|
||||
}
|
||||
|
||||
if (ref === this.tail)
|
||||
{
|
||||
this.tail = ref.prev;
|
||||
}
|
||||
|
||||
ref.prev = ref.next = undefined;
|
||||
|
||||
return ref.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the first element from the list and returns it's value. If the list is empty, undefined is returned and the list is not modified.
|
||||
*/
|
||||
public shift(): T
|
||||
{
|
||||
if (!this.head)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.length--;
|
||||
|
||||
const ref = this.head;
|
||||
this.head = this.head.next;
|
||||
|
||||
ref.next = undefined;
|
||||
|
||||
if (this.length === 0)
|
||||
{
|
||||
this.tail = undefined;
|
||||
}
|
||||
return node;
|
||||
|
||||
return ref.value;
|
||||
}
|
||||
|
||||
public indexOf(func: (t: T) => boolean): number
|
||||
/**
|
||||
* Removes the element from the list at the given index and returns it's value.
|
||||
*/
|
||||
public removeAt(idx: number): T
|
||||
{
|
||||
const node = this.head;
|
||||
let index = 0;
|
||||
while (node)
|
||||
if (idx < 0 || idx >= this.length)
|
||||
{
|
||||
if (func(node.getValue()))
|
||||
{
|
||||
return index;
|
||||
}
|
||||
index++;
|
||||
return;
|
||||
}
|
||||
return undefined;
|
||||
|
||||
if (idx === 0)
|
||||
{
|
||||
return this.shift();
|
||||
}
|
||||
|
||||
if (idx === this.length - 1)
|
||||
{
|
||||
return this.pop();
|
||||
}
|
||||
|
||||
let ref = this.head;
|
||||
this.length--;
|
||||
|
||||
for (let i = 0; i < idx; ++i)
|
||||
{
|
||||
ref = ref.next;
|
||||
}
|
||||
|
||||
if (ref.prev)
|
||||
{
|
||||
ref.prev.next = ref.next;
|
||||
}
|
||||
if (ref.next)
|
||||
{
|
||||
ref.next.prev = ref.prev;
|
||||
}
|
||||
|
||||
return ref.value;
|
||||
}
|
||||
|
||||
public contains(func: (t: T) => boolean): boolean
|
||||
/**
|
||||
* Removes the last element from the list and returns it's value. If the list is empty, undefined is returned and the list is not modified.
|
||||
*/
|
||||
public pop(): T
|
||||
{
|
||||
if (!this.tail)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.length--;
|
||||
|
||||
const ref = this.tail;
|
||||
this.tail = this.tail.prev;
|
||||
|
||||
ref.prev = undefined;
|
||||
|
||||
if (this.length === 0)
|
||||
{
|
||||
this.head = undefined;
|
||||
}
|
||||
|
||||
return ref.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterable of index, value pairs for every entry in the list.
|
||||
*/
|
||||
public *entries(): IterableIterator<[number, T]>
|
||||
{
|
||||
let node = this.head;
|
||||
for (let i = 0; i < this.length; ++i)
|
||||
{
|
||||
yield [i, node.value];
|
||||
node = node.next;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterable of values in the list.
|
||||
*/
|
||||
public *values(): IterableIterator<T>
|
||||
{
|
||||
let node = this.head;
|
||||
while (node)
|
||||
{
|
||||
if (func(node.getValue()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
node = node.getNextNode();
|
||||
yield node.value;
|
||||
node = node.next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public forEachNode(func: (t: LinkedListNode<T>) => void): void
|
||||
{
|
||||
let node = this.head;
|
||||
while (node)
|
||||
{
|
||||
func(node);
|
||||
node = node.getNextNode();
|
||||
}
|
||||
}
|
||||
|
||||
public forEachValue(func: (t: T) => void): void
|
||||
{
|
||||
let node = this.head;
|
||||
while (node)
|
||||
{
|
||||
func(node.getValue());
|
||||
node = node.getNextNode();
|
||||
}
|
||||
}
|
||||
|
||||
public findFirstNode(func: (t: LinkedListNode<T>) => boolean): LinkedListNode<T>
|
||||
{
|
||||
let node = this.head;
|
||||
while (node)
|
||||
{
|
||||
if (func(node))
|
||||
{
|
||||
return node;
|
||||
}
|
||||
node = node.getNextNode();
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public findFirstValue(func: (t: T) => boolean): T
|
||||
{
|
||||
let node = this.head;
|
||||
while (node)
|
||||
{
|
||||
if (func(node.getValue()))
|
||||
{
|
||||
return node.getValue();
|
||||
}
|
||||
node = node.getNextNode();
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public toList(): T[]
|
||||
{
|
||||
const elements: T[] = [];
|
||||
let node = this.head;
|
||||
while (node)
|
||||
{
|
||||
elements.push(node.getValue());
|
||||
node = node.getNextNode();
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
}
|
||||
|
||||
export class LinkedListNode<T>
|
||||
{
|
||||
private previous: LinkedListNode<T>;
|
||||
private value: T;
|
||||
private next: LinkedListNode<T>;
|
||||
|
||||
constructor(value: T, previous: LinkedListNode<T> = undefined, next: LinkedListNode<T> = undefined)
|
||||
{
|
||||
this.value = value;
|
||||
this.previous = previous;
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
public getValue(): T
|
||||
{
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public getNextNode(): LinkedListNode<T>
|
||||
{
|
||||
return this.next;
|
||||
}
|
||||
|
||||
public setNextNode(node: LinkedListNode<T>): void
|
||||
{
|
||||
this.next = node;
|
||||
}
|
||||
|
||||
public getPreviousNode(): LinkedListNode<T>
|
||||
{
|
||||
return this.previous;
|
||||
}
|
||||
|
||||
public setPreviousNode(node: LinkedListNode<T>): void
|
||||
{
|
||||
this.previous = node;
|
||||
}
|
||||
}
|
||||
|
5
project/src/utils/collections/lists/Nodes.ts
Normal file
5
project/src/utils/collections/lists/Nodes.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export class LinkedListNode<T>
|
||||
{
|
||||
constructor(public value: T, public prev?: LinkedListNode<T>, public next?: LinkedListNode<T>)
|
||||
{}
|
||||
}
|
@ -1,21 +1,30 @@
|
||||
import { LinkedList } from "../lists/LinkedList";
|
||||
|
||||
export class Queue<T>
|
||||
{
|
||||
private elements: Record<number, T>;
|
||||
private head: number;
|
||||
private tail: number;
|
||||
private list: LinkedList<T>;
|
||||
|
||||
public get length(): number
|
||||
{
|
||||
return this.list.length;
|
||||
}
|
||||
|
||||
constructor()
|
||||
{
|
||||
this.elements = {};
|
||||
this.head = 0;
|
||||
this.tail = 0;
|
||||
this.list = new LinkedList<T>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an element to the end of the queue.
|
||||
*/
|
||||
public enqueue(element: T): void
|
||||
{
|
||||
this.elements[this.tail] = element;
|
||||
this.tail++;
|
||||
this.list.append(element);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates over the elements received and adds each one to the end of the queue.
|
||||
*/
|
||||
public enqueueAll(elements: T[]): void
|
||||
{
|
||||
for (const element of elements)
|
||||
@ -24,25 +33,19 @@ export class Queue<T>
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the first element from the queue and returns it's value. If the queue is empty, undefined is returned and the queue is not modified.
|
||||
*/
|
||||
public dequeue(): T
|
||||
{
|
||||
const item = this.elements[this.head];
|
||||
delete this.elements[this.head];
|
||||
this.head++;
|
||||
return item;
|
||||
return this.list.shift();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first element's value.
|
||||
*/
|
||||
public peek(): T
|
||||
{
|
||||
return this.elements[this.head];
|
||||
}
|
||||
public getLength(): number
|
||||
{
|
||||
return this.tail - this.head;
|
||||
}
|
||||
|
||||
public isEmpty(): boolean
|
||||
{
|
||||
return this.getLength() === 0;
|
||||
return this.list.getHead();
|
||||
}
|
||||
}
|
||||
|
263
project/tests/utils/collections/lists/LinkedList.test.ts
Normal file
263
project/tests/utils/collections/lists/LinkedList.test.ts
Normal file
@ -0,0 +1,263 @@
|
||||
import "reflect-metadata";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { LinkedList } from "@spt-aki/utils/collections/lists/LinkedList";
|
||||
|
||||
describe("LinkedList", () =>
|
||||
{
|
||||
describe("prepend", () =>
|
||||
{
|
||||
const list = new LinkedList<number>();
|
||||
list.prepend(420);
|
||||
list.prepend(69);
|
||||
list.prepend(8008135);
|
||||
list.prepend(1337);
|
||||
|
||||
it("adds elements to the begining of the list", () =>
|
||||
{
|
||||
expect(list.getHead()).toEqual(1337);
|
||||
expect(list.length).toEqual(4);
|
||||
});
|
||||
});
|
||||
|
||||
describe("append", () =>
|
||||
{
|
||||
const list = new LinkedList<number>();
|
||||
list.append(420);
|
||||
list.append(69);
|
||||
list.append(8008135);
|
||||
list.append(1337);
|
||||
|
||||
it("adds elements to the end of the list", () =>
|
||||
{
|
||||
expect(list.getHead()).toEqual(420);
|
||||
expect(list.length).toEqual(4);
|
||||
});
|
||||
});
|
||||
|
||||
describe("insertAt", () =>
|
||||
{
|
||||
describe("empty list", () =>
|
||||
{
|
||||
const list = new LinkedList<number>();
|
||||
|
||||
it("should allow insertions at index 0 only", () =>
|
||||
{
|
||||
list.insertAt(420, 1);
|
||||
expect(list.length).toEqual(0);
|
||||
|
||||
list.insertAt(420, 0);
|
||||
expect(list.length).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe("filled list", () =>
|
||||
{
|
||||
const list = new LinkedList<number>();
|
||||
list.append(420);
|
||||
list.append(69);
|
||||
list.append(8008135);
|
||||
list.append(1337);
|
||||
|
||||
it("shouldn't insert if index is < 0 and > length", () =>
|
||||
{
|
||||
list.insertAt(10100111001, -1);
|
||||
expect(list.length).toEqual(4);
|
||||
|
||||
list.insertAt(123, 5); // index 4 would work even though it's out of bounds because it's the next index, it's the same as doing an append
|
||||
expect(list.length).toEqual(4);
|
||||
});
|
||||
|
||||
it("should insert if index is between 0 and length", () =>
|
||||
{
|
||||
list.insertAt(10100111001, 0);
|
||||
expect(list.length).toEqual(5);
|
||||
|
||||
list.insertAt(69420, 3);
|
||||
expect(list.length).toEqual(6);
|
||||
|
||||
list.insertAt(123, 6);
|
||||
expect(list.length).toEqual(7);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("getHead/getTail", () =>
|
||||
{
|
||||
it("should return undefined if the list is empty", () =>
|
||||
{
|
||||
const list = new LinkedList<number>();
|
||||
expect(list.getHead()).toEqual(undefined);
|
||||
expect(list.getTail()).toEqual(undefined);
|
||||
});
|
||||
|
||||
it("should return the head and the tail values if the list has 1 or more elements", () =>
|
||||
{
|
||||
const list = new LinkedList<number>();
|
||||
list.append(420);
|
||||
list.append(69);
|
||||
list.append(8008135);
|
||||
|
||||
expect(list.getHead()).toEqual(420);
|
||||
expect(list.getTail()).toEqual(8008135);
|
||||
});
|
||||
});
|
||||
|
||||
describe("get", () =>
|
||||
{
|
||||
describe("empty list", () =>
|
||||
{
|
||||
const list = new LinkedList<number>();
|
||||
|
||||
it("should return undefined", () =>
|
||||
{
|
||||
expect(list.get(0)).toEqual(undefined);
|
||||
expect(list.get(1)).toEqual(undefined);
|
||||
});
|
||||
});
|
||||
|
||||
describe("filled list", () =>
|
||||
{
|
||||
const list = new LinkedList<number>();
|
||||
list.append(420);
|
||||
list.append(69);
|
||||
list.append(8008135);
|
||||
list.append(1337);
|
||||
|
||||
it("should return undefined if index is < 0 or >= length", () =>
|
||||
{
|
||||
expect(list.get(-1)).toEqual(undefined);
|
||||
expect(list.get(list.length)).toEqual(undefined);
|
||||
});
|
||||
|
||||
it("should return the value if the index is between 0 and length - 1", () =>
|
||||
{
|
||||
expect(list.get(0)).toEqual(420);
|
||||
expect(list.get(1)).toEqual(69);
|
||||
expect(list.get(list.length - 1)).toEqual(1337);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("remove", () =>
|
||||
{
|
||||
const list = new LinkedList<number>();
|
||||
list.append(420);
|
||||
list.append(69);
|
||||
list.append(8008135);
|
||||
list.append(1337);
|
||||
|
||||
it("should return undefined if it doesn't find any element with the same value", () =>
|
||||
{
|
||||
expect(list.remove(10100111001)).toEqual(undefined);
|
||||
expect(list.length).toEqual(4);
|
||||
});
|
||||
|
||||
it("should remove an element and return it's value if one is found with the same value", () =>
|
||||
{
|
||||
expect(list.remove(420)).toEqual(420);
|
||||
expect(list.length).toEqual(3);
|
||||
|
||||
expect(list.remove(8008135)).toEqual(8008135);
|
||||
expect(list.length).toEqual(2);
|
||||
|
||||
expect(list.remove(1337)).toEqual(1337);
|
||||
expect(list.length).toEqual(1);
|
||||
|
||||
expect(list.remove(69)).toEqual(69);
|
||||
expect(list.length).toEqual(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("shift", () =>
|
||||
{
|
||||
describe("empty list", () =>
|
||||
{
|
||||
const list = new LinkedList<number>();
|
||||
|
||||
it("shouldn't change the list and should return undefined if list is empty", () =>
|
||||
{
|
||||
expect(list.shift()).toEqual(undefined);
|
||||
expect(list.length).toEqual(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("filled list", () =>
|
||||
{
|
||||
const list = new LinkedList<number>();
|
||||
list.append(420);
|
||||
list.append(1337);
|
||||
|
||||
it("should remove the first element and return it's value", () =>
|
||||
{
|
||||
expect(list.shift()).toEqual(420);
|
||||
expect(list.length).toEqual(1);
|
||||
|
||||
expect(list.shift()).toEqual(1337);
|
||||
expect(list.length).toEqual(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("pop", () =>
|
||||
{
|
||||
describe("empty list", () =>
|
||||
{
|
||||
const list = new LinkedList<number>();
|
||||
|
||||
it("shouldn't change the list and should return undefined if list is empty", () =>
|
||||
{
|
||||
expect(list.pop()).toEqual(undefined);
|
||||
expect(list.length).toEqual(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("filled list", () =>
|
||||
{
|
||||
const list = new LinkedList<number>();
|
||||
list.append(420);
|
||||
list.append(1337);
|
||||
|
||||
it("should remove the first element and return it's value", () =>
|
||||
{
|
||||
expect(list.pop()).toEqual(1337);
|
||||
expect(list.length).toEqual(1);
|
||||
|
||||
expect(list.pop()).toEqual(420);
|
||||
expect(list.length).toEqual(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("removeAt", () =>
|
||||
{
|
||||
const list = new LinkedList<number>();
|
||||
list.append(420);
|
||||
list.append(69);
|
||||
list.append(8008135);
|
||||
list.append(1337);
|
||||
list.append(10100111001);
|
||||
|
||||
it("should return undefined if index is < 0 or >= length", () =>
|
||||
{
|
||||
expect(list.removeAt(-1)).toEqual(undefined);
|
||||
expect(list.removeAt(list.length)).toEqual(undefined);
|
||||
});
|
||||
|
||||
it("should remove an element and return it's value if index is between 0 and length - 1", () =>
|
||||
{
|
||||
expect(list.removeAt(0)).toEqual(420);
|
||||
expect(list.length).toEqual(4);
|
||||
|
||||
expect(list.removeAt(2)).toEqual(1337);
|
||||
expect(list.length).toEqual(3);
|
||||
|
||||
expect(list.removeAt(list.length - 1)).toEqual(10100111001);
|
||||
expect(list.length).toEqual(2);
|
||||
|
||||
expect(list.removeAt(1)).toEqual(8008135);
|
||||
expect(list.removeAt(0)).toEqual(69);
|
||||
expect(list.length).toEqual(0);
|
||||
});
|
||||
});
|
||||
});
|
63
project/tests/utils/collections/queue/Queue.test.ts
Normal file
63
project/tests/utils/collections/queue/Queue.test.ts
Normal file
@ -0,0 +1,63 @@
|
||||
import "reflect-metadata";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { Queue } from "@spt-aki/utils/collections/queue/Queue";
|
||||
|
||||
describe("LinkedList", () =>
|
||||
{
|
||||
describe("enqueue", () =>
|
||||
{
|
||||
const queue = new Queue<number>();
|
||||
queue.enqueue(420);
|
||||
queue.enqueue(69);
|
||||
queue.enqueue(8008135);
|
||||
queue.enqueue(1337);
|
||||
|
||||
it("adds elements to the end of the queue", () =>
|
||||
{
|
||||
expect(queue.peek()).toEqual(420);
|
||||
expect(queue.length).toEqual(4);
|
||||
});
|
||||
});
|
||||
|
||||
describe("enqueueAll", () =>
|
||||
{
|
||||
const queue = new Queue<number>();
|
||||
queue.enqueueAll([420, 69, 8008135, 1337]);
|
||||
|
||||
it("iterates the array and adds each element to the end of the queue", () =>
|
||||
{
|
||||
expect(queue.peek()).toEqual(420);
|
||||
expect(queue.length).toEqual(4);
|
||||
});
|
||||
});
|
||||
|
||||
describe("dequeue", () =>
|
||||
{
|
||||
const queue = new Queue<number>();
|
||||
queue.enqueueAll([420, 69, 8008135, 1337]);
|
||||
|
||||
it("removes the first element and return it's value", () =>
|
||||
{
|
||||
expect(queue.dequeue()).toEqual(420);
|
||||
expect(queue.peek()).toEqual(69);
|
||||
expect(queue.length).toEqual(3);
|
||||
|
||||
expect(queue.dequeue()).toEqual(69);
|
||||
expect(queue.peek()).toEqual(8008135);
|
||||
expect(queue.length).toEqual(2);
|
||||
|
||||
expect(queue.dequeue()).toEqual(8008135);
|
||||
expect(queue.peek()).toEqual(1337);
|
||||
expect(queue.length).toEqual(1);
|
||||
|
||||
expect(queue.dequeue()).toEqual(1337);
|
||||
expect(queue.peek()).toEqual(undefined);
|
||||
expect(queue.length).toEqual(0);
|
||||
|
||||
expect(queue.dequeue()).toEqual(undefined);
|
||||
expect(queue.peek()).toEqual(undefined);
|
||||
expect(queue.length).toEqual(0);
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Block a user