From 760f3ee3c2a538cf15801323950beb28b64c8953 Mon Sep 17 00:00:00 2001 From: NERDDISCO <492378+TimPietrusky@users.noreply.github.com> Date: Wed, 21 Feb 2024 16:46:50 +0100 Subject: [PATCH] feat: added tests for createWindow and unpack, moved jest.setup.ts to the root, installed jest-mock-extended (#51) ## Changes * Added tests for `unpack` and `create-window` * Added `jest-mock-extended` to improve type safety * Added missing `archive.mjs` that was lost in one other PR and is needed for the future build --- jest.config.ts | 1 + jest.config.unit.mjs | 19 ------ tests/jest.setup.js => jest.setup.ts | 8 --- package-lock.json | 23 +++++++ package.json | 3 +- scripts/archive.mjs | 30 ++++++++++ .../utils/__test__/create-window.test.ts | 60 +++++++++++++++++++ .../future/utils/__test__/unpack.test.ts | 6 +- tests/unit/main.helpers.caption.test.ts | 8 --- 9 files changed, 118 insertions(+), 40 deletions(-) delete mode 100644 jest.config.unit.mjs rename tests/jest.setup.js => jest.setup.ts (83%) create mode 100644 scripts/archive.mjs create mode 100644 src/electron/future/utils/__test__/create-window.test.ts rename tests/unit/electron.utils.unpack.test.ts => src/electron/future/utils/__test__/unpack.test.ts (94%) delete mode 100644 tests/unit/main.helpers.caption.test.ts diff --git a/jest.config.ts b/jest.config.ts index 707230e32..f9107b7e7 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -24,6 +24,7 @@ const jestConfig = { }, transformIgnorePatterns: ["/node_modules/"], extensionsToTreatAsEsm: [".ts", ".tsx"], + setupFilesAfterEnv: ["/jest.setup.ts"], }; export default jestConfig; diff --git a/jest.config.unit.mjs b/jest.config.unit.mjs deleted file mode 100644 index aa77adf44..000000000 --- a/jest.config.unit.mjs +++ /dev/null @@ -1,19 +0,0 @@ -import { defaults } from "jest-config"; - -const jestConfig = { - ...defaults, - roots: ["/src/", "/tests/"], - testMatch: ["**/unit/**/*.test.ts"], - collectCoverage: false, - testEnvironment: "node", - preset: "ts-jest", - transformIgnorePatterns: ["/node_modules/(?!(nanoid)/)"], - extensionsToTreatAsEsm: [".ts", ".tsx"], - setupFilesAfterEnv: ["/tests/jest.setup.js"], - moduleNameMapper: { - "^@/(.*)$": "/src/electron/future/$1", - "^#/(.*)$": "/src/shared/$1", - }, -}; - -export default jestConfig; diff --git a/tests/jest.setup.js b/jest.setup.ts similarity index 83% rename from tests/jest.setup.js rename to jest.setup.ts index d645fa3e9..d787f1429 100644 --- a/tests/jest.setup.js +++ b/jest.setup.ts @@ -1,11 +1,3 @@ -global.console = { - log: console.log, - error: console.error, - warn: console.warn, - info: console.info, - debug: console.debug, -}; - jest.mock("electron", () => { const mockBrowserWindow = jest.fn().mockImplementation(() => ({ loadURL: jest.fn(), diff --git a/package-lock.json b/package-lock.json index b84776b8a..f002fbf02 100644 --- a/package-lock.json +++ b/package-lock.json @@ -84,6 +84,7 @@ "jest": "^29.7.0", "jest-config": "^29.7.0", "jest-environment-jsdom": "^29.7.0", + "jest-mock-extended": "^3.0.5", "jest-ts-webcompat-resolver": "^1.0.0", "jotai": "2.6.3", "json5": "^2.2.3", @@ -14855,6 +14856,19 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-mock-extended": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/jest-mock-extended/-/jest-mock-extended-3.0.5.tgz", + "integrity": "sha512-/eHdaNPUAXe7f65gHH5urc8SbRVWjYxBqmCgax2uqOBJy8UUcCBMN1upj1eZ8y/i+IqpyEm4Kq0VKss/GCCTdw==", + "dev": true, + "dependencies": { + "ts-essentials": "^7.0.3" + }, + "peerDependencies": { + "jest": "^24.0.0 || ^25.0.0 || ^26.0.0 || ^27.0.0 || ^28.0.0 || ^29.0.0", + "typescript": "^3.0.0 || ^4.0.0 || ^5.0.0" + } + }, "node_modules/jest-pnp-resolver": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", @@ -23858,6 +23872,15 @@ "typescript": ">=4.2.0" } }, + "node_modules/ts-essentials": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-7.0.3.tgz", + "integrity": "sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==", + "dev": true, + "peerDependencies": { + "typescript": ">=3.7.0" + } + }, "node_modules/ts-jest": { "version": "29.1.2", "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.2.tgz", diff --git a/package.json b/package.json index f427bbcd0..0b74e92de 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "toc": "npx markdown-toc README.md -i", "tsc:noEmit": "tsc --noEmit", "caption:test": "ts-node-esm main/captions/misc.ts", - "test:unit": "jest --runInBand --config jest.config.unit.mjs --verbose", + "test:unit": "jest --runInBand --config jest.config.ts --verbose", "pretest:e2e": "nextron build --no-pack", "test:e2e": "npx playwright test" }, @@ -100,6 +100,7 @@ "jest": "^29.7.0", "jest-config": "^29.7.0", "jest-environment-jsdom": "^29.7.0", + "jest-mock-extended": "^3.0.5", "jest-ts-webcompat-resolver": "^1.0.0", "jotai": "2.6.3", "json5": "^2.2.3", diff --git a/scripts/archive.mjs b/scripts/archive.mjs new file mode 100644 index 000000000..8479ac0a2 --- /dev/null +++ b/scripts/archive.mjs @@ -0,0 +1,30 @@ +import fsp from "node:fs/promises"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +import Seven from "node-7z"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const my7z = path.join(__dirname, "..", "resources", "7zip", "win", "7za.exe"); + +const sourceFolder = path.join(__dirname, "..", "resources", "python-embedded"); +const outputArchive = path.join(__dirname, "..", "resources", "python-embedded.7z"); + +const files = await fsp.readdir(sourceFolder); + +const archive = Seven.add( + outputArchive, + files.map(file => path.join(sourceFolder, file)), + { + $bin: my7z, + recursive: true, + } +); + +archive.on("end", () => { + console.log("Compression finished"); +}); + +archive.on("error", error => { + console.error("Compression error:", error); +}); diff --git a/src/electron/future/utils/__test__/create-window.test.ts b/src/electron/future/utils/__test__/create-window.test.ts new file mode 100644 index 000000000..33c16b4ed --- /dev/null +++ b/src/electron/future/utils/__test__/create-window.test.ts @@ -0,0 +1,60 @@ +import { BrowserWindow } from "electron"; +import Store from "electron-store"; +import type { DeepMockProxy } from "jest-mock-extended"; +import { mockDeep } from "jest-mock-extended"; + +import { createWindow } from "@/utils/create-window"; + +jest.mock("electron", () => ({ + BrowserWindow: jest.fn().mockImplementation(() => ({ + webContents: { + setWindowOpenHandler: jest.fn(), + }, + on: jest.fn(), + isMinimized: jest.fn(), + isMaximized: jest.fn(), + })), + shell: { + openExternal: jest.fn(), + }, + screen: { + getAllDisplays: jest.fn().mockReturnValue([ + { + bounds: { x: 0, y: 0, width: 1024, height: 768 }, + }, + ]), + getPrimaryDisplay: jest.fn().mockReturnValue({ + bounds: { x: 0, y: 0, width: 1920, height: 1080 }, + workArea: { x: 0, y: 0, width: 1920, height: 1040 }, + }), + }, +})); + +jest.mock("electron-store", () => ({ + __esModule: true, + default: jest.fn(), +})); + +describe("createWindow", () => { + const defaultState = { x: 100, y: 100, width: 1024, height: 768 }; + let storeMock: DeepMockProxy; + + beforeEach(() => { + storeMock = mockDeep(); + (Store as unknown as jest.Mock).mockImplementation(() => storeMock); + storeMock.get.mockReturnValue(defaultState); + }); + + it("should create a BrowserWindow with default size when no state is saved", async () => { + await createWindow("testWindow", {}); + + expect(BrowserWindow).toHaveBeenCalledWith( + expect.objectContaining({ + webPreferences: expect.objectContaining({ + contextIsolation: true, + nodeIntegration: false, + }), + }) + ); + }); +}); diff --git a/tests/unit/electron.utils.unpack.test.ts b/src/electron/future/utils/__test__/unpack.test.ts similarity index 94% rename from tests/unit/electron.utils.unpack.test.ts rename to src/electron/future/utils/__test__/unpack.test.ts index 9886a7939..a881f959b 100644 --- a/tests/unit/electron.utils.unpack.test.ts +++ b/src/electron/future/utils/__test__/unpack.test.ts @@ -3,15 +3,13 @@ import Seven from "node-7z"; import { unpack } from "@/utils/unpack"; jest.mock("node-7z", () => ({ - extractFull: jest.fn().mockReturnValue({ + extractFull: jest.fn().mockImplementation(() => ({ on: jest.fn().mockImplementation((event, handler) => { if (event === "end") { process.nextTick(handler); } - - return this; }), - }), + })), })); describe("electron/utils/unpack.ts", () => { diff --git a/tests/unit/main.helpers.caption.test.ts b/tests/unit/main.helpers.caption.test.ts deleted file mode 100644 index 7d3993a74..000000000 --- a/tests/unit/main.helpers.caption.test.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { runWd14 } from "../../main/helpers/caption"; - -describe("helpers/caption.ts", () => { - it("should do captioning with wd14", async () => { - const result = await runWd14(); - expect(result).toEqual("done"); - }); -});