mirror of
https://github.com/TriliumNext/Trilium.git
synced 2026-10-12 02:09:59 +00:00
test: hoist vi.mock() calls to module scope
Vitest hoists `vi.mock`, `vi.unmock` and `vi.hoisted` above everything else in
the file, so a call written inside `beforeAll`, `beforeEach` or a `describe`
callback never runs where it is written. Vitest 4 only warned about the
mismatch; vitest 5 throws, and takes the whole file's collection with it:
Error: 2 calls in "…/tree.spec.ts" were defined outside of the module's
top level scope
Moving each call up to module scope is what already happened at runtime, so no
behaviour changes. Every factory here was self-contained — none read anything
from the hook it sat in — and the hooks keep whatever else they were doing;
content_renderer's held nothing else and goes away.
FormattingToolbar was not in the CI report. It is a client spec, and the
"Test development" job dies at typecheck before it runs any, so the break would
only have surfaced once the typecheck errors were cleared. Found by sweeping
the tree for indented hoisted calls; the sweep's one other hit,
request.spec.ts, is a continuation line of a top-level `const` and is fine.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5
parent
e8eeb68b50
commit
eed9684710
@@ -7,6 +7,20 @@ import { randomString } from "../../services/utils";
|
||||
import { buildNote } from "../../test/easy-froca";
|
||||
import { getFormattingToolbarState } from "./FormattingToolbar";
|
||||
|
||||
vi.mock("../../services/tree.ts", () => ({
|
||||
default: {
|
||||
getActiveContextNotePath() {
|
||||
return "root";
|
||||
},
|
||||
resolveNotePath(inputNotePath: string) {
|
||||
return inputNotePath;
|
||||
},
|
||||
getNoteIdFromUrl(url) {
|
||||
return url.split("/").at(-1);
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
interface NoteContextInfo {
|
||||
type: NoteType;
|
||||
viewScope?: ViewMode;
|
||||
@@ -15,20 +29,6 @@ interface NoteContextInfo {
|
||||
|
||||
describe("Formatting toolbar logic", () => {
|
||||
beforeAll(() => {
|
||||
vi.mock("../../services/tree.ts", () => ({
|
||||
default: {
|
||||
getActiveContextNotePath() {
|
||||
return "root";
|
||||
},
|
||||
resolveNotePath(inputNotePath: string) {
|
||||
return inputNotePath;
|
||||
},
|
||||
getNoteIdFromUrl(url) {
|
||||
return url.split("/").at(-1);
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
buildNote({
|
||||
id: "root",
|
||||
title: "Root"
|
||||
|
||||
@@ -6,6 +6,20 @@ import clipperRoute, { processContent } from "./clipper";
|
||||
|
||||
const { buildNote } = becca_easy_mocking;
|
||||
|
||||
vi.mock("../../services/image.js", () => ({
|
||||
default: {
|
||||
saveImageToAttachment() {
|
||||
return {
|
||||
attachmentId: "foo",
|
||||
title: "encodedTitle",
|
||||
};
|
||||
},
|
||||
// The clipping is read as soon as this answers, so the picture has to be stored by
|
||||
// then; nothing here defers, so there is nothing for the wait to do.
|
||||
awaitImageWrite: async () => {}
|
||||
}
|
||||
}));
|
||||
|
||||
let note!: BNote;
|
||||
|
||||
describe("processContent", () => {
|
||||
@@ -14,19 +28,6 @@ describe("processContent", () => {
|
||||
content: "Hi there"
|
||||
});
|
||||
note.saveAttachment = () => {};
|
||||
vi.mock("../../services/image.js", () => ({
|
||||
default: {
|
||||
saveImageToAttachment() {
|
||||
return {
|
||||
attachmentId: "foo",
|
||||
title: "encodedTitle",
|
||||
};
|
||||
},
|
||||
// The clipping is read as soon as this answers, so the picture has to be stored by
|
||||
// then; nothing here defers, so there is nothing for the wait to do.
|
||||
awaitImageWrite: async () => {}
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
it("processes basic note", async () => {
|
||||
|
||||
@@ -2,7 +2,7 @@ import { trimIndentation } from "@triliumnext/commons";
|
||||
import { sanitize, utils } from "@triliumnext/core";
|
||||
import ejs from "ejs";
|
||||
import { parse } from "node-html-parser";
|
||||
import { beforeAll, describe, expect, it, vi } from "vitest";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { buildShareNote, buildShareNotes } from "../test/shaca_mocking.js";
|
||||
import { getContent, getDefaultTemplatePath, readTemplate, renderCode, renderNoteContent, type Result, shouldSyntaxHighlight } from "./content_renderer.js";
|
||||
@@ -10,16 +10,14 @@ import type SNote from "./shaca/entities/snote.js";
|
||||
import shaca from "./shaca/shaca.js";
|
||||
import shareRoot from "./share_root.js";
|
||||
|
||||
describe("content_renderer", () => {
|
||||
beforeAll(() => {
|
||||
vi.mock("../becca/becca_loader.js", () => ({
|
||||
default: {
|
||||
load: vi.fn(),
|
||||
loaded: Promise.resolve()
|
||||
}
|
||||
}));
|
||||
});
|
||||
vi.mock("../becca/becca_loader.js", () => ({
|
||||
default: {
|
||||
load: vi.fn(),
|
||||
loaded: Promise.resolve()
|
||||
}
|
||||
}));
|
||||
|
||||
describe("content_renderer", () => {
|
||||
it("Reports protected notes not being renderable", () => {
|
||||
const note = buildShareNote({ isProtected: true });
|
||||
const result = getContent(note);
|
||||
|
||||
@@ -8,6 +8,27 @@ import { getContext } from "./context.js";
|
||||
import scriptService, { buildJsx, executeBundle, getScriptBundle } from "./script.js";
|
||||
import ws from "./ws.js";
|
||||
|
||||
vi.mock("./sql.js", () => {
|
||||
return {
|
||||
default: {
|
||||
transactional: (cb: Function) => {
|
||||
cb();
|
||||
},
|
||||
execute: () => {},
|
||||
replace: () => {},
|
||||
getMap: () => {}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock("./sql_init.js", () => {
|
||||
const mock = {
|
||||
initializeDb: () => {},
|
||||
dbReady: Promise.resolve()
|
||||
};
|
||||
return { default: mock, ...mock };
|
||||
});
|
||||
|
||||
describe("Script", () => {
|
||||
// executeBundle enforces the backendScriptingEnabled security toggle (default false).
|
||||
const originalScriptingEnabled = config.Security.backendScriptingEnabled;
|
||||
@@ -26,27 +47,6 @@ describe("Script", () => {
|
||||
vi.spyOn(ws, "sendMessageToAllClients").mockImplementation(() => {}).mockClear();
|
||||
|
||||
buildNote({ id: "root", title: "root" });
|
||||
|
||||
vi.mock("./sql.js", () => {
|
||||
return {
|
||||
default: {
|
||||
transactional: (cb: Function) => {
|
||||
cb();
|
||||
},
|
||||
execute: () => {},
|
||||
replace: () => {},
|
||||
getMap: () => {}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock("./sql_init.js", () => {
|
||||
const mock = {
|
||||
initializeDb: () => {},
|
||||
dbReady: Promise.resolve()
|
||||
};
|
||||
return { default: mock, ...mock };
|
||||
});
|
||||
});
|
||||
|
||||
it("returns result from script", () => {
|
||||
|
||||
@@ -7,6 +7,27 @@ import tree from "./tree.js";
|
||||
import {buildNote} from "../test/becca_easy_mocking.js";
|
||||
import { getContext } from "./context.js";
|
||||
|
||||
vi.mock("./sql.js", () => {
|
||||
return {
|
||||
default: {
|
||||
transactional: (cb: Function) => {
|
||||
cb();
|
||||
},
|
||||
execute: () => {},
|
||||
replace: () => {},
|
||||
getMap: () => {}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock("./sql_init.js", () => {
|
||||
const mock = {
|
||||
initializeDb: () => {},
|
||||
dbReady: Promise.resolve()
|
||||
};
|
||||
return { default: mock, ...mock };
|
||||
});
|
||||
|
||||
describe("Tree", () => {
|
||||
let rootNote!: NoteBuilder;
|
||||
|
||||
@@ -26,27 +47,6 @@ describe("Tree", () => {
|
||||
parentNoteId: "none",
|
||||
notePosition: 10
|
||||
});
|
||||
|
||||
vi.mock("./sql.js", () => {
|
||||
return {
|
||||
default: {
|
||||
transactional: (cb: Function) => {
|
||||
cb();
|
||||
},
|
||||
execute: () => {},
|
||||
replace: () => {},
|
||||
getMap: () => {}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock("./sql_init.js", () => {
|
||||
const mock = {
|
||||
initializeDb: () => {},
|
||||
dbReady: Promise.resolve()
|
||||
};
|
||||
return { default: mock, ...mock };
|
||||
});
|
||||
});
|
||||
it("sorts notes by title (base case)", () => {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user