Skip to content

Commit

Permalink
Merge pull request #76 from NoamRa/tests-tests-tests
Browse files Browse the repository at this point in the history
tests!
  • Loading branch information
NoamRa authored Sep 2, 2022
2 parents 4825b14 + b7656f1 commit cace706
Show file tree
Hide file tree
Showing 11 changed files with 25,772 additions and 14,169 deletions.
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"setsar",
"STARTPTS",
"submenu",
"testid",
"timecode",
"togglefullscreen",
"typecheck",
Expand Down
39,714 changes: 25,561 additions & 14,153 deletions package-lock.json

Large diffs are not rendered by default.

36 changes: 24 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@
"lint": "eslint --ext .ts,.tsx,.js,.tsx,.json .",
"lint:fix": "npm run lint -- --fix",
"typecheck": "tsc --noEmit true",
"checks": "npm run typecheck && npm run lint"
"test-renderer": "jest --config src/renderer/jest.renderer.config.js",
"test-renderer:watch": "npm run test-renderer -- --watch",
"test-main": "jest --config src/main/jest.main.config.js",
"test-main:watch": "npm run test-main -- --watch",
"test-all": "npm run test-main && npm run test-renderer",
"checks": "npm run typecheck && npm run lint && npm run test-all"
},
"keywords": [
"FFmpeg",
Expand Down Expand Up @@ -73,7 +78,7 @@
}
},
"devDependencies": {
"@babel/core": "7.18.9",
"@babel/core": "7.18.13",
"@babel/preset-env": "7.18.10",
"@babel/preset-react": "7.18.6",
"@electron-forge/cli": "6.0.0-beta.65",
Expand All @@ -84,33 +89,40 @@
"@electron-forge/plugin-webpack": "6.0.0-beta.65",
"@electron-forge/publisher-github": "6.0.0-beta.65",
"@emotion/eslint-plugin": "11.10.0",
"@testing-library/jest-dom": "5.16.5",
"@testing-library/react": "13.3.0",
"@testing-library/user-event": "14.4.3",
"@types/fs-extra": "9.0.13",
"@types/react": "18.0.15",
"@types/jest": "28.1.8",
"@types/react": "18.0.18",
"@types/react-dom": "18.0.6",
"@typescript-eslint/eslint-plugin": "5.32.0",
"@typescript-eslint/parser": "5.32.0",
"@typescript-eslint/eslint-plugin": "5.36.1",
"@typescript-eslint/parser": "5.36.1",
"@vercel/webpack-asset-relocator-loader": "1.7.3",
"babel-loader": "8.2.5",
"css-loader": "6.7.1",
"electron": "19.0.10",
"eslint": "8.21.0",
"eslint-config-prettier": "8.3.0",
"eslint": "8.23.0",
"eslint-config-prettier": "8.5.0",
"eslint-plugin-import": "2.26.0",
"eslint-plugin-prettier": "4.2.1",
"eslint-plugin-react-hooks": "4.6.0",
"fork-ts-checker-webpack-plugin": "7.2.13",
"jest": "28.1.3",
"jest-environment-jsdom": "29.0.1",
"node-loader": "2.0.0",
"prettier": "2.7.1",
"style-loader": "3.3.1",
"ts-jest": "28.0.8",
"ts-loader": "9.3.1",
"typescript": "4.7.4"
"typescript": "4.8.2"
},
"dependencies": {
"@blueprintjs/core": "4.7.0",
"@emotion/react": "11.10.0",
"@emotion/styled": "11.10.0",
"@blueprintjs/core": "4.9.3",
"@emotion/react": "11.10.4",
"@emotion/styled": "11.10.4",
"electron-squirrel-startup": "1.0.0",
"electron-store": "8.0.0",
"electron-store": "8.1.0",
"fs-extra": "10.1.0",
"react": "18.2.0",
"react-dom": "18.2.0"
Expand Down
20 changes: 20 additions & 0 deletions src/main/ffmpeg/parseProgress.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { parseProgress } from "./parseProgress";

describe("Test parseProgress", () => {
it("should parse progress string", () => {
const example = `
foo=BAR fps=2 width=high! number=5 percent=66%
time=01:23:45.67 last=one
`;
expect(parseProgress(example)).toEqual({
foo: "BAR",
fps: 2,
number: 5,
percent: "66%",
width: "high!",
time: "01:23:45.67",
last: "one",
});
});
});
10 changes: 10 additions & 0 deletions src/main/jest.main.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = {
preset: "ts-jest",
testEnvironment: "node",
transform: {
"^.+\\.tsx?$": "ts-jest",
},
testRegex: ".test.(ts|tsx?)$",
moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"],
};
6 changes: 4 additions & 2 deletions src/main/preload/listenerManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import { ipcRenderer } from "electron";
import { genShortId } from "../utils/generateId";

export type ListenerId = string;
export type Listener<T> = (payload: WithFFmpegId<T>) => void;
export type Listener<T extends Record<string, unknown>> = (
payload: WithFFmpegId<T>,
) => void;
type ChannelAndListener = {
channel: string;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand All @@ -11,7 +13,7 @@ type ChannelAndListener = {

const listeners: Map<ListenerId, ChannelAndListener> = new Map();

export function addListener<T>(
export function addListener<T extends Record<string, unknown>>(
channel: string,
listener: Listener<T>,
): ListenerId {
Expand Down
15 changes: 15 additions & 0 deletions src/main/utils/generateId.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { genShortId } from "./generateId";

describe("Test ID generation", () => {
it("should create unique IDs with prefix", () => {
// for genShortId and its 3 random bytes, 1000 ids should be
// enough of a validation for uniqueness
const length = 1000;
const prefix = "test-short-id";
const IDs = [
...new Set(Array.from({ length }, () => genShortId("test-short-id"))),
];
expect(IDs).toHaveLength(length);
expect(IDs.every((id) => id.includes(prefix))).toBe(true);
});
});
64 changes: 64 additions & 0 deletions src/renderer/App.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import React from "react";
import { fireEvent, render, screen } from "./testUtils/testUtils";
import { App } from "./App";
import { presets } from "./presets";

describe("Test Navigation", () => {
it("should see the app's title and preset selection", () => {
render(<App />);

expect(screen.getByText("Alpha-Badger🦡")).toBeVisible();

expect(screen.getByLabelText("Choose preset:")).toBeVisible();

expect(screen.getAllByRole("option").length).toBe(presets.length);
});

it("should be able to switch between presets and see the preset's description", async () => {
const getOption = (name: string): HTMLOptionElement => {
return screen.getByRole<HTMLOptionElement>("option", { name });
};

render(<App />);

let presetUnderTestIndex = 0;
let presetUnderTest = presets[presetUnderTestIndex];
presets.forEach((preset) => {
if (preset === presetUnderTest) {
expect(screen.getByText(preset.name)).toBeVisible();
expect(getOption(preset.name).selected).toBe(true);
expect(screen.getByText(preset.description)).toBeVisible();
} else {
expect(getOption(preset.name).selected).toBe(false);
expect(screen.queryByText(preset.description)).toBeNull();
}
});

// change to preset 1
presetUnderTestIndex = 1;
presetUnderTest = presets[presetUnderTestIndex];
fireEvent.change(screen.getByLabelText("Choose preset:"), {
target: { value: presetUnderTestIndex },
});

// assert change preset called the API
expect(alphaBadgerApi.setSelectedPresetIndex).toHaveBeenCalledWith(
presetUnderTestIndex,
);
// this asserts the mocked value has changed, unrelated to the state in App.
// may be useful for catching regressions down the line
expect(alphaBadgerApi.getSelectedPresetIndex()).toBe(presetUnderTestIndex);

expect(getOption(presetUnderTest.name).selected).toBe(true);

presets.forEach((preset) => {
if (preset === presetUnderTest) {
expect(getOption(preset.name).selected).toBe(true);
expect(screen.getByText(preset.description)).toBeVisible();
} else {
expect(getOption(preset.name).selected).toBe(false);
expect(screen.queryByText(preset.description)).toBeNull();
}
});
});
});
4 changes: 2 additions & 2 deletions src/renderer/components/Status.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ type StatusProps = {
progress?: UseProgress["progress"];
};

export function Status({ status, progress }: StatusProps) {
const progressEntries = Object.entries(progress ?? {});
export function Status({ status, progress = {} }: StatusProps) {
const progressEntries = Object.entries(progress);

return (
<section id="status">
Expand Down
11 changes: 11 additions & 0 deletions src/renderer/jest.renderer.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */

module.exports = {
preset: "ts-jest",
testEnvironment: "jsdom",
transform: {
"^.+\\.tsx?$": "ts-jest",
},
testRegex: ".test.(ts|tsx?)$",
moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"],
};
60 changes: 60 additions & 0 deletions src/renderer/testUtils/testUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import path from "node:path";
import type { store } from "../../main/store";

import "@testing-library/jest-dom";
export * from "@testing-library/react";

import userEvent from "@testing-library/user-event";
export const user = userEvent.setup();

const mockedStore: typeof store = (() => {
const _store = new Map();

return {
getFFmpegPath: jest.fn((): string => {
return _store.get("ffmpegPath") || "";
}),
setFFmpegPath: jest.fn((ffmpegPath: string): void => {
_store.set("ffmpegPath", ffmpegPath);
}),
getFFprobePath: jest.fn((): string => {
return _store.get("ffprobePath") || "";
}),
setFFprobePath: jest.fn((ffprobePath: string): void => {
_store.set("ffprobePath", ffprobePath);
}),
getSelectedPresetIndex: jest.fn((): number => {
return _store.get("selectedPresetIndex") || 0;
}),
setSelectedPresetIndex: jest.fn((selectedPresetIndex: number): void => {
_store.set("selectedPresetIndex", selectedPresetIndex);
}),
};
})();

const mockedAlphaBadgerAPI: typeof alphaBadgerApi = {
path,
chooseFile: jest.fn(),
chooseFiles: jest.fn(),
chooseFolder: jest.fn(),

readMetadata: jest.fn(),
runFFmpegCommand: jest.fn(),
stopAll: jest.fn(),

// listeners
onError: jest.fn(),
onStart: jest.fn(),
onEnd: jest.fn(),
onProgress: jest.fn(),
onData: jest.fn(),
onCodecData: jest.fn(),
removeListener: jest.fn(),

// preset
getSelectedPresetIndex: mockedStore.getSelectedPresetIndex,
setSelectedPresetIndex: mockedStore.setSelectedPresetIndex,
};

// eslint-disable-next-line @typescript-eslint/no-explicit-any
(globalThis as any)["alphaBadgerApi"] = mockedAlphaBadgerAPI;

0 comments on commit cace706

Please sign in to comment.