Add test support

This commit is contained in:
2026-03-02 14:29:52 +08:00
parent 6cf7e3aa19
commit 08c0fa0c3f
7 changed files with 524 additions and 6 deletions

3
.gitignore vendored
View File

@@ -3,3 +3,6 @@ dist/
*.crx
*.pem
*.zip
test.cjs
test.cjs.map
src/test.ts

75
build_test.js Normal file
View File

@@ -0,0 +1,75 @@
import esbuild from 'esbuild';
import colors from 'colors';
import fs from 'fs';
function displaySize(bytes) {
const units = ['B', 'KiB', 'MiB', 'GiB', 'TiB'];
let i = 0;
while (bytes >= 1024 && i < units.length - 1) {
bytes /= 1024;
i++;
}
return `${bytes.toFixed(2)} ${units[i]}`;
}
/**@param {esbuild.BuildResult} result */
function displayResult(result) {
for (const outfile in result.metafile.outputs) {
const output = result.metafile.outputs[outfile];
let totalInBytes = 0;
for (const input in output.inputs) {
const inp = result.metafile.inputs[input];
totalInBytes += inp.bytes;
}
let inInfo = '';
if (totalInBytes > 0) {
const ratio = (output.bytes / totalInBytes * 100).toFixed(2);
inInfo = ` - Input size: ${colors.green(displaySize(totalInBytes))} (${totalInBytes} B), Ratio: ${colors.yellow(ratio + '%')}`;
}
console.log(`${colors.cyan(outfile)}: ${colors.yellow(displaySize(output.bytes))} (${output.bytes} B)${inInfo}`);
}
}
async function build(name) {
const result = await esbuild.build({
entryPoints: [`src/${name}.ts`],
bundle: true,
minify: true,
outfile: `${name}.cjs`,
platform: 'node',
target: ['node18'],
sourcemap: true,
sourcesContent: false,
metafile: true,
format: 'cjs',
})
displayResult(result);
return result;
}
async function generateTestFile() {
let content = `import { runTests, waitTestsRegistered } from "./test_base";\n`;
content += 'import process from "node:process";\n';
const files = await fs.promises.readdir('src', {recursive: true});
const testLists = [];
for (const file of files) {
if (file.endsWith('.test.ts')) {
const name = file.slice(0, -8).replaceAll(/[./\\]/g, '_');
content += `import ${name} from "./${file.replaceAll(/[\\]/g, '/')}";\n`;
testLists.push(` ${name},`);
}
}
content += `const tests = [\n${testLists.join('\n')}\n];\n`;
content += `async function run() {
await waitTestsRegistered(tests);
const re = await runTests();
if (re.failure > 0) {
process.exit(1);
}
}
run();\n`;
await fs.promises.writeFile('src/test.ts', content);
}
await generateTestFile();
await build('test');

View File

@@ -29,8 +29,12 @@
"build": "node build.js --dev",
"builddbg": "node build.js --dev --debug",
"buildrel": "node build.js",
"lint": "eslint src"
"lint": "eslint src",
"test": "node build_test.js && node --enable-source-maps test.cjs"
},
"type": "module",
"types": "./data.d.ts"
"types": "./data.d.ts",
"devDependencies": {
"expect": "^30.2.0"
}
}

58
src/test_base.ts Normal file
View File

@@ -0,0 +1,58 @@
export type TestFunction = () => Promise<void> | void;
type TestCase = {
filename: string;
name: string;
fn: TestFunction;
};
export type TestResult = {
success: number;
failure: number;
}
const testCases: TestCase[] = [];
/**
* Register a new test case.
* @param filename The name of the file containing the test.
* @param name The name of the test case.
* @param fn The test function to execute.
*/
export function test(filename: string, name: string, fn: TestFunction) {
testCases.push({ filename, name, fn });
}
/**
* Run all registered test cases and log the results to the console.
*/
export async function runTests() {
const results: TestResult = { success: 0, failure: 0 };
const runTestCase = async (testCase: TestCase) => {
try {
const re = testCase.fn();
if (re instanceof Promise) {
await re;
}
console.log(`${testCase.filename} - ${testCase.name}`);
results.success++;
} catch (error) {
console.error(`${testCase.filename} - ${testCase.name}:`, error);
results.failure++;
}
};
for (const testCase of testCases) {
await runTestCase(testCase);
}
console.log(`\nTest Results: ${results.success} passed, ${results.failure} failed`);
return results;
}
export async function waitTestsRegistered(list: TestFunction[]) {
for (const fn of list) {
const re = fn();
if (re instanceof Promise) {
await re;
}
}
}

