refactor: add ScriptRunner class
Change-Id: I118adb9ec338e88b40321208b84228886bb6b590
diff --git a/src/common/architecture/scripts/ScriptRunner.test.ts b/src/common/architecture/scripts/ScriptRunner.test.ts
new file mode 100644
index 0000000..7435c8e
--- /dev/null
+++ b/src/common/architecture/scripts/ScriptRunner.test.ts
@@ -0,0 +1,83 @@
+import Script, {
+ ScriptEnvironment,
+ ScriptPage,
+ ScriptRunPhase,
+} from './Script';
+import { beforeEach, expect, it, jest } from '@jest/globals';
+import ScriptRunner from './ScriptRunner';
+
+interface FakeScriptOptions {
+ id: string;
+ priority: number;
+}
+
+class FakeScript extends Script {
+ id: string;
+ priority: number;
+ page: ScriptPage.CommunityConsole;
+ environment: ScriptEnvironment.ContentScript;
+ runPhase: ScriptRunPhase.Main;
+
+ constructor(options: FakeScriptOptions) {
+ super();
+ this.id = options.id;
+ this.priority = options.priority;
+ }
+
+ execute() {}
+}
+
+const fakeScriptMock = jest
+ .spyOn(FakeScript.prototype, 'execute')
+ .mockImplementation(function() {
+ return (this as FakeScript).id;
+ });
+
+beforeEach(() => {
+ jest.clearAllMocks();
+});
+
+it('scripts run in the correct order based on priority', () => {
+ const scriptsConfig = [
+ {
+ script: new FakeScript({
+ id: '1',
+ priority: 1,
+ }),
+ expectedRunPosition: 2,
+ },
+ {
+ script: new FakeScript({
+ id: '2',
+ priority: 1000,
+ }),
+ expectedRunPosition: 3,
+ },
+ {
+ script: new FakeScript({
+ id: '3',
+ priority: 0,
+ }),
+ expectedRunPosition: 1,
+ },
+ {
+ script: new FakeScript({
+ id: '4',
+ priority: 2 ** 31,
+ }),
+ expectedRunPosition: 4,
+ },
+ ];
+
+ const scriptRunner = new ScriptRunner();
+ scriptRunner.add(...scriptsConfig.map((config) => config.script));
+ scriptRunner.run();
+
+ expect(fakeScriptMock).toHaveBeenCalledTimes(scriptsConfig.length);
+ for (const config of scriptsConfig) {
+ expect(fakeScriptMock).toHaveNthReturnedWith(
+ config.expectedRunPosition,
+ config.script.id,
+ );
+ }
+});
diff --git a/src/common/architecture/scripts/ScriptRunner.ts b/src/common/architecture/scripts/ScriptRunner.ts
new file mode 100644
index 0000000..4a2ed2d
--- /dev/null
+++ b/src/common/architecture/scripts/ScriptRunner.ts
@@ -0,0 +1,20 @@
+import Script from './Script';
+
+export default class ScriptRunner {
+ private scripts: Script[] = [];
+
+ add(...scripts: Script[]) {
+ this.scripts.push(...scripts);
+ }
+
+ run() {
+ this.scripts.sort((a, b) => {
+ if (a.priority < b.priority) return -1;
+ if (a.priority > b.priority) return 1;
+ return 0;
+ });
+ for (const script of this.scripts) {
+ script.execute();
+ }
+ }
+}