mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-02-02 18:37:12 +00:00
add unittest
This commit is contained in:
33
.github/workflows/unit-ci.yml
vendored
Normal file
33
.github/workflows/unit-ci.yml
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
# Run Unit test without Harnesses
|
||||
name: unit-ci
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '24.x'
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Install test dependencies (Playwright Chromium)
|
||||
run: npm run test:install-dependencies
|
||||
|
||||
- name: Run unit tests suite
|
||||
run: npm run test:unit
|
||||
@@ -26,6 +26,8 @@
|
||||
"check": "npm run lint && npm run svelte-check",
|
||||
"unittest": "deno test -A --no-check --coverage=cov_profile --v8-flags=--expose-gc --trace-leaks ./src/",
|
||||
"test": "vitest run",
|
||||
"test:unit": "vitest run --config vitest.config.unit.ts",
|
||||
"test:unit:coverage": "vitest run --config vitest.config.unit.ts --coverage",
|
||||
"test:install-playwright": "npx playwright install chromium",
|
||||
"test:install-dependencies": "npm run test:install-playwright",
|
||||
"test:coverage": "vitest run --coverage",
|
||||
|
||||
110
vitest.config.common.ts
Normal file
110
vitest.config.common.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
import { defineConfig } from "vitest/config";
|
||||
import { svelte } from "@sveltejs/vite-plugin-svelte";
|
||||
import { sveltePreprocess } from "svelte-preprocess";
|
||||
import inlineWorkerPlugin from "esbuild-plugin-inline-worker";
|
||||
import path from "path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import fs from "node:fs";
|
||||
import { platform } from "node:process";
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
const manifestJson = JSON.parse(fs.readFileSync("./manifest.json") + "");
|
||||
const packageJson = JSON.parse(fs.readFileSync("./package.json") + "");
|
||||
const updateInfo = JSON.stringify(fs.readFileSync("./updates.md") + "");
|
||||
const prod = false;
|
||||
const moduleAliasPlugin = {
|
||||
name: "module-alias",
|
||||
setup(build: any) {
|
||||
build.onResolve({ filter: /.(dev)(.ts|)$/ }, (args: any) => {
|
||||
// console.log(args.path);
|
||||
if (prod) {
|
||||
const prodTs = args.path.replace(".dev", ".prod");
|
||||
const statFile = prodTs.endsWith(".ts") ? prodTs : prodTs + ".ts";
|
||||
const realPath = path.join(args.resolveDir, statFile);
|
||||
console.log(`Checking ${statFile}`);
|
||||
if (fs.existsSync(realPath)) {
|
||||
console.log(`Replaced ${args.path} with ${prodTs}`);
|
||||
return {
|
||||
path: realPath,
|
||||
namespace: "file",
|
||||
};
|
||||
}
|
||||
}
|
||||
return null;
|
||||
});
|
||||
build.onResolve({ filter: /.(platform)(.ts|)$/ }, (args: any) => {
|
||||
// console.log(args.path);
|
||||
if (prod) {
|
||||
const prodTs = args.path.replace(".platform", ".obsidian");
|
||||
const statFile = prodTs.endsWith(".ts") ? prodTs : prodTs + ".ts";
|
||||
const realPath = path.join(args.resolveDir, statFile);
|
||||
console.log(`Checking ${statFile}`);
|
||||
if (fs.existsSync(realPath)) {
|
||||
console.log(`Replaced ${args.path} with ${prodTs}`);
|
||||
return {
|
||||
path: realPath,
|
||||
namespace: "file",
|
||||
};
|
||||
}
|
||||
}
|
||||
return null;
|
||||
});
|
||||
},
|
||||
};
|
||||
const externals = [
|
||||
"obsidian",
|
||||
"electron",
|
||||
"crypto",
|
||||
"@codemirror/autocomplete",
|
||||
"@codemirror/collab",
|
||||
"@codemirror/commands",
|
||||
"@codemirror/language",
|
||||
"@codemirror/lint",
|
||||
"@codemirror/search",
|
||||
"@codemirror/state",
|
||||
"@codemirror/view",
|
||||
"@lezer/common",
|
||||
"@lezer/highlight",
|
||||
"@lezer/lr",
|
||||
];
|
||||
const define = {
|
||||
MANIFEST_VERSION: `"${manifestJson.version}"`,
|
||||
PACKAGE_VERSION: `"${packageJson.version}"`,
|
||||
UPDATE_INFO: `${updateInfo}`,
|
||||
global: "globalThis",
|
||||
hostPlatform: `"${platform}"`,
|
||||
};
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
moduleAliasPlugin,
|
||||
inlineWorkerPlugin({
|
||||
external: externals,
|
||||
treeShaking: true,
|
||||
}),
|
||||
svelte({
|
||||
preprocess: sveltePreprocess(),
|
||||
compilerOptions: { css: "injected", preserveComments: false },
|
||||
}),
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
obsidian: path.resolve(__dirname, "./test/harness/obsidian-mock.ts"),
|
||||
"@": path.resolve(__dirname, "./src"),
|
||||
"@lib": path.resolve(__dirname, "./src/lib/src"),
|
||||
src: path.resolve(__dirname, "./src"),
|
||||
},
|
||||
},
|
||||
esbuild: {
|
||||
define: define,
|
||||
target: "es2018",
|
||||
platform: "browser",
|
||||
},
|
||||
// define,
|
||||
server: {
|
||||
headers: {
|
||||
"Service-Worker-Allowed": "/",
|
||||
},
|
||||
port: 5173,
|
||||
},
|
||||
});
|
||||
236
vitest.config.ts
236
vitest.config.ts
@@ -1,180 +1,76 @@
|
||||
import { defineConfig } from "vitest/config";
|
||||
import { defineConfig, mergeConfig } from "vitest/config";
|
||||
import { playwright } from "@vitest/browser-playwright";
|
||||
import { svelte } from "@sveltejs/vite-plugin-svelte";
|
||||
import { sveltePreprocess } from "svelte-preprocess";
|
||||
import inlineWorkerPlugin from "esbuild-plugin-inline-worker";
|
||||
import path from "path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import fs from "node:fs";
|
||||
import viteConfig from "./vitest.config.common";
|
||||
import dotenv from "dotenv";
|
||||
import { platform } from "node:process";
|
||||
|
||||
import { acceptWebPeer, closeWebPeer, grantClipboardPermissions, openWebPeer } from "./test/lib/commands.ts";
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
import { grantClipboardPermissions, openWebPeer, closeWebPeer, acceptWebPeer } from "./test/lib/commands";
|
||||
const defEnv = dotenv.config({ path: ".env" }).parsed;
|
||||
const testEnv = dotenv.config({ path: ".test.env" }).parsed;
|
||||
const env = Object.assign({}, defEnv, testEnv);
|
||||
const debuggerEnabled = env?.ENABLE_DEBUGGER === "true";
|
||||
const enableUI = env?.ENABLE_UI === "true";
|
||||
// const livesyncLogsEnabled = env?.PRINT_LIVESYNC_LOGS === "true";
|
||||
const headless = !debuggerEnabled && !enableUI;
|
||||
const manifestJson = JSON.parse(fs.readFileSync("./manifest.json") + "");
|
||||
const packageJson = JSON.parse(fs.readFileSync("./package.json") + "");
|
||||
const updateInfo = JSON.stringify(fs.readFileSync("./updates.md") + "");
|
||||
const prod = false;
|
||||
const moduleAliasPlugin = {
|
||||
name: "module-alias",
|
||||
setup(build: any) {
|
||||
build.onResolve({ filter: /.(dev)(.ts|)$/ }, (args: any) => {
|
||||
// console.log(args.path);
|
||||
if (prod) {
|
||||
const prodTs = args.path.replace(".dev", ".prod");
|
||||
const statFile = prodTs.endsWith(".ts") ? prodTs : prodTs + ".ts";
|
||||
const realPath = path.join(args.resolveDir, statFile);
|
||||
console.log(`Checking ${statFile}`);
|
||||
if (fs.existsSync(realPath)) {
|
||||
console.log(`Replaced ${args.path} with ${prodTs}`);
|
||||
return {
|
||||
path: realPath,
|
||||
namespace: "file",
|
||||
};
|
||||
}
|
||||
}
|
||||
return null;
|
||||
});
|
||||
build.onResolve({ filter: /.(platform)(.ts|)$/ }, (args: any) => {
|
||||
// console.log(args.path);
|
||||
if (prod) {
|
||||
const prodTs = args.path.replace(".platform", ".obsidian");
|
||||
const statFile = prodTs.endsWith(".ts") ? prodTs : prodTs + ".ts";
|
||||
const realPath = path.join(args.resolveDir, statFile);
|
||||
console.log(`Checking ${statFile}`);
|
||||
if (fs.existsSync(realPath)) {
|
||||
console.log(`Replaced ${args.path} with ${prodTs}`);
|
||||
return {
|
||||
path: realPath,
|
||||
namespace: "file",
|
||||
};
|
||||
}
|
||||
}
|
||||
return null;
|
||||
});
|
||||
},
|
||||
};
|
||||
const externals = [
|
||||
"obsidian",
|
||||
"electron",
|
||||
"crypto",
|
||||
"@codemirror/autocomplete",
|
||||
"@codemirror/collab",
|
||||
"@codemirror/commands",
|
||||
"@codemirror/language",
|
||||
"@codemirror/lint",
|
||||
"@codemirror/search",
|
||||
"@codemirror/state",
|
||||
"@codemirror/view",
|
||||
"@lezer/common",
|
||||
"@lezer/highlight",
|
||||
"@lezer/lr",
|
||||
];
|
||||
const define = {
|
||||
MANIFEST_VERSION: `"${manifestJson.version}"`,
|
||||
PACKAGE_VERSION: `"${packageJson.version}"`,
|
||||
UPDATE_INFO: `${updateInfo}`,
|
||||
global: "globalThis",
|
||||
hostPlatform: `"${platform}"`,
|
||||
};
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
moduleAliasPlugin,
|
||||
inlineWorkerPlugin({
|
||||
external: externals,
|
||||
treeShaking: true,
|
||||
}),
|
||||
svelte({
|
||||
preprocess: sveltePreprocess(),
|
||||
compilerOptions: { css: "injected", preserveComments: false },
|
||||
}),
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
obsidian: path.resolve(__dirname, "./test/harness/obsidian-mock.ts"),
|
||||
"@": path.resolve(__dirname, "./src"),
|
||||
"@lib": path.resolve(__dirname, "./src/lib/src"),
|
||||
src: path.resolve(__dirname, "./src"),
|
||||
},
|
||||
},
|
||||
esbuild: {
|
||||
define: define,
|
||||
target: "es2018",
|
||||
platform: "browser",
|
||||
},
|
||||
// define,
|
||||
server: {
|
||||
headers: {
|
||||
"Service-Worker-Allowed": "/",
|
||||
},
|
||||
port: 5173,
|
||||
},
|
||||
test: {
|
||||
env: env,
|
||||
testTimeout: 40000,
|
||||
hookTimeout: 50000,
|
||||
fileParallelism: false,
|
||||
isolate: true,
|
||||
watch: false,
|
||||
|
||||
// environment: "browser",
|
||||
include: ["test/**/*.test.ts"],
|
||||
coverage: {
|
||||
include: ["src/**/*.ts", "src/lib/src/**/*.ts", "src/**/*.svelte"],
|
||||
exclude: ["**/*.test.ts", "src/lib/**"],
|
||||
provider: "v8",
|
||||
reporter: ["text", "json", "html"],
|
||||
// ignoreEmptyLines: true,
|
||||
},
|
||||
browser: {
|
||||
isolate: true,
|
||||
commands: {
|
||||
grantClipboardPermissions,
|
||||
openWebPeer,
|
||||
closeWebPeer,
|
||||
acceptWebPeer,
|
||||
},
|
||||
provider: playwright({
|
||||
launchOptions: {
|
||||
args: ["--js-flags=--expose-gc"],
|
||||
// chromiumSandbox: true,
|
||||
},
|
||||
}),
|
||||
enabled: true,
|
||||
screenshotFailures: false,
|
||||
instances: [
|
||||
{
|
||||
execArgv: ["--js-flags=--expose-gc"],
|
||||
browser: "chromium",
|
||||
headless,
|
||||
isolate: true,
|
||||
inspector: debuggerEnabled
|
||||
? {
|
||||
waitForDebugger: true,
|
||||
enabled: true,
|
||||
}
|
||||
: undefined,
|
||||
printConsoleTrace: debuggerEnabled,
|
||||
onUnhandledError(error) {
|
||||
// Ignore certain errors
|
||||
const msg = error.message || "";
|
||||
if (msg.includes("Cannot create so many PeerConnections")) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
headless,
|
||||
export default mergeConfig(
|
||||
viteConfig,
|
||||
defineConfig({
|
||||
test: {
|
||||
env: env,
|
||||
testTimeout: 40000,
|
||||
hookTimeout: 50000,
|
||||
fileParallelism: false,
|
||||
ui: debuggerEnabled || enableUI ? true : false,
|
||||
isolate: true,
|
||||
watch: false,
|
||||
|
||||
// environment: "browser",
|
||||
include: ["test/**/*.test.ts"],
|
||||
coverage: {
|
||||
include: ["src/**/*.ts", "src/lib/src/**/*.ts", "src/**/*.svelte"],
|
||||
exclude: ["**/*.test.ts", "src/lib/**"],
|
||||
provider: "v8",
|
||||
reporter: ["text", "json", "html"],
|
||||
// ignoreEmptyLines: true,
|
||||
},
|
||||
browser: {
|
||||
isolate: true,
|
||||
commands: {
|
||||
grantClipboardPermissions,
|
||||
openWebPeer,
|
||||
closeWebPeer,
|
||||
acceptWebPeer,
|
||||
},
|
||||
provider: playwright({
|
||||
launchOptions: {
|
||||
args: ["--js-flags=--expose-gc"],
|
||||
// chromiumSandbox: true,
|
||||
},
|
||||
}),
|
||||
enabled: true,
|
||||
screenshotFailures: false,
|
||||
instances: [
|
||||
{
|
||||
execArgv: ["--js-flags=--expose-gc"],
|
||||
browser: "chromium",
|
||||
headless,
|
||||
isolate: true,
|
||||
inspector: debuggerEnabled
|
||||
? {
|
||||
waitForDebugger: true,
|
||||
enabled: true,
|
||||
}
|
||||
: undefined,
|
||||
printConsoleTrace: debuggerEnabled,
|
||||
onUnhandledError(error) {
|
||||
// Ignore certain errors
|
||||
const msg = error.message || "";
|
||||
if (msg.includes("Cannot create so many PeerConnections")) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
headless,
|
||||
fileParallelism: false,
|
||||
ui: debuggerEnabled || enableUI ? true : false,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
19
vitest.config.unit.ts
Normal file
19
vitest.config.unit.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { defineConfig, mergeConfig } from "vitest/config";
|
||||
import viteConfig from "./vitest.config.common";
|
||||
|
||||
export default mergeConfig(
|
||||
viteConfig,
|
||||
defineConfig({
|
||||
test: {
|
||||
name: "unit-tests",
|
||||
include: ["**/*unit.test.ts"],
|
||||
exclude: ["test/**"],
|
||||
coverage: {
|
||||
include: ["src/**/*.ts"],
|
||||
exclude: ["**/*.test.ts", "src/lib/**/*.test.ts", "**/_*", "src/lib/apps", "src/lib/src/cli"],
|
||||
provider: "v8",
|
||||
reporter: ["text", "json", "html"],
|
||||
},
|
||||
},
|
||||
})
|
||||
);
|
||||
Reference in New Issue
Block a user