86
src/utils/qd.test.ts Normal file
View File

@@ -0,0 +1,86 @@
import { test } from "../test_base";
import expect from "expect";
import { get_new_volumes, ChapterShowMode } from "./qd";
import type { Volume } from "../qdtypes";
import type { QdChapterSimpleInfo } from "../types";
const filename = 'utils/qd.test.ts';
export default function t() {
test(filename, 'merge_volumes_1', () => {
const sourceList: Volume[] = [
{
id: 'test',
name: 'Test Volume',
isVip: false,
chapters: [
{ id: 1, name: 'Chapter 1' },
{ id: 2, name: 'Chapter 2' },
],
},
];
const targetList: QdChapterSimpleInfo[] = [
{
primaryKey: 0,
id: 2,
name: 'Chapter 2',
bookId: 0,
time: 10,
},
{
primaryKey: 0,
id: 3,
name: 'Chapter 3',
bookId: 0,
time: 11,
},
];
expect(get_new_volumes(targetList, sourceList, ChapterShowMode.All)).toEqual([
{
id: 'vol_new',
name: '其他已保存章节',
isVip: false,
chapters: [
{ id: 3, name: 'Chapter 3', isSaved: true },
],
},
{
id: 'test',
name: 'Test Volume',
isVip: false,
chapters: [
{ id: 1, name: 'Chapter 1' },
{ id: 2, name: 'Chapter 2', isSaved: true },
],
},
]);
expect(get_new_volumes(targetList, sourceList, ChapterShowMode.SavedOnly)).toEqual([
{
id: 'vol_new',
name: '其他已保存章节',
isVip: false,
chapters: [
{ id: 3, name: 'Chapter 3' },
],
},
{
id: 'test',
name: 'Test Volume',
isVip: false,
chapters: [
{ id: 2, name: 'Chapter 2' },
],
},
]);
expect(get_new_volumes(targetList, sourceList, ChapterShowMode.UnsavedOnly)).toEqual([
{
id: 'test',
name: 'Test Volume',
isVip: false,
chapters: [
{ id: 1, name: 'Chapter 1' },
],
},
]);
});
}

View File

