Skip to content

Commit 6d46ff1

Browse files
authored
Merge pull request #370 from Jameskmonger/queue-t
feat: add Queue<T> to `engine/util`
2 parents 994c442 + daf296f commit 6d46ff1

File tree

3 files changed

+175
-0
lines changed

3 files changed

+175
-0
lines changed

src/engine/util/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ export * from './num';
77
export * from './strings';
88
export * from './time';
99
export * from './varbits';
10+
export * from './queue';

src/engine/util/queue.test.ts

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import { Queue } from './queue'
2+
3+
describe('Queue', () => {
4+
let queue: Queue<number>;
5+
beforeEach(() => {
6+
queue = new Queue<number>();
7+
});
8+
9+
describe('checking Queue length', () => {
10+
it('should be empty when created', () => {
11+
expect(queue.isEmpty).toBe(true);
12+
expect(queue.isNotEmpty).toBe(false);
13+
});
14+
15+
it('should be not empty when an item is added', () => {
16+
queue.enqueue(1);
17+
expect(queue.isEmpty).toBe(false);
18+
expect(queue.isNotEmpty).toBe(true);
19+
});
20+
21+
it('should be empty when all items are removed', () => {
22+
queue.enqueue(1);
23+
queue.dequeue();
24+
expect(queue.isEmpty).toBe(true);
25+
expect(queue.isNotEmpty).toBe(false);
26+
});
27+
28+
it('should return the correct length', () => {
29+
queue.enqueue(1);
30+
queue.enqueue(2);
31+
queue.enqueue(3);
32+
expect(queue.length).toBe(3);
33+
});
34+
});
35+
36+
it('should return the correct items', () => {
37+
queue.enqueue(1);
38+
queue.enqueue(2);
39+
queue.enqueue(3);
40+
expect(queue.items).toEqual([1, 2, 3]);
41+
});
42+
43+
describe('when peeking', () => {
44+
it('should return the correct item', () => {
45+
queue.enqueue(1);
46+
queue.enqueue(2);
47+
queue.enqueue(3);
48+
expect(queue.peek()).toBe(1);
49+
});
50+
51+
it('should not remove the item', () => {
52+
queue.enqueue(1);
53+
queue.enqueue(2);
54+
queue.enqueue(3);
55+
queue.peek();
56+
expect(queue.items).toEqual([1, 2, 3]);
57+
});
58+
59+
it('should return undefined when the queue is empty', () => {
60+
expect(queue.peek()).toBeUndefined();
61+
});
62+
});
63+
64+
describe('when dequeuing', () => {
65+
it('should return the correct item', () => {
66+
queue.enqueue(1);
67+
queue.enqueue(2);
68+
queue.enqueue(3);
69+
expect(queue.dequeue()).toBe(1);
70+
});
71+
72+
it('should remove the item', () => {
73+
queue.enqueue(1);
74+
queue.enqueue(2);
75+
queue.enqueue(3);
76+
queue.dequeue();
77+
expect(queue.items).toEqual([2, 3]);
78+
});
79+
80+
it('should return undefined when the queue is empty', () => {
81+
expect(queue.dequeue()).toBeUndefined();
82+
});
83+
});
84+
85+
describe('when clearing', () => {
86+
it('should remove all items', () => {
87+
queue.enqueue(1);
88+
queue.enqueue(2);
89+
queue.enqueue(3);
90+
queue.clear();
91+
expect(queue.items).toEqual([]);
92+
});
93+
});
94+
95+
describe('when iterating', () => {
96+
it('should iterate over all items', () => {
97+
queue.enqueue(1);
98+
queue.enqueue(2);
99+
queue.enqueue(3);
100+
const items: number[] = [];
101+
for (const item of queue.items) {
102+
items.push(item);
103+
}
104+
expect(items).toEqual([1, 2, 3]);
105+
});
106+
});
107+
})

src/engine/util/queue.ts

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/**
2+
* A first-in-first-out queue.
3+
*
4+
* @author jameskmonger
5+
*/
6+
export class Queue<TItem> {
7+
private _items: TItem[] = [];
8+
9+
/**
10+
* Get the items in the queue.
11+
*/
12+
public get items(): TItem[] {
13+
return this._items;
14+
}
15+
16+
/**
17+
* Get the length of the queue.
18+
*/
19+
public get length(): number {
20+
return this._items.length;
21+
}
22+
23+
/**
24+
* Is the queue empty?
25+
*/
26+
public get isEmpty(): boolean {
27+
return this._items.length === 0;
28+
}
29+
30+
/**
31+
* Does the queue contain items?
32+
*/
33+
public get isNotEmpty(): boolean {
34+
return this._items.length > 0;
35+
}
36+
37+
/**
38+
* Add an item to the end of the queue.
39+
* @param item The item to add.
40+
*/
41+
public enqueue(item: TItem): void {
42+
this._items.push(item);
43+
}
44+
45+
/**
46+
* Remove an item from the front of the queue.
47+
* @returns The item removed.
48+
*/
49+
public dequeue(): TItem {
50+
return this._items.shift();
51+
}
52+
53+
/**
54+
* Get the item at the front of the queue without removing it.
55+
* @returns The item at the front of the queue.
56+
*/
57+
public peek(): TItem {
58+
return this._items[0];
59+
}
60+
61+
/**
62+
* Remove all items from the queue.
63+
*/
64+
public clear(): void {
65+
this._items = [];
66+
}
67+
}

0 commit comments

Comments
 (0)