test(backend): migrate to vitest (#95)
Use `vitest` for backend tests: - `bench` script now uses [vitest's `bench`](https://vitest.dev/api/#bench) - e2e test fails with same error happening now with jest:`data-testid` attribute not present. vitest left, jest right <img width="1264" height="603" alt="image" src="https://github.com/user-attachments/assets/56fc43a6-e143-4208-bf14-7e016aae7fa9" />
This commit is contained in:
@@ -1,8 +0,0 @@
|
||||
export default {
|
||||
clearMocks: true,
|
||||
transform: {},
|
||||
testEnvironment: "jsdom",
|
||||
coverageProvider: "v8",
|
||||
testMatch: ["<rootDir>/tests/bench/*.bench.{ts,js}"],
|
||||
setupFiles: ["<rootDir>/tests/setup.jest.js"],
|
||||
};
|
||||
@@ -1,7 +0,0 @@
|
||||
export default {
|
||||
coverageProvider: "v8",
|
||||
projects: [
|
||||
"<rootDir>/jest.public-instance.config.js",
|
||||
"<rootDir>/jest.private-instance.config.js",
|
||||
],
|
||||
};
|
||||
@@ -1,7 +0,0 @@
|
||||
export default {
|
||||
clearMocks: true,
|
||||
transform: {},
|
||||
testEnvironment: "node",
|
||||
coverageProvider: "v8",
|
||||
testMatch: ["<rootDir>/tests/e2e/*.test.{ts,js}"],
|
||||
};
|
||||
@@ -1,13 +0,0 @@
|
||||
export default {
|
||||
clearMocks: true,
|
||||
transform: {},
|
||||
testEnvironment: "jsdom",
|
||||
testMatch: [
|
||||
"<rootDir>/tests/*.test.{ts,js}",
|
||||
"<rootDir>/tests/private-instance/*.test.{ts,js}",
|
||||
],
|
||||
setupFiles: [
|
||||
"<rootDir>/tests/setup.jest.js",
|
||||
"<rootDir>/tests/setup.private-instance.jest.js",
|
||||
],
|
||||
};
|
||||
@@ -1,10 +0,0 @@
|
||||
export default {
|
||||
clearMocks: true,
|
||||
transform: {},
|
||||
testEnvironment: "jsdom",
|
||||
testMatch: [
|
||||
"<rootDir>/tests/*.test.{ts,js}",
|
||||
"<rootDir>/tests/public-instance/*.test.{ts,js}",
|
||||
],
|
||||
setupFiles: ["<rootDir>/tests/setup.jest.js"],
|
||||
};
|
||||
@@ -19,27 +19,25 @@
|
||||
"url": "https://github.com/stats-organization/github-stats-extended.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage",
|
||||
"test:watch": "node --experimental-vm-modules node_modules/jest/bin/jest.js --watch",
|
||||
"test:update:snapshot": "node --experimental-vm-modules node_modules/jest/bin/jest.js -u",
|
||||
"test:e2e": "node --experimental-vm-modules node_modules/jest/bin/jest.js --config jest.e2e.config.js",
|
||||
"test": "vitest",
|
||||
"test:update:snapshot": "vitest -u",
|
||||
"test:e2e": "vitest --config vitest.config.e2e.ts",
|
||||
"theme-readme-gen": "node scripts/generate-theme-doc",
|
||||
"generate-langs-json": "node scripts/generate-langs-json",
|
||||
"lint": "npx eslint --max-warnings 0 \"./src/**/*.js\" \"./scripts/**/*.js\" \"./tests/**/*.js\" \"./api-renamed/**/*.js\" \"./themes/**/*.js\"",
|
||||
"bench": "node --experimental-vm-modules node_modules/jest/bin/jest.js --config jest.bench.config.js"
|
||||
"bench": "vitest bench --run --config vitest.config.bench.ts"
|
||||
},
|
||||
"author": "Anurag Hazra",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@jest/globals": "30.2.0",
|
||||
"@testing-library/dom": "^10.4.1",
|
||||
"@testing-library/jest-dom": "^6.9.1",
|
||||
"@uppercod/css-to-object": "^1.1.1",
|
||||
"@vitest/coverage-v8": "catalog:default",
|
||||
"axios-mock-adapter": "^2.1.0",
|
||||
"express": "^5.2.1",
|
||||
"jest": "^30.2.0",
|
||||
"jest-environment-jsdom": "^30.2.0",
|
||||
"js-yaml": "^4.1.1"
|
||||
"js-yaml": "^4.1.1",
|
||||
"jsdom": "28.0.0",
|
||||
"vitest": "catalog:default"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^1.13.5",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`Test Render WakaTime Card should render correctly 1`] = `
|
||||
exports[`Test Render WakaTime Card > should render correctly 1`] = `
|
||||
"
|
||||
<svg
|
||||
width="495"
|
||||
@@ -158,7 +158,7 @@ exports[`Test Render WakaTime Card should render correctly 1`] = `
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`Test Render WakaTime Card should render correctly with compact layout 1`] = `
|
||||
exports[`Test Render WakaTime Card > should render correctly with compact layout 1`] = `
|
||||
"
|
||||
<svg
|
||||
width="495"
|
||||
@@ -310,7 +310,7 @@ exports[`Test Render WakaTime Card should render correctly with compact layout 1
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`Test Render WakaTime Card should render correctly with compact layout when langs_count is set 1`] = `
|
||||
exports[`Test Render WakaTime Card > should render correctly with compact layout when langs_count is set 1`] = `
|
||||
"
|
||||
<svg
|
||||
width="495"
|
||||
@@ -462,7 +462,7 @@ exports[`Test Render WakaTime Card should render correctly with compact layout w
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`Test Render WakaTime Card should render correctly with percent display format 1`] = `
|
||||
exports[`Test Render WakaTime Card > should render correctly with percent display format 1`] = `
|
||||
"
|
||||
<svg
|
||||
width="495"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`Test /api/wakatime should render error if user data is not accessible 1`] = `
|
||||
exports[`Test /api/wakatime > should render error if user data is not accessible 1`] = `
|
||||
"
|
||||
<svg
|
||||
width="495"
|
||||
|
||||
@@ -1,15 +1,8 @@
|
||||
// @ts-check
|
||||
|
||||
import {
|
||||
afterEach,
|
||||
beforeEach,
|
||||
describe,
|
||||
expect,
|
||||
it,
|
||||
jest,
|
||||
} from "@jest/globals";
|
||||
import axios from "axios";
|
||||
import MockAdapter from "axios-mock-adapter";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import api from "../api-renamed/index.js";
|
||||
import { calculateRank } from "../src/calculateRank.js";
|
||||
@@ -52,8 +45,8 @@ const faker = (query, data) => {
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
setHeader: vi.fn(),
|
||||
send: vi.fn(),
|
||||
};
|
||||
mock.onPost("https://api.github.com/graphql").replyOnce(200, data);
|
||||
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import { it, jest } from "@jest/globals";
|
||||
import axios from "axios";
|
||||
import MockAdapter from "axios-mock-adapter";
|
||||
import { bench, describe, vi } from "vitest";
|
||||
|
||||
import api from "../../api-renamed/index.js";
|
||||
|
||||
import { runAndLogStats } from "./utils.js";
|
||||
|
||||
const stats = {
|
||||
name: "Anurag Hazra",
|
||||
totalStars: 100,
|
||||
@@ -63,18 +61,22 @@ const faker = (query, data) => {
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
setHeader: vi.fn(),
|
||||
send: vi.fn(),
|
||||
};
|
||||
mock.onPost("https://api.github.com/graphql").replyOnce(200, data);
|
||||
|
||||
return { req, res };
|
||||
};
|
||||
|
||||
it("test /api", async () => {
|
||||
await runAndLogStats("test /api", async () => {
|
||||
const { req, res } = faker({}, data_stats);
|
||||
describe("/api", () => {
|
||||
bench(
|
||||
"base",
|
||||
async () => {
|
||||
const { req, res } = faker({}, data_stats);
|
||||
|
||||
await api(req, res);
|
||||
});
|
||||
await api(req, res);
|
||||
},
|
||||
{ warmupIterations: 50 },
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
import { it } from "@jest/globals";
|
||||
import { bench, describe } from "vitest";
|
||||
|
||||
import { calculateRank } from "../../src/calculateRank.js";
|
||||
|
||||
import { runAndLogStats } from "./utils.js";
|
||||
|
||||
it("calculateRank", async () => {
|
||||
await runAndLogStats("calculateRank", () => {
|
||||
calculateRank({
|
||||
all_commits: false,
|
||||
commits: 1300,
|
||||
prs: 1500,
|
||||
issues: 4500,
|
||||
reviews: 1000,
|
||||
repos: 0,
|
||||
stars: 600000,
|
||||
followers: 50000,
|
||||
});
|
||||
});
|
||||
describe("calculateRank", () => {
|
||||
bench(
|
||||
"base",
|
||||
async () => {
|
||||
calculateRank({
|
||||
all_commits: false,
|
||||
commits: 1300,
|
||||
prs: 1500,
|
||||
issues: 4500,
|
||||
reviews: 1000,
|
||||
repos: 0,
|
||||
stars: 600000,
|
||||
followers: 50000,
|
||||
});
|
||||
},
|
||||
{ warmupIterations: 50 },
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import { it, jest } from "@jest/globals";
|
||||
import axios from "axios";
|
||||
import MockAdapter from "axios-mock-adapter";
|
||||
import { bench, describe, vi } from "vitest";
|
||||
|
||||
import gist from "../../api-renamed/gist.js";
|
||||
|
||||
import { runAndLogStats } from "./utils.js";
|
||||
|
||||
const gist_data = {
|
||||
data: {
|
||||
viewer: {
|
||||
@@ -36,18 +34,22 @@ const gist_data = {
|
||||
const mock = new MockAdapter(axios);
|
||||
mock.onPost("https://api.github.com/graphql").reply(200, gist_data);
|
||||
|
||||
it("test /api/gist", async () => {
|
||||
await runAndLogStats("test /api/gist", async () => {
|
||||
const req = {
|
||||
query: {
|
||||
id: "bbfce31e0217a3689c8d961a356cb10d",
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
};
|
||||
describe("test /api/gist", () => {
|
||||
bench(
|
||||
"base",
|
||||
async () => {
|
||||
const req = {
|
||||
query: {
|
||||
id: "bbfce31e0217a3689c8d961a356cb10d",
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: vi.fn(),
|
||||
send: vi.fn(),
|
||||
};
|
||||
|
||||
await gist(req, res);
|
||||
});
|
||||
await gist(req, res);
|
||||
},
|
||||
{ warmupIterations: 50 },
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import { it, jest } from "@jest/globals";
|
||||
import axios from "axios";
|
||||
import MockAdapter from "axios-mock-adapter";
|
||||
import { bench, describe, vi } from "vitest";
|
||||
|
||||
import pin from "../../api-renamed/pin.js";
|
||||
|
||||
import { runAndLogStats } from "./utils.js";
|
||||
|
||||
const data_repo = {
|
||||
repository: {
|
||||
username: "anuraghazra",
|
||||
@@ -34,19 +32,23 @@ const data_user = {
|
||||
const mock = new MockAdapter(axios);
|
||||
mock.onPost("https://api.github.com/graphql").reply(200, data_user);
|
||||
|
||||
it("test /api/pin", async () => {
|
||||
await runAndLogStats("test /api/pin", async () => {
|
||||
const req = {
|
||||
query: {
|
||||
username: "anuraghazra",
|
||||
repo: "convoychat",
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
};
|
||||
describe("/api/pin", () => {
|
||||
bench(
|
||||
"base",
|
||||
async () => {
|
||||
const req = {
|
||||
query: {
|
||||
username: "anuraghazra",
|
||||
repo: "convoychat",
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: vi.fn(),
|
||||
send: vi.fn(),
|
||||
};
|
||||
|
||||
await pin(req, res);
|
||||
});
|
||||
await pin(req, res);
|
||||
},
|
||||
{ warmupIterations: 50 },
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1,184 +0,0 @@
|
||||
// @ts-check
|
||||
|
||||
const DEFAULT_RUNS = 1000;
|
||||
const DEFAULT_WARMUPS = 50;
|
||||
|
||||
/**
|
||||
* Formats a duration in nanoseconds to a compact human-readable string.
|
||||
*
|
||||
* @param {bigint} ns Duration in nanoseconds.
|
||||
* @returns {string} Formatted time string.
|
||||
*/
|
||||
const formatTime = (ns) => {
|
||||
if (ns < 1_000n) {
|
||||
return `${ns}ns`;
|
||||
}
|
||||
if (ns < 1_000_000n) {
|
||||
return `${Number(ns) / 1_000}µs`;
|
||||
}
|
||||
if (ns < 1_000_000_000n) {
|
||||
return `${(Number(ns) / 1_000_000).toFixed(3)}ms`;
|
||||
}
|
||||
return `${(Number(ns) / 1_000_000_000).toFixed(3)}s`;
|
||||
};
|
||||
|
||||
/**
|
||||
* Measures synchronous or async function execution time.
|
||||
*
|
||||
* @param {Function} fn Function to measure.
|
||||
* @returns {Promise<bigint>} elapsed nanoseconds
|
||||
*/
|
||||
const measurePerformance = async (fn) => {
|
||||
const start = process.hrtime.bigint();
|
||||
const ret = fn();
|
||||
if (ret instanceof Promise) {
|
||||
await ret;
|
||||
}
|
||||
const end = process.hrtime.bigint();
|
||||
return end - start;
|
||||
};
|
||||
|
||||
/**
|
||||
* Computes basic & extended statistics.
|
||||
*
|
||||
* @param {bigint[]} samples Array of samples in nanoseconds.
|
||||
* @returns {{
|
||||
* runs: number
|
||||
* min: number
|
||||
* max: number
|
||||
* average: number
|
||||
* median: number
|
||||
* p75: number
|
||||
* p95: number
|
||||
* p99: number
|
||||
* stdev: number
|
||||
* totalTime: number
|
||||
* }} Stats
|
||||
*/
|
||||
const computeStats = (samples) => {
|
||||
const sorted = [...samples].sort((a, b) => (a < b ? -1 : 1));
|
||||
const toNumber = (/** @type {bigint} */ b) => Number(b); // safe for typical short benches
|
||||
const n = sorted.length;
|
||||
const sum = sorted.reduce((a, b) => a + b, 0n);
|
||||
const avg = Number(sum) / n;
|
||||
const median =
|
||||
n % 2
|
||||
? toNumber(sorted[(n - 1) / 2])
|
||||
: (toNumber(sorted[n / 2 - 1]) + toNumber(sorted[n / 2])) / 2;
|
||||
const p = (/** @type {number} */ q) => {
|
||||
const idx = Math.min(n - 1, Math.floor((q / 100) * n));
|
||||
return toNumber(sorted[idx]);
|
||||
};
|
||||
const min = toNumber(sorted[0]);
|
||||
const max = toNumber(sorted[n - 1]);
|
||||
const variance =
|
||||
sorted.reduce((acc, v) => acc + (toNumber(v) - avg) ** 2, 0) / n;
|
||||
const stdev = Math.sqrt(variance);
|
||||
|
||||
return {
|
||||
runs: n,
|
||||
min,
|
||||
max,
|
||||
average: avg,
|
||||
median,
|
||||
p75: p(75),
|
||||
p95: p(95),
|
||||
p99: p(99),
|
||||
stdev,
|
||||
totalTime: toNumber(sum),
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Benchmark a function.
|
||||
*
|
||||
* @param {string} fnName Name of the function (for logging).
|
||||
* @param {Function} fn Function to benchmark.
|
||||
* @param {object} [opts] Options.
|
||||
* @param {number} [opts.runs] Number of measured runs.
|
||||
* @param {number} [opts.warmup] Warm-up iterations (not measured).
|
||||
* @param {boolean} [opts.trimOutliers] Drop top & bottom 1% before stats.
|
||||
* @returns {Promise<object>} Stats (nanoseconds for core metrics).
|
||||
*/
|
||||
export const runAndLogStats = async (
|
||||
fnName,
|
||||
fn,
|
||||
{ runs = DEFAULT_RUNS, warmup = DEFAULT_WARMUPS, trimOutliers = false } = {},
|
||||
) => {
|
||||
if (runs <= 0) {
|
||||
throw new Error("Number of runs must be positive.");
|
||||
}
|
||||
|
||||
// Warm-up
|
||||
for (let i = 0; i < warmup; i++) {
|
||||
const ret = fn();
|
||||
if (ret instanceof Promise) {
|
||||
await ret;
|
||||
}
|
||||
}
|
||||
|
||||
const samples = [];
|
||||
for (let i = 0; i < runs; i++) {
|
||||
samples.push(await measurePerformance(fn));
|
||||
}
|
||||
|
||||
let processed = samples;
|
||||
if (trimOutliers && samples.length > 10) {
|
||||
const sorted = [...samples].sort((a, b) => (a < b ? -1 : 1));
|
||||
const cut = Math.max(1, Math.floor(sorted.length * 0.01));
|
||||
processed = sorted.slice(cut, sorted.length - cut);
|
||||
}
|
||||
|
||||
const stats = computeStats(processed);
|
||||
|
||||
const fmt = (/** @type {number} */ ns) => formatTime(BigInt(Math.round(ns)));
|
||||
console.log(
|
||||
`${fnName} | runs=${stats.runs} avg=${fmt(stats.average)} median=${fmt(
|
||||
stats.median,
|
||||
)} p95=${fmt(stats.p95)} min=${fmt(stats.min)} max=${fmt(
|
||||
stats.max,
|
||||
)} stdev=${fmt(stats.stdev)}`,
|
||||
);
|
||||
|
||||
return stats;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an asymmetric matcher for approximate numeric equality.
|
||||
*
|
||||
* This helper is intended for use in test frameworks (e.g., Jest) where
|
||||
* values need to be compared within a configurable decimal precision
|
||||
* instead of strict equality.
|
||||
*
|
||||
* The comparison succeeds when:
|
||||
*
|
||||
* |actual - expected| < 10^(-precision)
|
||||
*
|
||||
* For example, with `precision = 3`, values must be within `0.001`.
|
||||
*
|
||||
* @param {number} expected The expected numeric value to compare against.
|
||||
*
|
||||
* @param {number} [precision=10]
|
||||
* The number of decimal places of tolerance. Higher values mean stricter
|
||||
* comparison. Internally converted to epsilon = 10^-precision.
|
||||
*
|
||||
* @returns {{
|
||||
* asymmetricMatch(actual: unknown): boolean,
|
||||
* toAsymmetricMatcher(): string
|
||||
* }} An object implementing Jest-style asymmetric matcher methods.
|
||||
*
|
||||
*/
|
||||
export function approxNumber(expected, precision = 10) {
|
||||
return {
|
||||
asymmetricMatch(actual) {
|
||||
if (typeof actual !== "number" || typeof expected !== "number") {
|
||||
return false;
|
||||
}
|
||||
const epsilon = Math.pow(10, -precision);
|
||||
return Math.abs(actual - expected) < epsilon;
|
||||
},
|
||||
toAsymmetricMatcher() {
|
||||
return `≈ ${expected} (precision ${precision})`;
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
import { describe, expect, it } from "@jest/globals";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import "@testing-library/jest-dom";
|
||||
import { calculateRank } from "../src/calculateRank.js";
|
||||
|
||||
import { approxNumber } from "./bench/utils.js";
|
||||
import { approxNumber } from "./utils.js";
|
||||
|
||||
import "@testing-library/jest-dom/vitest";
|
||||
|
||||
describe("Test calculateRank", () => {
|
||||
it("new user gets C rank", () => {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { describe, expect, it } from "@jest/globals";
|
||||
import { queryByTestId } from "@testing-library/dom";
|
||||
import "@testing-library/jest-dom";
|
||||
import { cssToObject } from "@uppercod/css-to-object";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { Card } from "../src/common/Card.js";
|
||||
import { getCardColors } from "../src/common/color.js";
|
||||
import { icons } from "../src/common/icons.js";
|
||||
|
||||
import "@testing-library/jest-dom/vitest";
|
||||
|
||||
describe("Card", () => {
|
||||
it("should hide border", () => {
|
||||
const card = new Card({});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { describe, expect, it } from "@jest/globals";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { getCardColors } from "../src/common/color";
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
* @file Contains end-to-end tests for the Vercel preview instance.
|
||||
*/
|
||||
|
||||
import { beforeAll, describe, expect, test } from "@jest/globals";
|
||||
import axios from "axios";
|
||||
import { beforeAll, describe, expect, test } from "vitest";
|
||||
|
||||
import { renderGistCard } from "../../src/cards/gist.js";
|
||||
import { renderRepoCard } from "../../src/cards/repo.js";
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { afterEach, describe, expect, it } from "@jest/globals";
|
||||
import "@testing-library/jest-dom";
|
||||
import axios from "axios";
|
||||
import MockAdapter from "axios-mock-adapter";
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
|
||||
import { fetchGist } from "../src/fetchers/gist.js";
|
||||
|
||||
import "@testing-library/jest-dom/vitest";
|
||||
|
||||
const gist_data = {
|
||||
data: {
|
||||
viewer: {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { afterEach, describe, expect, it } from "@jest/globals";
|
||||
import "@testing-library/jest-dom";
|
||||
import axios from "axios";
|
||||
import MockAdapter from "axios-mock-adapter";
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
|
||||
import { fetchRepo } from "../src/fetchers/repo.js";
|
||||
|
||||
import "@testing-library/jest-dom/vitest";
|
||||
|
||||
const data_repo = {
|
||||
repository: {
|
||||
name: "convoychat",
|
||||
|
||||
@@ -1,18 +1,12 @@
|
||||
/** @jest-environment node */
|
||||
/*
|
||||
Jest must use node for these tests because jsdom doesn't support the structuredClone call in stats.js.
|
||||
https://jestjs.io/docs/configuration#testenvironment-string
|
||||
https://github.com/jsdom/jsdom/issues/3363
|
||||
*/
|
||||
|
||||
import { afterEach, beforeEach, describe, expect, it } from "@jest/globals";
|
||||
import "@testing-library/jest-dom";
|
||||
import axios from "axios";
|
||||
import MockAdapter from "axios-mock-adapter";
|
||||
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
||||
|
||||
import { calculateRank } from "../src/calculateRank.js";
|
||||
import { fetchStats } from "../src/fetchers/stats.js";
|
||||
|
||||
import "@testing-library/jest-dom/vitest";
|
||||
|
||||
// Test parameters.
|
||||
const data_stats = {
|
||||
data: {
|
||||
@@ -260,8 +254,8 @@ describe("Test fetchStats", () => {
|
||||
});
|
||||
|
||||
it("should throw specific error when include_all_commits true and invalid username", async () => {
|
||||
expect(fetchStats("asdf///---", true)).rejects.toThrow(
|
||||
new Error("Invalid username provided."),
|
||||
await expect(fetchStats("asdf///---", true)).rejects.toThrow(
|
||||
"Invalid username provided.",
|
||||
);
|
||||
});
|
||||
|
||||
@@ -272,8 +266,8 @@ describe("Test fetchStats", () => {
|
||||
)
|
||||
.reply(200, { error: "Some test error message" });
|
||||
|
||||
expect(fetchStats("anuraghazra", true)).rejects.toThrow(
|
||||
new Error("Could not fetch data from GitHub REST API."),
|
||||
await expect(fetchStats("anuraghazra", true)).rejects.toThrow(
|
||||
"Could not fetch data from GitHub REST API.",
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { afterEach, describe, expect, it } from "@jest/globals";
|
||||
import "@testing-library/jest-dom";
|
||||
import axios from "axios";
|
||||
import MockAdapter from "axios-mock-adapter";
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
|
||||
import { fetchTopLanguages } from "../src/fetchers/top-languages.js";
|
||||
|
||||
import { approxNumber } from "./bench/utils.js";
|
||||
import { approxNumber } from "./utils.js";
|
||||
|
||||
import "@testing-library/jest-dom/vitest";
|
||||
|
||||
const mock = new MockAdapter(axios);
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { afterEach, describe, expect, it } from "@jest/globals";
|
||||
import "@testing-library/jest-dom";
|
||||
import axios from "axios";
|
||||
import MockAdapter from "axios-mock-adapter";
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
|
||||
import { fetchWakatimeStats } from "../src/fetchers/wakatime.js";
|
||||
|
||||
import "@testing-library/jest-dom/vitest";
|
||||
|
||||
const mock = new MockAdapter(axios);
|
||||
|
||||
afterEach(() => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { describe, expect, it } from "@jest/globals";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { flexLayout } from "../src/common/render.js";
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { describe, expect, it } from "@jest/globals";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import {
|
||||
formatBytes,
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
// @ts-check
|
||||
|
||||
import { afterEach, describe, expect, it, jest } from "@jest/globals";
|
||||
import "@testing-library/jest-dom";
|
||||
import axios from "axios";
|
||||
import MockAdapter from "axios-mock-adapter";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import gist from "../api-renamed/gist.js";
|
||||
import { renderGistCard } from "../src/cards/gist.js";
|
||||
@@ -12,6 +11,8 @@ import { renderError } from "../src/common/render.js";
|
||||
|
||||
import { gist_data } from "./test-data/gist-data.js";
|
||||
|
||||
import "@testing-library/jest-dom/vitest";
|
||||
|
||||
const gist_not_found_data = {
|
||||
data: {
|
||||
viewer: {
|
||||
@@ -34,8 +35,8 @@ describe("Test /api/gist", () => {
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
setHeader: vi.fn(),
|
||||
send: vi.fn(),
|
||||
};
|
||||
mock.onPost("https://api.github.com/graphql").reply(200, gist_data);
|
||||
|
||||
@@ -66,8 +67,8 @@ describe("Test /api/gist", () => {
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
setHeader: vi.fn(),
|
||||
send: vi.fn(),
|
||||
};
|
||||
mock.onPost("https://api.github.com/graphql").reply(200, gist_data);
|
||||
|
||||
@@ -96,8 +97,8 @@ describe("Test /api/gist", () => {
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
setHeader: vi.fn(),
|
||||
send: vi.fn(),
|
||||
};
|
||||
mock
|
||||
.onPost("https://api.github.com/graphql")
|
||||
@@ -119,8 +120,8 @@ describe("Test /api/gist", () => {
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
setHeader: vi.fn(),
|
||||
send: vi.fn(),
|
||||
};
|
||||
mock.onPost("https://api.github.com/graphql").reply(200, gist_data);
|
||||
|
||||
@@ -142,8 +143,8 @@ describe("Test /api/gist", () => {
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
setHeader: vi.fn(),
|
||||
send: vi.fn(),
|
||||
};
|
||||
mock.onPost("https://api.github.com/graphql").reply(200, gist_data);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { describe, expect, it } from "@jest/globals";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { encodeHTML } from "../src/common/html.js";
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { describe, expect, it } from "@jest/globals";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { I18n } from "../src/common/I18n.js";
|
||||
import { statCardLocales } from "../src/translations.js";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { describe, expect, it } from "@jest/globals";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import {
|
||||
chunkArray,
|
||||
|
||||
@@ -2,16 +2,9 @@
|
||||
* @file Tests for the status/pat-info cloud function.
|
||||
*/
|
||||
|
||||
import {
|
||||
afterEach,
|
||||
beforeAll,
|
||||
describe,
|
||||
expect,
|
||||
it,
|
||||
jest,
|
||||
} from "@jest/globals";
|
||||
import axios from "axios";
|
||||
import MockAdapter from "axios-mock-adapter";
|
||||
import { afterEach, beforeAll, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import patInfo, { RATE_LIMIT_SECONDS } from "../api-renamed/status/pat-info.js";
|
||||
|
||||
@@ -30,8 +23,8 @@ const faker = (query) => {
|
||||
query: { ...query },
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
setHeader: vi.fn(),
|
||||
send: vi.fn(),
|
||||
};
|
||||
|
||||
return { req, res };
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
// @ts-check
|
||||
|
||||
import { afterEach, describe, expect, it, jest } from "@jest/globals";
|
||||
import "@testing-library/jest-dom";
|
||||
import axios from "axios";
|
||||
import MockAdapter from "axios-mock-adapter";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import pin from "../api-renamed/pin.js";
|
||||
import { renderRepoCard } from "../src/cards/repo.js";
|
||||
@@ -12,6 +11,8 @@ import { renderError } from "../src/common/render.js";
|
||||
|
||||
import { data_repo, data_user } from "./test-data/pin-data.js";
|
||||
|
||||
import "@testing-library/jest-dom/vitest";
|
||||
|
||||
const mock = new MockAdapter(axios);
|
||||
|
||||
afterEach(() => {
|
||||
@@ -27,8 +28,8 @@ describe("Test /api/pin", () => {
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
setHeader: vi.fn(),
|
||||
send: vi.fn(),
|
||||
};
|
||||
mock.onPost("https://api.github.com/graphql").reply(200, data_user);
|
||||
|
||||
@@ -57,8 +58,8 @@ describe("Test /api/pin", () => {
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
setHeader: vi.fn(),
|
||||
send: vi.fn(),
|
||||
};
|
||||
mock.onPost("https://api.github.com/graphql").reply(200, data_user);
|
||||
|
||||
@@ -85,8 +86,8 @@ describe("Test /api/pin", () => {
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
setHeader: vi.fn(),
|
||||
send: vi.fn(),
|
||||
};
|
||||
mock
|
||||
.onPost("https://api.github.com/graphql")
|
||||
@@ -108,8 +109,8 @@ describe("Test /api/pin", () => {
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
setHeader: vi.fn(),
|
||||
send: vi.fn(),
|
||||
};
|
||||
mock
|
||||
.onPost("https://api.github.com/graphql")
|
||||
@@ -132,8 +133,8 @@ describe("Test /api/pin", () => {
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
setHeader: vi.fn(),
|
||||
send: vi.fn(),
|
||||
};
|
||||
mock.onPost("https://api.github.com/graphql").reply(200, data_user);
|
||||
|
||||
@@ -156,8 +157,8 @@ describe("Test /api/pin", () => {
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
setHeader: vi.fn(),
|
||||
send: vi.fn(),
|
||||
};
|
||||
mock.onPost("https://api.github.com/graphql").reply(200, data_user);
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// @ts-check
|
||||
|
||||
import { afterEach, describe, expect, it, jest } from "@jest/globals";
|
||||
import axios from "axios";
|
||||
import MockAdapter from "axios-mock-adapter";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import api from "../../api-renamed/index.js";
|
||||
import { renderError } from "../../src/common/render.js";
|
||||
@@ -22,8 +22,8 @@ describe("Test /api/", () => {
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
setHeader: vi.fn(),
|
||||
send: vi.fn(),
|
||||
};
|
||||
mock.onPost("https://api.github.com/graphql").replyOnce(200, data_stats);
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// @ts-check
|
||||
|
||||
import { afterEach, describe, expect, it, jest } from "@jest/globals";
|
||||
import axios from "axios";
|
||||
import MockAdapter from "axios-mock-adapter";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import gist from "../../api-renamed/gist.js";
|
||||
import { renderError } from "../../src/common/render.js";
|
||||
@@ -22,8 +22,8 @@ describe("Test /api/gist with gist whitelist", () => {
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
setHeader: vi.fn(),
|
||||
send: vi.fn(),
|
||||
};
|
||||
mock.onPost("https://api.github.com/graphql").reply(200, gist_data);
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// @ts-check
|
||||
|
||||
import { afterEach, describe, expect, it, jest } from "@jest/globals";
|
||||
import axios from "axios";
|
||||
import MockAdapter from "axios-mock-adapter";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import pin from "../../api-renamed/pin.js";
|
||||
import { renderError } from "../../src/common/render.js";
|
||||
@@ -23,8 +23,8 @@ describe("Test /api/pin", () => {
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
setHeader: vi.fn(),
|
||||
send: vi.fn(),
|
||||
};
|
||||
mock.onPost("https://api.github.com/graphql").reply(200, data_user);
|
||||
|
||||
@@ -45,8 +45,8 @@ describe("Test /api/pin", () => {
|
||||
query: {},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
setHeader: vi.fn(),
|
||||
send: vi.fn(),
|
||||
};
|
||||
mock.onPost("https://api.github.com/graphql").reply(200, data_user);
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// @ts-check
|
||||
|
||||
import { afterEach, describe, expect, it, jest } from "@jest/globals";
|
||||
import axios from "axios";
|
||||
import MockAdapter from "axios-mock-adapter";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import topLangs from "../../api-renamed/top-langs.js";
|
||||
import { renderError } from "../../src/common/render.js";
|
||||
@@ -22,8 +22,8 @@ describe("Test /api/top-langs", () => {
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
setHeader: vi.fn(),
|
||||
send: vi.fn(),
|
||||
};
|
||||
mock.onPost("https://api.github.com/graphql").reply(200, data_langs);
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// @ts-check
|
||||
|
||||
import { afterEach, describe, expect, it, jest } from "@jest/globals";
|
||||
import axios from "axios";
|
||||
import MockAdapter from "axios-mock-adapter";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import api from "../../api-renamed/index.js";
|
||||
import { renderError } from "../../src/common/render.js";
|
||||
@@ -22,8 +22,8 @@ describe("Test /api/", () => {
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
setHeader: vi.fn(),
|
||||
send: vi.fn(),
|
||||
};
|
||||
mock.onPost("https://api.github.com/graphql").replyOnce(200, data_stats);
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// @ts-check
|
||||
|
||||
import { afterEach, describe, expect, it, jest } from "@jest/globals";
|
||||
import axios from "axios";
|
||||
import MockAdapter from "axios-mock-adapter";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import gist from "../../api-renamed/gist.js";
|
||||
import { renderError } from "../../src/common/render.js";
|
||||
@@ -20,8 +20,8 @@ describe("Test /api/gist", () => {
|
||||
query: {},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
setHeader: vi.fn(),
|
||||
send: vi.fn(),
|
||||
};
|
||||
mock.onPost("https://api.github.com/graphql").reply(200, gist_data);
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// @ts-check
|
||||
|
||||
import { afterEach, describe, expect, it, jest } from "@jest/globals";
|
||||
import axios from "axios";
|
||||
import MockAdapter from "axios-mock-adapter";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import pin from "../../api-renamed/pin.js";
|
||||
import { renderError } from "../../src/common/render.js";
|
||||
@@ -23,8 +23,8 @@ describe("Test /api/pin", () => {
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
setHeader: vi.fn(),
|
||||
send: vi.fn(),
|
||||
};
|
||||
mock.onPost("https://api.github.com/graphql").reply(200, data_user);
|
||||
|
||||
@@ -45,8 +45,8 @@ describe("Test /api/pin", () => {
|
||||
query: {},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
setHeader: vi.fn(),
|
||||
send: vi.fn(),
|
||||
};
|
||||
mock.onPost("https://api.github.com/graphql").reply(200, data_user);
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// @ts-check
|
||||
|
||||
import { afterEach, describe, expect, it, jest } from "@jest/globals";
|
||||
import axios from "axios";
|
||||
import MockAdapter from "axios-mock-adapter";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import topLangs from "../../api-renamed/top-langs.js";
|
||||
import { renderError } from "../../src/common/render.js";
|
||||
@@ -22,8 +22,8 @@ describe("Test /api/top-langs", () => {
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
setHeader: vi.fn(),
|
||||
send: vi.fn(),
|
||||
};
|
||||
mock.onPost("https://api.github.com/graphql").reply(200, data_langs);
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
// @ts-check
|
||||
|
||||
import { describe, expect, it } from "@jest/globals";
|
||||
import { queryByTestId } from "@testing-library/dom";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import "@testing-library/jest-dom/jest-globals";
|
||||
import { renderError } from "../src/common/render.js";
|
||||
|
||||
import "@testing-library/jest-dom/vitest";
|
||||
|
||||
describe("Test render.js", () => {
|
||||
it("should test renderError", () => {
|
||||
document.body.innerHTML = renderError({ message: "Something went wrong" });
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { describe, expect, it } from "@jest/globals";
|
||||
import { queryByTestId } from "@testing-library/dom";
|
||||
import "@testing-library/jest-dom";
|
||||
import { cssToObject } from "@uppercod/css-to-object";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { renderGistCard } from "../src/cards/gist.js";
|
||||
import { themes } from "../themes/index.js";
|
||||
|
||||
import "@testing-library/jest-dom/vitest";
|
||||
|
||||
/**
|
||||
* @type {import("../src/fetchers/gist").GistData}
|
||||
*/
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { describe, expect, it } from "@jest/globals";
|
||||
import { queryByTestId } from "@testing-library/dom";
|
||||
import "@testing-library/jest-dom";
|
||||
import { cssToObject } from "@uppercod/css-to-object";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { renderRepoCard } from "../src/cards/repo.js";
|
||||
import { themes } from "../themes/index.js";
|
||||
|
||||
import "@testing-library/jest-dom/vitest";
|
||||
|
||||
const data_repo = {
|
||||
repository: {
|
||||
nameWithOwner: "anuraghazra/convoychat",
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
import { describe, expect, it } from "@jest/globals";
|
||||
import {
|
||||
getByTestId,
|
||||
queryAllByTestId,
|
||||
queryByTestId,
|
||||
} from "@testing-library/dom";
|
||||
import "@testing-library/jest-dom";
|
||||
import { cssToObject } from "@uppercod/css-to-object";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { renderStatsCard } from "../src/cards/stats.js";
|
||||
import { CustomError } from "../src/common/error.js";
|
||||
import { themes } from "../themes/index.js";
|
||||
|
||||
import "@testing-library/jest-dom/vitest";
|
||||
|
||||
const stats = {
|
||||
name: "Anurag Hazra",
|
||||
totalStars: 100,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { describe, expect, it } from "@jest/globals";
|
||||
import { queryAllByTestId, queryByTestId } from "@testing-library/dom";
|
||||
import "@testing-library/jest-dom";
|
||||
import { cssToObject } from "@uppercod/css-to-object";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import {
|
||||
MIN_CARD_WIDTH,
|
||||
@@ -23,7 +22,9 @@ import {
|
||||
} from "../src/cards/top-languages.js";
|
||||
import { themes } from "../themes/index.js";
|
||||
|
||||
import { approxNumber } from "./bench/utils.js";
|
||||
import { approxNumber } from "./utils.js";
|
||||
|
||||
import "@testing-library/jest-dom/vitest";
|
||||
|
||||
const langs = {
|
||||
HTML: {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { describe, expect, it } from "@jest/globals";
|
||||
import { queryByTestId } from "@testing-library/dom";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { renderWakatimeCard } from "../src/cards/wakatime.js";
|
||||
|
||||
import { wakaTimeData } from "./fetchWakatime.test.js";
|
||||
|
||||
import "@testing-library/jest-dom";
|
||||
import "@testing-library/jest-dom/vitest";
|
||||
|
||||
describe("Test Render WakaTime Card", () => {
|
||||
it("should render correctly", () => {
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
// @ts-check
|
||||
|
||||
import { describe, expect, it, jest } from "@jest/globals";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
import "@testing-library/jest-dom/vitest";
|
||||
|
||||
import "@testing-library/jest-dom";
|
||||
import { logger } from "../src/common/log.js";
|
||||
import { retryer } from "../src/common/retryer.js";
|
||||
|
||||
const fetcher = jest.fn((variables, token) => {
|
||||
const fetcher = vi.fn((variables, token) => {
|
||||
logger.log(variables, token);
|
||||
return new Promise((res) => res({ data: "ok" }));
|
||||
});
|
||||
|
||||
const fetcherFail = jest.fn(() => {
|
||||
const fetcherFail = vi.fn(() => {
|
||||
return new Promise((res) =>
|
||||
res({ data: { errors: [{ type: "RATE_LIMITED" }] } }),
|
||||
);
|
||||
});
|
||||
|
||||
const fetcherFailOnSecondTry = jest.fn((_vars, _token, retries) => {
|
||||
const fetcherFailOnSecondTry = vi.fn((_vars, _token, retries) => {
|
||||
return new Promise((res) => {
|
||||
// faking rate limit
|
||||
// @ts-ignore
|
||||
@@ -28,7 +29,7 @@ const fetcherFailOnSecondTry = jest.fn((_vars, _token, retries) => {
|
||||
});
|
||||
});
|
||||
|
||||
const fetcherFailWithMessageBasedRateLimitErr = jest.fn(
|
||||
const fetcherFailWithMessageBasedRateLimitErr = vi.fn(
|
||||
(_vars, _token, retries) => {
|
||||
return new Promise((res) => {
|
||||
// faking rate limit
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
* @file Tests for the status/up cloud function.
|
||||
*/
|
||||
|
||||
import { afterEach, describe, expect, it, jest } from "@jest/globals";
|
||||
import axios from "axios";
|
||||
import MockAdapter from "axios-mock-adapter";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import up, { RATE_LIMIT_SECONDS } from "../api-renamed/status/up.js";
|
||||
|
||||
@@ -21,8 +21,8 @@ const faker = (query) => {
|
||||
query: { ...query },
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
setHeader: vi.fn(),
|
||||
send: vi.fn(),
|
||||
};
|
||||
|
||||
return { req, res };
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
// @ts-check
|
||||
|
||||
import { afterEach, describe, expect, it, jest } from "@jest/globals";
|
||||
import "@testing-library/jest-dom";
|
||||
import axios from "axios";
|
||||
import MockAdapter from "axios-mock-adapter";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import topLangs from "../api-renamed/top-langs.js";
|
||||
import { renderTopLanguages } from "../src/cards/top-languages.js";
|
||||
@@ -12,6 +11,8 @@ import { renderError } from "../src/common/render.js";
|
||||
|
||||
import { data_langs } from "./test-data/langs-data.js";
|
||||
|
||||
import "@testing-library/jest-dom/vitest";
|
||||
|
||||
const error = {
|
||||
errors: [
|
||||
{
|
||||
@@ -50,8 +51,8 @@ describe("Test /api/top-langs", () => {
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
setHeader: vi.fn(),
|
||||
send: vi.fn(),
|
||||
};
|
||||
mock.onPost("https://api.github.com/graphql").reply(200, data_langs);
|
||||
|
||||
@@ -74,8 +75,8 @@ describe("Test /api/top-langs", () => {
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
setHeader: vi.fn(),
|
||||
send: vi.fn(),
|
||||
};
|
||||
mock.onPost("https://api.github.com/graphql").reply(200, data_langs);
|
||||
|
||||
@@ -101,8 +102,8 @@ describe("Test /api/top-langs", () => {
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
setHeader: vi.fn(),
|
||||
send: vi.fn(),
|
||||
};
|
||||
mock.onPost("https://api.github.com/graphql").reply(200, error);
|
||||
|
||||
@@ -126,8 +127,8 @@ describe("Test /api/top-langs", () => {
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
setHeader: vi.fn(),
|
||||
send: vi.fn(),
|
||||
};
|
||||
mock.onPost("https://api.github.com/graphql").reply(200, data_langs);
|
||||
|
||||
@@ -150,8 +151,8 @@ describe("Test /api/top-langs", () => {
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
setHeader: vi.fn(),
|
||||
send: vi.fn(),
|
||||
};
|
||||
mock.onPost("https://api.github.com/graphql").reply(200, data_langs);
|
||||
|
||||
@@ -173,8 +174,8 @@ describe("Test /api/top-langs", () => {
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
setHeader: vi.fn(),
|
||||
send: vi.fn(),
|
||||
};
|
||||
mock.onPost("https://api.github.com/graphql").reply(200, data_langs);
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
// @ts-check
|
||||
|
||||
/**
|
||||
* Creates an asymmetric matcher for approximate numeric equality.
|
||||
*
|
||||
* This helper is intended for use in test frameworks (e.g., Jest) where
|
||||
* values need to be compared within a configurable decimal precision
|
||||
* instead of strict equality.
|
||||
*
|
||||
* The comparison succeeds when:
|
||||
*
|
||||
* |actual - expected| < 10^(-precision)
|
||||
*
|
||||
* For example, with `precision = 3`, values must be within `0.001`.
|
||||
*
|
||||
* @param {number} expected The expected numeric value to compare against.
|
||||
*
|
||||
* @param {number} [precision=10]
|
||||
* The number of decimal places of tolerance. Higher values mean stricter
|
||||
* comparison. Internally converted to epsilon = 10^-precision.
|
||||
*
|
||||
* @returns {{
|
||||
* asymmetricMatch(actual: unknown): boolean,
|
||||
* toAsymmetricMatcher(): string
|
||||
* }} An object implementing Jest-style asymmetric matcher methods.
|
||||
*
|
||||
*/
|
||||
export function approxNumber(expected, precision = 10) {
|
||||
return {
|
||||
asymmetricMatch(actual) {
|
||||
if (typeof actual !== "number" || typeof expected !== "number") {
|
||||
return false;
|
||||
}
|
||||
const epsilon = Math.pow(10, -precision);
|
||||
return Math.abs(actual - expected) < epsilon;
|
||||
},
|
||||
toAsymmetricMatcher() {
|
||||
return `≈ ${expected} (precision ${precision})`;
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,13 +1,14 @@
|
||||
import { afterEach, describe, expect, it, jest } from "@jest/globals";
|
||||
import "@testing-library/jest-dom";
|
||||
import axios from "axios";
|
||||
import MockAdapter from "axios-mock-adapter";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import wakatime from "../api-renamed/wakatime.js";
|
||||
import { renderWakatimeCard } from "../src/cards/wakatime.js";
|
||||
import { CACHE_TTL, DURATIONS } from "../src/common/cache.js";
|
||||
import { renderError } from "../src/index.js";
|
||||
|
||||
import "@testing-library/jest-dom/vitest";
|
||||
|
||||
const wakaTimeData = {
|
||||
data: {
|
||||
categories: [
|
||||
@@ -118,7 +119,7 @@ describe("Test /api/wakatime", () => {
|
||||
it("should test the request", async () => {
|
||||
const username = "anuraghazra";
|
||||
const req = { query: { username } };
|
||||
const res = { setHeader: jest.fn(), send: jest.fn() };
|
||||
const res = { setHeader: vi.fn(), send: vi.fn() };
|
||||
mock
|
||||
.onGet(
|
||||
`https://wakatime.com/api/v1/users/${username}/stats?is_including_today=true`,
|
||||
@@ -136,7 +137,7 @@ describe("Test /api/wakatime", () => {
|
||||
it("should render error if wrong locale is provided", async () => {
|
||||
const username = "anuraghazra";
|
||||
const req = { query: { username, locale: "asdf" } };
|
||||
const res = { setHeader: jest.fn(), send: jest.fn() };
|
||||
const res = { setHeader: vi.fn(), send: vi.fn() };
|
||||
mock
|
||||
.onGet(
|
||||
`https://wakatime.com/api/v1/users/${username}/stats?is_including_today=true`,
|
||||
@@ -157,7 +158,7 @@ describe("Test /api/wakatime", () => {
|
||||
it("should render error if user data is not accessible", async () => {
|
||||
const username = "anuraghazra";
|
||||
const req = { query: { username } };
|
||||
const res = { setHeader: jest.fn(), send: jest.fn() };
|
||||
const res = { setHeader: vi.fn(), send: vi.fn() };
|
||||
mock
|
||||
.onGet(
|
||||
`https://wakatime.com/api/v1/users/${username}/stats?is_including_today=true`,
|
||||
@@ -174,7 +175,7 @@ describe("Test /api/wakatime", () => {
|
||||
it("should have proper cache", async () => {
|
||||
const username = "anuraghazra";
|
||||
const req = { query: { username } };
|
||||
const res = { setHeader: jest.fn(), send: jest.fn() };
|
||||
const res = { setHeader: vi.fn(), send: vi.fn() };
|
||||
mock
|
||||
.onGet(
|
||||
`https://wakatime.com/api/v1/users/${username}/stats?is_including_today=true`,
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"extends": ["../../tsconfig.base.json"],
|
||||
"include": [
|
||||
"src",
|
||||
"vitest.config.ts",
|
||||
"vitest.config.bench.ts",
|
||||
"vitest.config.e2e.ts"
|
||||
],
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"module": "nodenext",
|
||||
"moduleResolution": "nodenext"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { defineConfig } from "vitest/config";
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
dir: "./tests/bench",
|
||||
environment: "jsdom",
|
||||
setupFiles: ["./tests/_setup.js"],
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,8 @@
|
||||
import { defineConfig } from "vitest/config";
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
environment: "node",
|
||||
dir: "tests/e2e",
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,32 @@
|
||||
import { defineConfig } from "vitest/config";
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
coverage: {
|
||||
enabled: true,
|
||||
},
|
||||
projects: [
|
||||
{
|
||||
test: {
|
||||
name: "backend/public-instance",
|
||||
environment: "jsdom",
|
||||
dir: "tests",
|
||||
include: ["./*.test.{ts,js}", "./public-instance/*.test.{ts,js}"],
|
||||
setupFiles: ["./tests/_setup.js"],
|
||||
},
|
||||
},
|
||||
{
|
||||
test: {
|
||||
name: "backend/private-instance",
|
||||
environment: "jsdom",
|
||||
dir: "tests",
|
||||
include: ["./*.test.{ts,js}", "./private-instance/*.test.{ts,js}"],
|
||||
setupFiles: [
|
||||
"./tests/_setup.js",
|
||||
"./tests/_setup.private-instance.js",
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
+1
-18
@@ -2,26 +2,9 @@
|
||||
"$schema": "./node_modules/knip/schema.json",
|
||||
"workspaces": {
|
||||
"apps/backend": {
|
||||
"jest": {
|
||||
"config": [
|
||||
"jest.config.js",
|
||||
"jest.*.config.js",
|
||||
"package.json" // included by default, see https://knip.dev/reference/plugins/jest
|
||||
]
|
||||
},
|
||||
|
||||
"entry": [
|
||||
"api-renamed/*.js",
|
||||
"express.js",
|
||||
|
||||
"jest.*.js",
|
||||
"tests/bench/*.bench.js"
|
||||
],
|
||||
"entry": ["api-renamed/*.js", "express.js", "tests/bench/*.bench.js"],
|
||||
"ignoreFiles": [
|
||||
"_dot_vercel_copy/**/*" // Hopefully by using a npm package this file will be removed
|
||||
],
|
||||
"ignoreDependencies": [
|
||||
"jest" // used by test scripts referencing binary due to lack of ESM support
|
||||
]
|
||||
},
|
||||
"apps/frontend": {
|
||||
|
||||
Generated
+312
-2235
File diff suppressed because it is too large
Load Diff
@@ -2,6 +2,7 @@ packages:
|
||||
- apps/*
|
||||
|
||||
catalog:
|
||||
"@vitest/coverage-v8": 4.0.18
|
||||
vite: 7.3.1
|
||||
vitest: 4.0.18
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
{
|
||||
"files": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./apps/backend"
|
||||
},
|
||||
{
|
||||
"path": "./apps/frontend"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user