Skip to content

Commit

Permalink
UI: Switching to vitest (#251)
Browse files Browse the repository at this point in the history
* Removing jest and all of its crutches.

* Switching to vitest.

* Improving the coverage of setCountdown() branches.

* Improving the branch coverage for makeMessageHandler().

* Restoring previous implementation of hasPermission flag, as more elegant and now covered by tests.

* Ref: now it's safe to mock not implementation not only once.
  • Loading branch information
RobinTail authored Dec 27, 2023
1 parent f726a5a commit 5d8d25f
Show file tree
Hide file tree
Showing 24 changed files with 517 additions and 1,457 deletions.
5 changes: 2 additions & 3 deletions ui/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
{
"env": {
"es6": true,
"browser": true,
"jest": true
"browser": true
},
"extends": [
"airbnb-typescript/base",
Expand All @@ -24,7 +23,7 @@
},
"overrides": [
{
"files": ["tsup.config.ts"],
"files": ["*.config.*ts", "mocks/*.ts"],
"rules": {
"import/no-extraneous-dependencies": "off"
}
Expand Down
1 change: 1 addition & 0 deletions ui/bindings.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { readFileSync } from "node:fs";
import { JSDOM } from "jsdom";
import { describe, test, expect } from "vitest";

describe("Knockout bindings", () => {
const html = readFileSync(
Expand Down
6 changes: 3 additions & 3 deletions ui/helpers/__snapshots__/actions.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`Actions toggleRelay() action should open the confirmation dialog: .find() 1`] = `
exports[`Actions > toggleRelay() action > should open the confirmation dialog > .find() 1`] = `
[
[
".modal-title",
Expand All @@ -17,7 +17,7 @@ exports[`Actions toggleRelay() action should open the confirmation dialog: .find
]
`;

exports[`Actions toggleRelay() action should open the confirmation dialog: .text() 1`] = `
exports[`Actions > toggleRelay() action > should open the confirmation dialog > .text() 1`] = `
[
[
"Turning Printer off",
Expand Down
34 changes: 17 additions & 17 deletions ui/helpers/__snapshots__/countdown.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`Countdown helpers formatDeadline() helper Should format the supplied UNIX timestamp having offset 0 seconds 1`] = `"in 0 seconds"`;
exports[`Countdown helpers > formatDeadline() helper > Should format the supplied UNIX timestamp having offset 0 seconds 1`] = `"in 0 seconds"`;

exports[`Countdown helpers formatDeadline() helper Should format the supplied UNIX timestamp having offset 1 seconds 1`] = `"in 1 second"`;
exports[`Countdown helpers > formatDeadline() helper > Should format the supplied UNIX timestamp having offset 1 seconds 1`] = `"in 1 second"`;

exports[`Countdown helpers formatDeadline() helper Should format the supplied UNIX timestamp having offset 30 seconds 1`] = `"in 30 seconds"`;
exports[`Countdown helpers > formatDeadline() helper > Should format the supplied UNIX timestamp having offset 30 seconds 1`] = `"in 30 seconds"`;

exports[`Countdown helpers formatDeadline() helper Should format the supplied UNIX timestamp having offset 59 seconds 1`] = `"in 59 seconds"`;
exports[`Countdown helpers > formatDeadline() helper > Should format the supplied UNIX timestamp having offset 59 seconds 1`] = `"in 59 seconds"`;

exports[`Countdown helpers formatDeadline() helper Should format the supplied UNIX timestamp having offset 60 seconds 1`] = `"in 1.0 minutes"`;
exports[`Countdown helpers > formatDeadline() helper > Should format the supplied UNIX timestamp having offset 60 seconds 1`] = `"in 1.0 minutes"`;

exports[`Countdown helpers formatDeadline() helper Should format the supplied UNIX timestamp having offset 61 seconds 1`] = `"in 1.0 minutes"`;
exports[`Countdown helpers > formatDeadline() helper > Should format the supplied UNIX timestamp having offset 61 seconds 1`] = `"in 1.0 minutes"`;

exports[`Countdown helpers formatDeadline() helper Should format the supplied UNIX timestamp having offset 90 seconds 1`] = `"in 1.5 minutes"`;
exports[`Countdown helpers > formatDeadline() helper > Should format the supplied UNIX timestamp having offset 90 seconds 1`] = `"in 1.5 minutes"`;

exports[`Countdown helpers formatDeadline() helper Should format the supplied UNIX timestamp having offset 119 seconds 1`] = `"in 2.0 minutes"`;
exports[`Countdown helpers > formatDeadline() helper > Should format the supplied UNIX timestamp having offset 119 seconds 1`] = `"in 2.0 minutes"`;

exports[`Countdown helpers formatDeadline() helper Should format the supplied UNIX timestamp having offset 120 seconds 1`] = `"in 2 minutes"`;
exports[`Countdown helpers > formatDeadline() helper > Should format the supplied UNIX timestamp having offset 120 seconds 1`] = `"in 2 minutes"`;

exports[`Countdown helpers formatDeadline() helper Should format the supplied UNIX timestamp having offset 121 seconds 1`] = `"in 2 minutes"`;
exports[`Countdown helpers > formatDeadline() helper > Should format the supplied UNIX timestamp having offset 121 seconds 1`] = `"in 2 minutes"`;

exports[`Countdown helpers formatDeadline() helper Should format the supplied UNIX timestamp having offset 300 seconds 1`] = `"in 5 minutes"`;
exports[`Countdown helpers > formatDeadline() helper > Should format the supplied UNIX timestamp having offset 300 seconds 1`] = `"in 5 minutes"`;

exports[`Countdown helpers formatDeadline() helper Should format the supplied UNIX timestamp having offset 600 seconds 1`] = `"in 10 minutes"`;
exports[`Countdown helpers > formatDeadline() helper > Should format the supplied UNIX timestamp having offset 600 seconds 1`] = `"in 10 minutes"`;

exports[`Countdown helpers formatDeadline() helper Should format the supplied UNIX timestamp having offset 3600 seconds 1`] = `"in 1 hour"`;
exports[`Countdown helpers > formatDeadline() helper > Should format the supplied UNIX timestamp having offset 3600 seconds 1`] = `"in 1 hour"`;

exports[`Countdown helpers getCountdownDelay() helper should return refresh interval for supplied timestamp having offset 60 seconds 1`] = `1000`;
exports[`Countdown helpers > getCountdownDelay() helper > should return refresh interval for supplied timestamp having offset 60 seconds 1`] = `1000`;

exports[`Countdown helpers getCountdownDelay() helper should return refresh interval for supplied timestamp having offset 120 seconds 1`] = `1000`;
exports[`Countdown helpers > getCountdownDelay() helper > should return refresh interval for supplied timestamp having offset 120 seconds 1`] = `1000`;

exports[`Countdown helpers getCountdownDelay() helper should return refresh interval for supplied timestamp having offset 121 seconds 1`] = `60000`;
exports[`Countdown helpers > getCountdownDelay() helper > should return refresh interval for supplied timestamp having offset 121 seconds 1`] = `60000`;
14 changes: 7 additions & 7 deletions ui/helpers/__snapshots__/hints.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`Hints helpers addPopover() helper should add a popover to the target element: .find() 1`] = `
exports[`Hints helpers > addPopover() helper > should add a popover to the target element > .find() 1`] = `
[
[
"#pop-closer",
Expand All @@ -14,7 +14,7 @@ exports[`Hints helpers addPopover() helper should add a popover to the target el
]
`;

exports[`Hints helpers addPopover() helper should add a popover to the target element: .popover() 1`] = `
exports[`Hints helpers > addPopover() helper > should add a popover to the target element > .popover() 1`] = `
[
[
{
Expand All @@ -32,7 +32,7 @@ exports[`Hints helpers addPopover() helper should add a popover to the target el
]
`;

exports[`Hints helpers showHints() helper should display tooltips 1`] = `
exports[`Hints helpers > showHints() helper > should display tooltips 1`] = `
[
[
{
Expand All @@ -49,7 +49,7 @@ exports[`Hints helpers showHints() helper should display tooltips 1`] = `
]
`;

exports[`Hints helpers showHints() helper should show popover for a single upcoming task 1`] = `
exports[`Hints helpers > showHints() helper > should show popover for a single upcoming task 1`] = `
[
[
{
Expand All @@ -67,7 +67,7 @@ exports[`Hints helpers showHints() helper should show popover for a single upcom
]
`;

exports[`Hints helpers showHints() helper should show single popover for multiple upcoming tasks 1`] = `
exports[`Hints helpers > showHints() helper > should show single popover for multiple upcoming tasks 1`] = `
[
[
{
Expand All @@ -78,7 +78,7 @@ exports[`Hints helpers showHints() helper should show single popover for multipl
]
`;

exports[`Hints helpers showHints() helper should show single popover for multiple upcoming tasks 2`] = `
exports[`Hints helpers > showHints() helper > should show single popover for multiple upcoming tasks 2`] = `
[
[
{
Expand Down
3 changes: 2 additions & 1 deletion ui/helpers/actions.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { elementMock, jQueryMock } from "../mocks/jQuery";
import { cancelTask, toggleRelay } from "./actions";
import { vi, describe, afterEach, test, expect } from "vitest";

describe("Actions", () => {
const apiMock = jest.fn();
const apiMock = vi.fn();

Object.assign(global, {
OctoPrint: { simpleApiCommand: apiMock },
Expand Down
18 changes: 16 additions & 2 deletions ui/helpers/countdown.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
import MockDate from "mockdate";
import { elementMock, jQueryMock } from "../mocks/jQuery";
import { formatDeadline, getCountdownDelay, setCountdown } from "./countdown";
import {
describe,
vi,
beforeAll,
afterEach,
afterAll,
expect,
test,
} from "vitest";

describe("Countdown helpers", () => {
const setIntervalMock = jest.fn<void, [() => void, number]>(
const setIntervalMock = vi.fn<[() => void, number], void>(
() => "mockedInterval",
);
const clearIntervalMock = jest.fn();
const clearIntervalMock = vi.fn();

Object.assign(global, {
LOCALE: "en",
Expand Down Expand Up @@ -63,6 +72,11 @@ describe("Countdown helpers", () => {
expect.any(Function),
1000,
);
// coverage branch for the case nextDelay === delay
const nextIntervalFn = setIntervalMock.mock.calls[1][0];
MockDate.set(Date.now() + 1000); // same delay branch this time
nextIntervalFn();
expect(setIntervalMock).toHaveBeenCalledTimes(2); // not called again this time
} else {
expect(elementMock.text).not.toHaveBeenCalled();
expect(clearIntervalMock).toHaveBeenCalledWith("mockedInterval");
Expand Down
1 change: 1 addition & 0 deletions ui/helpers/hints.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { countdownMock, deadlineMock, disposerMock } from "../mocks/countdown";
import { cancelMock } from "../mocks/actions";
import { elementMock, jQueryMock } from "../mocks/jQuery";
import { addTooltip, clearHints, addPopover, showHints } from "./hints";
import { describe, beforeAll, afterAll, afterEach, test, expect } from "vitest";

describe("Hints helpers", () => {
Object.assign(global, {
Expand Down
1 change: 1 addition & 0 deletions ui/helpers/narrowing.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { hasUpcomingTask } from "./narrowing";
import { describe, test, expect } from "vitest";

describe("Narrowing helpers", () => {
describe("hasUpcomingTask() helper", () => {
Expand Down
15 changes: 0 additions & 15 deletions ui/jest.config.json

This file was deleted.

6 changes: 4 additions & 2 deletions ui/mocks/OctoRelayModel.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export const modelMock = jest.fn();
import { vi } from "vitest";

jest.mock("../model/OctoRelayModel", () => ({ OctoRelayViewModel: modelMock }));
export const modelMock = vi.fn();

vi.mock("../model/OctoRelayModel", () => ({ OctoRelayViewModel: modelMock }));
8 changes: 5 additions & 3 deletions ui/mocks/actions.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
export const cancelMock = jest.fn();
export const toggleMock = jest.fn();
import { vi } from "vitest";

jest.mock("../helpers/actions", () => ({
export const cancelMock = vi.fn();
export const toggleMock = vi.fn();

vi.mock("../helpers/actions", () => ({
cancelTask: cancelMock,
toggleRelay: toggleMock,
}));
10 changes: 6 additions & 4 deletions ui/mocks/countdown.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
export const disposerMock = jest.fn();
export const countdownMock = jest.fn(() => disposerMock);
export const deadlineMock = jest.fn(() => "sample deadline");
import { vi } from "vitest";

jest.mock("../helpers/countdown", () => ({
export const disposerMock = vi.fn();
export const countdownMock = vi.fn(() => disposerMock);
export const deadlineMock = vi.fn(() => "sample deadline");

vi.mock("../helpers/countdown", () => ({
setCountdown: countdownMock,
formatDeadline: deadlineMock,
}));
8 changes: 5 additions & 3 deletions ui/mocks/hints.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
export const clearMock = jest.fn();
export const showMock = jest.fn();
import { vi } from "vitest";

jest.mock("../helpers/hints", () => ({
export const clearMock = vi.fn();
export const showMock = vi.fn();

vi.mock("../helpers/hints", () => ({
clearHints: clearMock,
showHints: showMock,
}));
26 changes: 14 additions & 12 deletions ui/mocks/jQuery.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { vi, Mock } from "vitest";

export const elementMock: Record<
| "toggle"
| "html"
Expand All @@ -9,21 +11,21 @@ export const elementMock: Record<
| "is"
| "popover"
| "tooltip",
jest.Mock
Mock
> = {
toggle: jest.fn(() => elementMock),
html: jest.fn(() => elementMock),
off: jest.fn(() => elementMock),
on: jest.fn(() => elementMock),
find: jest.fn(() => elementMock),
text: jest.fn(() => elementMock),
modal: jest.fn(() => elementMock),
is: jest.fn(() => elementMock),
tooltip: jest.fn(() => elementMock),
popover: jest.fn(() => elementMock),
toggle: vi.fn(() => elementMock),
html: vi.fn(() => elementMock),
off: vi.fn(() => elementMock),
on: vi.fn(() => elementMock),
find: vi.fn(() => elementMock),
text: vi.fn(() => elementMock),
modal: vi.fn(() => elementMock),
is: vi.fn(() => elementMock),
tooltip: vi.fn(() => elementMock),
popover: vi.fn(() => elementMock),
};

export const jQueryMock = jest.fn((subject: string | (() => void)) => {
export const jQueryMock = vi.fn((subject: string | (() => void)) => {
if (typeof subject === "function") {
return subject();
}
Expand Down
8 changes: 5 additions & 3 deletions ui/mocks/messageHandler.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
export const handlerMock = jest.fn();
import { vi } from "vitest";

jest.mock("../model/messageHandler", () => ({
makeMessageHandler: jest.fn(() => handlerMock),
export const handlerMock = vi.fn();

vi.mock("../model/messageHandler", () => ({
makeMessageHandler: vi.fn(() => handlerMock),
}));
5 changes: 3 additions & 2 deletions ui/model/OctoRelayModel.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { handlerMock } from "../mocks/messageHandler";
import type { OwnModel, OwnProperties } from "../types/OwnModel";
import { OctoRelayViewModel } from "./OctoRelayModel";
import { describe, test, vi, expect } from "vitest";

describe("OctoRelayViewModel", () => {
test("should set certain props of itself", () => {
const dep1 = jest.fn();
const dep2 = jest.fn();
const dep1 = vi.fn();
const dep2 = vi.fn();
OctoRelayViewModel.call(OctoRelayViewModel as OwnModel & OwnProperties, [
dep1,
dep2,
Expand Down
1 change: 1 addition & 0 deletions ui/model/initOctoRelayModel.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { modelMock } from "../mocks/OctoRelayModel";
import { initOctoRelayModel } from "./initOctoRelayModel";
import { describe, test, expect } from "vitest";

describe("initOctorelayModel()", () => {
const registryMock: ViewModel[] = [];
Expand Down
Loading

0 comments on commit 5d8d25f

Please sign in to comment.