-
Notifications
You must be signed in to change notification settings - Fork 0
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
1 parent
efa7231
commit c48d4ba
Showing
5 changed files
with
256 additions
and
32 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import { TaskQueue, Task, LazyTaskQueue } from '../internal/task_queue'; | ||
|
||
describe('Task and TaskQueue', () => { | ||
const taskQueue = new TaskQueue(); | ||
const lazyTaskQueue = new LazyTaskQueue(); | ||
|
||
beforeEach(() => { | ||
taskQueue.clear(); | ||
lazyTaskQueue.clear(); | ||
}); | ||
|
||
test('Task creation and execution', () => { | ||
const callbackMock = jest.fn(); | ||
const task = new Task('Task1', callbackMock); | ||
|
||
expect(task.getTaskName()).toBe('Task1'); | ||
|
||
task.run(); | ||
expect(callbackMock).toHaveBeenCalledWith('Task1'); | ||
}); | ||
|
||
test('TaskQueue add and schedule', () => { | ||
const callbackMock = jest.fn(); | ||
|
||
taskQueue.add('Task1', callbackMock); | ||
taskQueue.schedule('Task1'); | ||
|
||
expect(callbackMock).toHaveBeenCalledWith('Task1'); | ||
}); | ||
|
||
test('TaskQueue clear', () => { | ||
const callbackMock = jest.fn(); | ||
|
||
taskQueue.add('Task1', callbackMock); | ||
taskQueue.add('Task2', callbackMock); | ||
taskQueue.clear(); | ||
|
||
// Use public method to check the length | ||
expect(taskQueue.getQueueLength()).toBe(0); | ||
}); | ||
|
||
test('TaskQueue multiple tasks with the same name', () => { | ||
const callbackMock1 = jest.fn(); | ||
const callbackMock2 = jest.fn(); | ||
|
||
taskQueue.add('Task1', callbackMock1); | ||
taskQueue.add('Task1', callbackMock2); | ||
taskQueue.schedule('Task1'); | ||
|
||
expect(callbackMock1).toHaveBeenCalledWith('Task1'); | ||
expect(callbackMock2).toHaveBeenCalledWith('Task1'); | ||
}); | ||
|
||
test('LazyTaskQueue multiple tasks with the same name', () => { | ||
const callbackMock1 = jest.fn(); | ||
const callbackMock2 = jest.fn(); | ||
|
||
lazyTaskQueue.add('Task1', callbackMock1); | ||
lazyTaskQueue.add('Task1', callbackMock2); | ||
lazyTaskQueue.schedule('Task1'); | ||
|
||
expect(callbackMock1).not.toHaveBeenCalled(); | ||
expect(callbackMock2).toHaveBeenCalledWith('Task1'); | ||
}); | ||
|
||
|
||
test('TaskQueue removing tasks', () => { | ||
const callbackMock1 = jest.fn(); | ||
const callbackMock2 = jest.fn(); | ||
|
||
taskQueue.add('Task1', callbackMock1); | ||
taskQueue.add('Task2', callbackMock2); | ||
|
||
taskQueue.schedule('Task1'); | ||
expect(callbackMock1).toHaveBeenCalledWith('Task1'); | ||
expect(callbackMock2).not.toHaveBeenCalled(); | ||
|
||
// Use public method to check the length | ||
expect(taskQueue.getQueueLength()).toBe(1); | ||
|
||
const _taskQueue = (taskQueue as any); | ||
// Use public method to check if the task was removed | ||
expect(_taskQueue.findTask('Task1')).toBeUndefined(); | ||
}); | ||
}); |
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 |
---|---|---|
@@ -0,0 +1,147 @@ | ||
// Task class represents a task with a name and a callback function | ||
export class Task { | ||
// Private properties | ||
private _name: symbol | string = ""; | ||
private _callback: ((name: any) => void) | void; | ||
|
||
// Constructor to initialize the task with a name and a callback | ||
constructor(name: string | symbol, callback: ((name: symbol | string) => void)) { | ||
this._name = name; | ||
this._callback = callback; | ||
} | ||
|
||
/** | ||
* Get the name of the task. | ||
* @returns {symbol | string} The name of the task. | ||
*/ | ||
public getTaskName(): symbol | string { | ||
return this._name; | ||
} | ||
|
||
/** | ||
* Execute the task's callback function. | ||
*/ | ||
public run(): void { | ||
this._callback?.(this._name); | ||
} | ||
} | ||
|
||
|
||
|
||
|
||
// TaskQueue class manages a queue of tasks | ||
export class TaskQueue { | ||
// Private property to store the queue of tasks | ||
private readonly _queue: Task[] = []; | ||
|
||
// Constructor to initialize the task queue | ||
constructor() { } | ||
|
||
/** | ||
* Find all tasks with a given name. | ||
* @param {string | symbol} name - The name of the tasks to find. | ||
* @returns {Task[]} An array of tasks with the specified name. | ||
*/ | ||
protected _findTasksList(name: string | symbol): Task[] { | ||
return this._queue.filter((task: Task) => task.getTaskName() === name); | ||
} | ||
|
||
/** | ||
* Remove all tasks with a given name. | ||
* @param {string | symbol} name - The name of the tasks to remove. | ||
*/ | ||
protected _removeTasks(name: string | symbol): void { | ||
for (let i = this._queue.length - 1; i >= 0; i--) { | ||
const currentTask = this._queue[i]; | ||
if (currentTask && currentTask.getTaskName() === name) { | ||
this._queue.splice(i, 1); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Find a task with a given name. | ||
* @param {string | symbol} name - The name of the task to find. | ||
* @returns {Task | undefined} The task with the specified name, or undefined if not found. | ||
*/ | ||
protected findTask(name: string | symbol): Task | undefined{ | ||
return this._queue.find((task: Task) => task.getTaskName() === name); | ||
} | ||
|
||
|
||
/** | ||
* Find a task with a given name. | ||
* @param {string | symbol} name - The name of the task to find. | ||
* @returns {number} index | ||
*/ | ||
protected findTaskIndex(name: string | symbol):number{ | ||
return this._queue.findIndex((task: Task) => task.getTaskName() === name); | ||
} | ||
|
||
/** | ||
* Add a new task to the queue. | ||
* @param {string | symbol} name - The name of the task. | ||
* @param {((name: symbol | string) => void)} callback - The callback function to execute when the task runs. | ||
*/ | ||
public add(name: string | symbol, callback: ((name: symbol | string) => void)): void { | ||
const task = new Task(name, callback); | ||
this._queue.push(task); | ||
} | ||
|
||
/** | ||
* Execute the task with a given name and remove all tasks with that name. | ||
* @param {string | symbol} name - The name of the tasks to execute and remove. | ||
*/ | ||
public schedule(name: string | symbol): void { | ||
const taskIndex = this.findTaskIndex(name); | ||
const task = this._queue[taskIndex]; | ||
if(taskIndex < 0 || !this._queue.length || !task) return; | ||
task.run(); | ||
this._queue.splice(taskIndex, 1); | ||
// next | ||
this.schedule(name); | ||
} | ||
|
||
/** | ||
* Clear the entire task queue. | ||
*/ | ||
public clear(): void { | ||
this._queue.splice(0, this._queue.length); | ||
} | ||
|
||
|
||
/** | ||
* Get the current length of the task queue. | ||
* @returns {number} The length of the task queue. | ||
*/ | ||
public getQueueLength(): number { | ||
return this._queue.length; | ||
} | ||
} | ||
|
||
|
||
|
||
|
||
|
||
// In order to reduce the number of executions, | ||
// the last execution will overwrite the previous ones and | ||
// only the last task will be executed. | ||
export class LazyTaskQueue extends TaskQueue{ | ||
|
||
|
||
constructor(){ | ||
super() | ||
} | ||
|
||
/** | ||
* Execute the last task with a given name and remove all tasks with that name. | ||
* @param {string | symbol} name - The name of the tasks to execute and remove. | ||
*/ | ||
override schedule(name: string | symbol): void { | ||
const tasksList = this._findTasksList(name); | ||
const finalTask = tasksList[tasksList.length - 1]; | ||
finalTask?.run(); | ||
this._removeTasks(name); | ||
} | ||
|
||
} |
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 |
---|---|---|
|
@@ -39,6 +39,7 @@ | |
"exclude": [ | ||
"node_modules", | ||
"**/__tests__/*", | ||
"./lib/**/*" | ||
"lib", | ||
"index.d.ts" | ||
] | ||
} |