-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
37 changed files
with
569 additions
and
815 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,47 +1,49 @@ | ||
import { Queue } from './queue'; | ||
import { describe, it } from 'node:test'; | ||
import assert from 'node:assert'; | ||
|
||
describe('Queue', () => { | ||
it('should initialize with size 0', () => { | ||
const queue = new Queue<number>(); | ||
expect(queue.getSize()).toBe(0); | ||
expect(queue.isEmpty()).toBe(true); | ||
assert.strictEqual(queue.getSize(), 0); | ||
assert.strictEqual(queue.isEmpty(), true); | ||
}); | ||
|
||
it('should enqueue items and update size', () => { | ||
const queue = new Queue<number>(); | ||
queue.enqueue(1); | ||
expect(queue.getSize()).toBe(1); | ||
expect(queue.isEmpty()).toBe(false); | ||
assert.strictEqual(queue.getSize(), 1); | ||
assert.strictEqual(queue.isEmpty(), false); | ||
queue.enqueue(2); | ||
expect(queue.getSize()).toBe(2); | ||
assert.strictEqual(queue.getSize(), 2); | ||
}); | ||
|
||
it('should dequeue items in the correct order', () => { | ||
const queue = new Queue<number>(); | ||
queue.enqueue(1); | ||
queue.enqueue(2); | ||
expect(queue.dequeue()).toBe(1); | ||
expect(queue.getSize()).toBe(1); | ||
expect(queue.dequeue()).toBe(2); | ||
expect(queue.getSize()).toBe(0); | ||
expect(queue.isEmpty()).toBe(true); | ||
assert.strictEqual(queue.dequeue(), 1); | ||
assert.strictEqual(queue.getSize(), 1); | ||
assert.strictEqual(queue.dequeue(), 2); | ||
assert.strictEqual(queue.getSize(), 0); | ||
assert.strictEqual(queue.isEmpty(), true); | ||
}); | ||
|
||
it('should return null when dequeue is called on an empty queue', () => { | ||
const queue = new Queue<number>(); | ||
expect(queue.dequeue()).toBeNull(); | ||
assert.strictEqual(queue.dequeue(), null); | ||
}); | ||
|
||
it('should handle enqueue and dequeue operations correctly', () => { | ||
const queue = new Queue<number>(); | ||
queue.enqueue(1); | ||
queue.enqueue(2); | ||
queue.enqueue(3); | ||
expect(queue.dequeue()).toBe(1); | ||
assert.strictEqual(queue.dequeue(), 1); | ||
queue.enqueue(4); | ||
expect(queue.dequeue()).toBe(2); | ||
expect(queue.dequeue()).toBe(3); | ||
expect(queue.dequeue()).toBe(4); | ||
expect(queue.isEmpty()).toBe(true); | ||
assert.strictEqual(queue.dequeue(), 2); | ||
assert.strictEqual(queue.dequeue(), 3); | ||
assert.strictEqual(queue.dequeue(), 4); | ||
assert.strictEqual(queue.isEmpty(), true); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,90 +1,76 @@ | ||
import { TaskExec } from './task-exec'; | ||
import { sleep } from '../test-utils'; | ||
import { describe, it, mock } from 'node:test'; | ||
import assert from 'node:assert'; | ||
|
||
describe('utils', () => { | ||
it('should verify task executed in time - A:40, B:20 -> B, A', async () => { | ||
const runner = new TaskExec(); | ||
let val = ''; | ||
const funA = jest.fn().mockImplementation(() => { | ||
val += 'A'; | ||
}); | ||
const funB = jest.fn().mockImplementation(() => { | ||
val += 'B'; | ||
}); | ||
const funA = () => { val += 'A'; }; | ||
const funB = () => { val += 'B'; }; | ||
|
||
runner.exec(funA, 100); | ||
|
||
await sleep(20); | ||
|
||
expect(funA).not.toHaveBeenCalled(); | ||
assert.strictEqual(val, ''); | ||
runner.exec(funB, 40); | ||
|
||
await sleep(20); | ||
|
||
expect(funA).not.toHaveBeenCalled(); | ||
expect(funB).not.toHaveBeenCalled(); | ||
assert.strictEqual(val, ''); | ||
|
||
await sleep(40); | ||
|
||
expect(funA).not.toHaveBeenCalled(); | ||
expect(funB).toHaveBeenCalledTimes(1); | ||
assert.strictEqual(val, 'B'); | ||
|
||
await sleep(100); | ||
|
||
expect(funA).toHaveBeenCalledTimes(1); | ||
expect(funB).toHaveBeenCalledTimes(1); | ||
expect(val).toBe('BA'); | ||
assert.strictEqual(val, 'BA'); | ||
}); | ||
|
||
it('should verify task executed in time - A:20, B:40 -> A, B', async () => { | ||
const runner = new TaskExec(); | ||
let val = ''; | ||
const funA = jest.fn().mockImplementation(() => { | ||
val += 'A'; | ||
}); | ||
const funB = jest.fn().mockImplementation(() => { | ||
val += 'B'; | ||
}); | ||
const funA = () => { val += 'A'; }; | ||
const funB = () => { val += 'B'; }; | ||
|
||
runner.exec(funA, 50); | ||
runner.exec(funB, 100); | ||
|
||
await sleep(20); | ||
|
||
expect(funA).not.toHaveBeenCalled(); | ||
expect(funB).not.toHaveBeenCalled(); | ||
assert.strictEqual(val, ''); | ||
|
||
await sleep(50); | ||
|
||
expect(funA).toHaveBeenCalled(); | ||
expect(funB).not.toHaveBeenCalled(); | ||
assert.strictEqual(val, 'A'); | ||
|
||
await sleep(50); | ||
|
||
expect(funA).toHaveBeenCalledTimes(1); | ||
expect(funB).toHaveBeenCalledTimes(1); | ||
expect(val).toBe('AB'); | ||
assert.strictEqual(val, 'AB'); | ||
}); | ||
|
||
it('should verify task executed in time - - A:20, B:20, C:10 -> A, B, C', async () => { | ||
const runner = new TaskExec(); | ||
const funA = jest.fn(); | ||
const funB = jest.fn(); | ||
const funC = jest.fn(); | ||
const funA = mock.fn(); | ||
const funB = mock.fn(); | ||
const funC = mock.fn(); | ||
|
||
runner.exec(funA, 50); | ||
runner.exec(funB, 50); | ||
|
||
await sleep(20); | ||
|
||
expect(funA).not.toHaveBeenCalled(); | ||
expect(funB).not.toHaveBeenCalled(); | ||
assert.equal(funA.mock.callCount(), 0); | ||
assert.equal(funB.mock.callCount(), 0); | ||
runner.exec(funC, 10); | ||
|
||
await sleep(50); | ||
|
||
expect(funA).toHaveBeenCalledTimes(1); | ||
expect(funB).toHaveBeenCalledTimes(1); | ||
expect(funC).toHaveBeenCalledTimes(1); | ||
assert.equal(funA.mock.callCount(), 1); | ||
assert.equal(funB.mock.callCount(), 1); | ||
assert.equal(funC.mock.callCount(), 1); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,20 @@ | ||
import { isPromise } from './utils'; | ||
import { describe, it } from 'node:test'; | ||
import assert from 'node:assert'; | ||
|
||
describe('utils', () => { | ||
describe('isPromise', () => { | ||
it('should return true if a Promise or an object with then attribute', () => { | ||
expect(isPromise(Promise.resolve())).toBe(true); | ||
expect(isPromise({ then: () => null })).toBe(true); | ||
assert.equal(isPromise(Promise.resolve()), true); | ||
assert.equal(isPromise({ then: () => null }), true); | ||
}); | ||
|
||
it('should return false if not a Promise and not an object with then', () => { | ||
expect(isPromise({})).toBe(false); | ||
expect(isPromise(2)).toBe(false); | ||
expect(isPromise(true)).toBe(false); | ||
expect(isPromise(null)).toBe(false); | ||
expect(isPromise(undefined)).toBe(false); | ||
assert.equal(isPromise({}), false); | ||
assert.equal(isPromise(2), false); | ||
assert.equal(isPromise(true), false); | ||
assert.equal(isPromise(null), false); | ||
assert.equal(isPromise(undefined), false); | ||
}); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,108 +1,48 @@ | ||
import { debounce } from './debounce'; | ||
import { sleep } from '../common/test-utils'; | ||
import { describe, it, mock } from 'node:test'; | ||
import assert from 'node:assert'; | ||
|
||
describe('debounce', () => { | ||
it('should make sure error thrown when decorator not set on method', () => { | ||
try { | ||
assert.throws(() => { | ||
const nonValidDebounce: any = debounce(50); | ||
|
||
class T { | ||
@nonValidDebounce | ||
boo: string; | ||
@nonValidDebounce boo: string; | ||
} | ||
} catch (e) { | ||
expect('@debounce is applicable only on a methods.').toBe(e.message); | ||
|
||
return; | ||
} | ||
|
||
throw new Error('should not reach this line'); | ||
}, Error('@debounce is applicable only on a methods.')); | ||
}); | ||
|
||
it('should verify method invocation is debounced', async () => { | ||
const goo = mock.fn(); | ||
|
||
class T { | ||
prop: number; | ||
|
||
@debounce<T>(30) | ||
foo(): void { | ||
return this.goo(); | ||
} | ||
|
||
goo(): void { | ||
expect(this.prop).toBe(3); | ||
@debounce<T>(50) | ||
foo(x: number): void { | ||
return goo(x); | ||
} | ||
} | ||
|
||
const t = new T(); | ||
t.prop = 3; | ||
const spy = jest.spyOn(T.prototype, 'goo'); | ||
t.foo(); // 15 | ||
|
||
expect(spy).not.toHaveBeenCalled(); | ||
|
||
await sleep(10); | ||
expect(spy).toHaveBeenCalledTimes(0); | ||
t.foo(); // 20 | ||
t.foo(1); | ||
t.foo(2); | ||
|
||
await sleep(20); | ||
expect(spy).toHaveBeenCalledTimes(0); | ||
|
||
await sleep(40); | ||
expect(spy).toHaveBeenCalledTimes(1); | ||
}); | ||
|
||
it('should verify method params are passed', (done) => { | ||
class T { | ||
@debounce<T>(5) | ||
foo(x: number, y: number): void { | ||
return this.goo(x, y); | ||
} | ||
|
||
goo(x: number, y: number): void { | ||
|
||
} | ||
} | ||
|
||
const t = new T(); | ||
const spy = jest.spyOn(T.prototype, 'goo'); | ||
t.foo(1, 2); | ||
|
||
setTimeout(() => { | ||
expect(spy).toHaveBeenCalledWith(1, 2); | ||
done(); | ||
}, 10); | ||
}); | ||
|
||
it('should multi instances working', async () => { | ||
class T { | ||
|
||
@debounce<T>(30) | ||
foo(): void { | ||
return this.goo(); | ||
} | ||
|
||
goo(): void { | ||
} | ||
} | ||
|
||
const t1 = new T(); | ||
const t2 = new T(); | ||
const spy1 = jest.spyOn(t1, 'goo'); | ||
const spy2 = jest.spyOn(t1, 'goo'); | ||
t1.foo(); | ||
assert.equal(goo.mock.callCount(), 0); | ||
|
||
expect(spy1).not.toHaveBeenCalled(); | ||
expect(spy2).not.toHaveBeenCalled(); | ||
await sleep(50); | ||
|
||
await sleep(10); | ||
expect(spy1).not.toHaveBeenCalled(); | ||
t2.foo(); // 20 | ||
t.foo(3); | ||
assert.equal(goo.mock.callCount(), 1); | ||
assert.equal(goo.mock.calls[0].arguments.length, 1); | ||
assert.equal(goo.mock.calls[0].arguments[0], 2); | ||
|
||
await sleep(30); // 40 | ||
expect(spy1).toHaveBeenCalledTimes(1); | ||
await sleep(75); | ||
|
||
await sleep(30); // 70 | ||
expect(spy1).toHaveBeenCalledTimes(1); | ||
expect(spy2).toHaveBeenCalledTimes(1); | ||
assert.equal(goo.mock.callCount(), 2); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.