@@ -79,6 +79,28 @@ export function get_new_volumes(chapterLists: QdChapterSimpleInfo[], volumes: Vo
});
}
}
for (const vol of vols) {
for (const ch of vol.chapters) {
chIds.delete(ch.id);
}
}
if (chIds.size > 0) {
const volCh: Chapter[] = [];
for (const ch of chapterLists) {
if (chIds.has(ch.id)) {
volCh.push({
id: ch.id,
name: ch.name,
});
}
}
vols.unshift({
id: 'vol_new',
name: '其他已保存章节',
chapters: volCh,
isVip: false,
});
}
} else if (keepMode == ChapterShowMode.UnsavedOnly) {
const chIds = new Set(chapterLists.map(ch => ch.id));
for (const vol of volumes) {

278
yarn.lock
View File

@@ -61,6 +61,20 @@
json2mq "^0.2.0"
throttle-debounce "^5.0.0"
"@babel/code-frame@^7.27.1":
version "7.29.0"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.29.0.tgz#7cd7a59f15b3cc0dcd803038f7792712a7d0b15c"
integrity sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==
dependencies:
"@babel/helper-validator-identifier" "^7.28.5"
js-tokens "^4.0.0"
picocolors "^1.1.1"
"@babel/helper-validator-identifier@^7.28.5":
version "7.28.5"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz#010b6938fab7cb7df74aa2bbc06aa503b8fe5fb4"
integrity sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==
"@babel/runtime@^7.10.1", "@babel/runtime@^7.11.1", "@babel/runtime@^7.18.0", "@babel/runtime@^7.20.0", "@babel/runtime@^7.23.2", "@babel/runtime@^7.24.4", "@babel/runtime@^7.24.7", "@babel/runtime@^7.28.4":
version "7.28.6"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.28.6.tgz#d267a43cb1836dc4d182cce93ae75ba954ef6d2b"
@@ -297,6 +311,51 @@
resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.4.3.tgz#c2b9d2e374ee62c586d3adbea87199b1d7a7a6ba"
integrity sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==
"@jest/[email protected]":
version "30.0.1"
resolved "https://registry.yarnpkg.com/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz#0ededeae4d071f5c8ffe3678d15f3a1be09156be"
integrity sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==
"@jest/[email protected]":
version "30.2.0"
resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-30.2.0.tgz#4f95413d4748454fdb17404bf1141827d15e6011"
integrity sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA==
dependencies:
"@jest/get-type" "30.1.0"
"@jest/[email protected]":
version "30.1.0"
resolved "https://registry.yarnpkg.com/@jest/get-type/-/get-type-30.1.0.tgz#4fcb4dc2ebcf0811be1c04fd1cb79c2dba431cbc"
integrity sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==
"@jest/[email protected]":
version "30.0.1"
resolved "https://registry.yarnpkg.com/@jest/pattern/-/pattern-30.0.1.tgz#d5304147f49a052900b4b853dedb111d080e199f"
integrity sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==
dependencies:
"@types/node" "*"
jest-regex-util "30.0.1"
"@jest/[email protected]":
version "30.0.5"
resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-30.0.5.tgz#7bdf69fc5a368a5abdb49fd91036c55225846473"
integrity sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==
dependencies:
"@sinclair/typebox" "^0.34.0"
"@jest/[email protected]":
version "30.2.0"
resolved "https://registry.yarnpkg.com/@jest/types/-/types-30.2.0.tgz#1c678a7924b8f59eafd4c77d56b6d0ba976d62b8"
integrity sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==
dependencies:
"@jest/pattern" "30.0.1"
"@jest/schemas" "30.0.5"
"@types/istanbul-lib-coverage" "^2.0.6"
"@types/istanbul-reports" "^3.0.4"
"@types/node" "*"
"@types/yargs" "^17.0.33"
chalk "^4.1.2"
"@material-icons/svg@^1.0.33":
version "1.0.33"
resolved "https://registry.yarnpkg.com/@material-icons/svg/-/svg-1.0.33.tgz#c3f4a5395c3b2267ce032081e9fe426995442ced"
@@ -701,6 +760,11 @@
"@rc-component/util" "^1.4.0"
clsx "^2.1.1"
"@sinclair/typebox@^0.34.0":
version "0.34.48"
resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.34.48.tgz#75b0ead87e59e1adbd6dccdc42bad4fddee73b59"
integrity sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==
"@stablelib/binary@^2.0.1":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@stablelib/binary/-/binary-2.0.1.tgz#65c36a24e2c65f375e4c5c4cb340b9112d9badb6"
@@ -762,11 +826,37 @@
resolved "https://registry.yarnpkg.com/@types/har-format/-/har-format-1.2.16.tgz#b71ede8681400cc08b3685f061c31e416cf94944"
integrity sha512-fluxdy7ryD3MV6h8pTfTYpy/xQzCFC7m89nOH9y94cNqJ1mDIDPut7MnRHI3F6qRmh/cT2fUjG1MLdCNb4hE9A==
"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.6":
version "2.0.6"
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz#7739c232a1fee9b4d3ce8985f314c0c6d33549d7"
integrity sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==
"@types/istanbul-lib-report@*":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz#53047614ae72e19fc0401d872de3ae2b4ce350bf"
integrity sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==
dependencies:
"@types/istanbul-lib-coverage" "*"
"@types/istanbul-reports@^3.0.4":
version "3.0.4"
resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz#0f03e3d2f670fbdac586e34b433783070cc16f54"
integrity sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==
dependencies:
"@types/istanbul-lib-report" "*"
"@types/json-schema@^7.0.15":
version "7.0.15"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==
"@types/node@*":
version "25.3.3"
resolved "https://registry.yarnpkg.com/@types/node/-/node-25.3.3.tgz#605862544ee7ffd7a936bcbf0135a14012f1e549"
integrity sha512-DpzbrH7wIcBaJibpKo9nnSQL0MTRdnWttGyE5haGwK86xgMOkFLp7vEyfQPGLOJh5wNYiJ3V9PmUMDhV9u8kkQ==
dependencies:
undici-types "~7.18.0"
"@types/react-dom@^19.2.3":
version "19.2.3"
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-19.2.3.tgz#c1e305d15a52a3e508d54dca770d202cb63abf2c"
@@ -779,6 +869,23 @@
dependencies:
csstype "^3.2.2"
"@types/stack-utils@^2.0.3":
version "2.0.3"
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8"
integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==
"@types/yargs-parser@*":
version "21.0.3"
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15"
integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==
"@types/yargs@^17.0.33":
version "17.0.35"
resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.35.tgz#07013e46aa4d7d7d50a49e15604c1c5340d4eb24"
integrity sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==
dependencies:
"@types/yargs-parser" "*"
"@typescript-eslint/[email protected]":
version "8.56.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.56.0.tgz#5aec3db807a6b8437ea5d5ebf7bd16b4119aba8d"
@@ -902,6 +1009,11 @@ ansi-styles@^4.1.0:
dependencies:
color-convert "^2.0.1"
ansi-styles@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b"
integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==
antd@^6.3.0:
version "6.3.0"
resolved "https://registry.yarnpkg.com/antd/-/antd-6.3.0.tgz#0ea0596d2d8c19cb5860e3fa6ad20128f6c8ffda"
@@ -1071,6 +1183,13 @@ brace-expansion@^2.0.1:
dependencies:
balanced-match "^1.0.0"
braces@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789"
integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==
dependencies:
fill-range "^7.1.1"
call-bind-apply-helpers@^1.0.0, call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6"
@@ -1102,7 +1221,7 @@ callsites@^3.0.0:
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
chalk@^4.0.0:
chalk@^4.0.0, chalk@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
@@ -1110,6 +1229,11 @@ chalk@^4.0.0:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
ci-info@^4.2.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-4.4.0.tgz#7d54eff9f54b45b62401c26032696eb59c8bd18c"
integrity sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==
clsx@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999"
@@ -1406,6 +1530,11 @@ esbuild@^0.27.3:
"@esbuild/win32-ia32" "0.27.3"
"@esbuild/win32-x64" "0.27.3"
escape-string-regexp@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344"
integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==
escape-string-regexp@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
@@ -1531,6 +1660,18 @@ esutils@^2.0.2:
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
expect@^30.2.0:
version "30.2.0"
resolved "https://registry.yarnpkg.com/expect/-/expect-30.2.0.tgz#d4013bed267013c14bc1199cec8aa57cee9b5869"
integrity sha512-u/feCi0GPsI+988gU2FLcsHyAHTU0MX1Wg68NhAnN7z/+C5wqG+CY8J53N9ioe8RXgaoz0nBR/TYMf3AycUuPw==
dependencies:
"@jest/expect-utils" "30.2.0"
"@jest/get-type" "30.1.0"
jest-matcher-utils "30.2.0"
jest-message-util "30.2.0"
jest-mock "30.2.0"
jest-util "30.2.0"
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
@@ -1558,6 +1699,13 @@ file-entry-cache@^8.0.0:
dependencies:
flat-cache "^4.0.0"
fill-range@^7.1.1:
version "7.1.1"
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292"
integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==
dependencies:
to-regex-range "^5.0.1"
find-up@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc"
@@ -1671,6 +1819,11 @@ gopd@^1.0.1, gopd@^1.2.0:
resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1"
integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==
graceful-fs@^4.2.11:
version "4.2.11"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3"
integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==
has-bigints@^1.0.2:
version "1.1.0"
resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.1.0.tgz#28607e965ac967e03cd2a2c70a2636a1edad49fe"
@@ -1863,6 +2016,11 @@ is-number-object@^1.1.1:
call-bound "^1.0.3"
has-tostringtag "^1.0.2"
is-number@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
is-regex@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.2.1.tgz#76d70a3ed10ef9be48eb577887d74205bf0cad22"
@@ -1951,7 +2109,68 @@ iterator.prototype@^1.1.5:
has-symbols "^1.1.0"
set-function-name "^2.0.2"
"js-tokens@^3.0.0 || ^4.0.0":
[email protected]:
version "30.2.0"
resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-30.2.0.tgz#e3ec3a6ea5c5747f605c9e874f83d756cba36825"
integrity sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A==
dependencies:
"@jest/diff-sequences" "30.0.1"
"@jest/get-type" "30.1.0"
chalk "^4.1.2"
pretty-format "30.2.0"
[email protected]:
version "30.2.0"
resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-30.2.0.tgz#69a0d4c271066559ec8b0d8174829adc3f23a783"
integrity sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg==
dependencies:
"@jest/get-type" "30.1.0"
chalk "^4.1.2"
jest-diff "30.2.0"
pretty-format "30.2.0"
[email protected]:
version "30.2.0"
resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-30.2.0.tgz#fc97bf90d11f118b31e6131e2b67fc4f39f92152"
integrity sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw==
dependencies:
"@babel/code-frame" "^7.27.1"
"@jest/types" "30.2.0"
"@types/stack-utils" "^2.0.3"
chalk "^4.1.2"
graceful-fs "^4.2.11"
micromatch "^4.0.8"
pretty-format "30.2.0"
slash "^3.0.0"
stack-utils "^2.0.6"
[email protected]:
version "30.2.0"
resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-30.2.0.tgz#69f991614eeb4060189459d3584f710845bff45e"
integrity sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw==
dependencies:
"@jest/types" "30.2.0"
"@types/node" "*"
jest-util "30.2.0"
[email protected]:
version "30.0.1"
resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-30.0.1.tgz#f17c1de3958b67dfe485354f5a10093298f2a49b"
integrity sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==
[email protected]:
version "30.2.0"
resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-30.2.0.tgz#5142adbcad6f4e53c2776c067a4db3c14f913705"
integrity sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==
dependencies:
"@jest/types" "30.2.0"
"@types/node" "*"
chalk "^4.1.2"
ci-info "^4.2.0"
graceful-fs "^4.2.11"
picomatch "^4.0.2"
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
@@ -2039,6 +2258,14 @@ math-intrinsics@^1.1.0:
resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9"
integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==
micromatch@^4.0.8:
version "4.0.8"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202"
integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==
dependencies:
braces "^3.0.3"
picomatch "^2.3.1"
minimatch@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
@@ -2192,7 +2419,17 @@ path-parse@^1.0.7:
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
picomatch@^4.0.3:
picocolors@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b"
integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
picomatch@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
picomatch@^4.0.2, picomatch@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.3.tgz#796c76136d1eead715db1e7bad785dedd695a042"
integrity sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==
@@ -2212,6 +2449,15 @@ prelude-ls@^1.2.1:
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
[email protected]:
version "30.2.0"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-30.2.0.tgz#2d44fe6134529aed18506f6d11509d8a62775ebe"
integrity sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==
dependencies:
"@jest/schemas" "30.0.5"
ansi-styles "^5.2.0"
react-is "^18.3.1"
prop-types@^15.8.1:
version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
@@ -2238,7 +2484,7 @@ react-is@^16.13.1:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
react-is@^18.2.0:
react-is@^18.2.0, react-is@^18.3.1:
version "18.3.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e"
integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==
@@ -2442,6 +2688,18 @@ side-channel@^1.1.0:
side-channel-map "^1.0.1"
side-channel-weakmap "^1.0.2"
slash@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
stack-utils@^2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f"
integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==
dependencies:
escape-string-regexp "^2.0.0"
stop-iteration-iterator@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz#f481ff70a548f6124d0312c3aa14cbfa7aa542ad"
@@ -2549,6 +2807,13 @@ tinyglobby@^0.2.15:
fdir "^6.5.0"
picomatch "^4.0.3"
to-regex-range@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
dependencies:
is-number "^7.0.0"
ts-api-utils@^2.4.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-2.4.0.tgz#2690579f96d2790253bdcf1ca35d569ad78f9ad8"
@@ -2631,6 +2896,11 @@ unbox-primitive@^1.1.0:
has-symbols "^1.1.0"
which-boxed-primitive "^1.1.1"
undici-types@~7.18.0:
version "7.18.2"
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.18.2.tgz#29357a89e7b7ca4aef3bf0fd3fd0cd73884229e9"
integrity sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==
uri-js@^4.2.2:
version "4.4.1"
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"