diff --git a/.gitignore b/.gitignore index a905f345..90dd4ea0 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,5 @@ test-temp-* test-results/ fixtures-test/ .rslib/ + +!packages/core/src/coverage \ No newline at end of file diff --git a/examples/node/package.json b/examples/node/package.json index 4286643e..3e4254aa 100644 --- a/examples/node/package.json +++ b/examples/node/package.json @@ -9,6 +9,7 @@ }, "devDependencies": { "@rstest/core": "workspace:*", + "@rstest/coverage-istanbul": "workspace:*", "@types/node": "^22.13.8", "typescript": "^5.8.3" } diff --git a/examples/node/rstest.config.ts b/examples/node/rstest.config.ts index 9ee3cbab..12f2d5c9 100644 --- a/examples/node/rstest.config.ts +++ b/examples/node/rstest.config.ts @@ -1,3 +1,8 @@ import { defineConfig } from '@rstest/core'; -export default defineConfig({}); +export default defineConfig({ + coverage: { + enabled: true, + provider: 'istanbul', + }, +}); diff --git a/examples/node/src/array.ts b/examples/node/src/array.ts new file mode 100644 index 00000000..82e90bc6 --- /dev/null +++ b/examples/node/src/array.ts @@ -0,0 +1,36 @@ +export const removeDuplicates = (arr: T[]): T[] => { + return [...new Set(arr)]; +}; + +export const chunk = (arr: T[], size: number): T[][] => { + if (size <= 0) { + throw new Error('Chunk size must be greater than 0'); + } + const result: T[][] = []; + for (let i = 0; i < arr.length; i += size) { + result.push(arr.slice(i, i + size)); + } + return result; +}; + +export const flatten = (arr: (T | T[])[]): T[] => { + return arr.reduce((acc, val) => { + return acc.concat(Array.isArray(val) ? flatten(val) : val); + }, []); +}; + +export const findMax = (arr: number[]): number => { + if (arr.length === 0) { + throw new Error('Array cannot be empty'); + } + return Math.max(...arr); +}; + +export const shuffle = (arr: T[]): T[] => { + const shuffled = [...arr]; + for (let i = shuffled.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]]; + } + return shuffled; +}; diff --git a/examples/node/src/date.ts b/examples/node/src/date.ts new file mode 100644 index 00000000..5bd30616 --- /dev/null +++ b/examples/node/src/date.ts @@ -0,0 +1,30 @@ +export const formatDate = (date: Date, format = 'YYYY-MM-DD'): string => { + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + + return format + .replace('YYYY', year.toString()) + .replace('MM', month) + .replace('DD', day); +}; + +export const addDays = (date: Date, days: number): Date => { + const result = new Date(date); + result.setDate(result.getDate() + days); + return result; +}; + +export const getDaysBetween = (date1: Date, date2: Date): number => { + const timeDiff = Math.abs(date2.getTime() - date1.getTime()); + return Math.ceil(timeDiff / (1000 * 3600 * 24)); +}; + +export const isWeekend = (date: Date): boolean => { + const day = date.getDay(); + return day === 0 || day === 6; // Sunday = 0, Saturday = 6 +}; + +export const getQuarter = (date: Date): number => { + return Math.floor((date.getMonth() + 3) / 3); +}; diff --git a/examples/node/src/string.ts b/examples/node/src/string.ts new file mode 100644 index 00000000..0bdb8d0c --- /dev/null +++ b/examples/node/src/string.ts @@ -0,0 +1,25 @@ +export const capitalize = (str: string): string => { + if (!str) return str; + return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase(); +}; + +export const reverseString = (str: string): string => { + return str.split('').reverse().join(''); +}; + +export const isPalindrome = (str: string): boolean => { + const cleaned = str.toLowerCase().replace(/[^a-z0-9]/g, ''); + return cleaned === cleaned.split('').reverse().join(''); +}; + +export const countWords = (str: string): number => { + return str + .trim() + .split(/\s+/) + .filter((word) => word.length > 0).length; +}; + +export const truncate = (str: string, maxLength: number): string => { + if (str.length <= maxLength) return str; + return str.slice(0, maxLength - 3) + '...'; +}; diff --git a/examples/node/test/array.test.ts b/examples/node/test/array.test.ts new file mode 100644 index 00000000..f55c89a9 --- /dev/null +++ b/examples/node/test/array.test.ts @@ -0,0 +1,78 @@ +import { describe, expect, it } from '@rstest/core'; +import { + chunk, + findMax, + flatten, + removeDuplicates, + shuffle, +} from '../src/array'; + +describe('Array Utils', () => { + describe('removeDuplicates', () => { + it('should remove duplicate numbers', () => { + expect(removeDuplicates([1, 2, 2, 3, 3, 4])).toEqual([1, 2, 3, 4]); + }); + + it('should remove duplicate strings', () => { + expect(removeDuplicates(['a', 'b', 'b', 'c'])).toEqual(['a', 'b', 'c']); + }); + + it('should handle empty array', () => { + expect(removeDuplicates([])).toEqual([]); + }); + }); + + describe('chunk', () => { + it('should chunk array into specified size', () => { + expect(chunk([1, 2, 3, 4, 5, 6], 2)).toEqual([ + [1, 2], + [3, 4], + [5, 6], + ]); + }); + + it('should handle remainder elements', () => { + expect(chunk([1, 2, 3, 4, 5], 2)).toEqual([[1, 2], [3, 4], [5]]); + }); + + it('should throw error for invalid chunk size', () => { + expect(() => chunk([1, 2, 3], 0)).toThrow( + 'Chunk size must be greater than 0', + ); + }); + }); + + describe('flatten', () => { + it('should flatten nested arrays', () => { + expect(flatten([1, [2, 3], [4, [5, 6]]])).toEqual([1, 2, 3, 4, 5, 6]); + }); + + it('should handle empty arrays', () => { + expect(flatten([])).toEqual([]); + }); + }); + + describe('findMax', () => { + it('should find maximum number', () => { + expect(findMax([1, 5, 3, 9, 2])).toBe(9); + }); + + it('should throw error for empty array', () => { + expect(() => findMax([])).toThrow('Array cannot be empty'); + }); + }); + + describe('shuffle', () => { + it('should return array with same length', () => { + const original = [1, 2, 3, 4, 5]; + const shuffled = shuffle(original); + expect(shuffled).toHaveLength(original.length); + }); + + it('should contain all original elements', () => { + const original = [1, 2, 3, 4, 5]; + const shuffled = shuffle(original); + expect(shuffled.sort()).toEqual(original.sort()); + }); + }); +}); diff --git a/examples/node/test/date.test.ts b/examples/node/test/date.test.ts new file mode 100644 index 00000000..8b421176 --- /dev/null +++ b/examples/node/test/date.test.ts @@ -0,0 +1,76 @@ +import { describe, expect, it } from '@rstest/core'; +import { + addDays, + formatDate, + getDaysBetween, + getQuarter, + isWeekend, +} from '../src/date'; + +describe('Date Utils', () => { + describe('formatDate', () => { + it('should format date with default format', () => { + const date = new Date('2023-12-25'); + expect(formatDate(date)).toBe('2023-12-25'); + }); + + it('should format date with custom format', () => { + const date = new Date('2023-12-25'); + expect(formatDate(date, 'DD/MM/YYYY')).toBe('25/12/2023'); + }); + }); + + describe('addDays', () => { + it('should add days to date', () => { + const date = new Date('2023-12-25'); + const result = addDays(date, 5); + expect(result.getDate()).toBe(30); + }); + + it('should subtract days from date', () => { + const date = new Date('2023-12-25'); + const result = addDays(date, -5); + expect(result.getDate()).toBe(20); + }); + }); + + describe('getDaysBetween', () => { + it('should calculate days between two dates', () => { + const date1 = new Date('2023-12-25'); + const date2 = new Date('2023-12-30'); + expect(getDaysBetween(date1, date2)).toBe(5); + }); + + it('should handle reversed dates', () => { + const date1 = new Date('2023-12-30'); + const date2 = new Date('2023-12-25'); + expect(getDaysBetween(date1, date2)).toBe(5); + }); + }); + + describe('isWeekend', () => { + it('should return true for Saturday', () => { + const saturday = new Date('2023-12-23'); // Saturday + expect(isWeekend(saturday)).toBe(true); + }); + + it('should return true for Sunday', () => { + const sunday = new Date('2023-12-24'); // Sunday + expect(isWeekend(sunday)).toBe(true); + }); + + it('should return false for weekday', () => { + const monday = new Date('2023-12-25'); // Monday + expect(isWeekend(monday)).toBe(false); + }); + }); + + describe('getQuarter', () => { + it('should return correct quarter for different months', () => { + expect(getQuarter(new Date('2023-01-15'))).toBe(1); + expect(getQuarter(new Date('2023-04-15'))).toBe(2); + expect(getQuarter(new Date('2023-07-15'))).toBe(3); + expect(getQuarter(new Date('2023-10-15'))).toBe(4); + }); + }); +}); diff --git a/examples/node/test/string.test.ts b/examples/node/test/string.test.ts new file mode 100644 index 00000000..e7c2fdcf --- /dev/null +++ b/examples/node/test/string.test.ts @@ -0,0 +1,88 @@ +import { describe, expect, it } from '@rstest/core'; +import { + capitalize, + countWords, + isPalindrome, + reverseString, + truncate, +} from '../src/string'; + +describe('String Utils', () => { + describe('capitalize', () => { + it('should capitalize first letter', () => { + expect(capitalize('hello')).toBe('Hello'); + }); + + it('should handle empty string', () => { + expect(capitalize('')).toBe(''); + }); + + it('should handle single character', () => { + expect(capitalize('a')).toBe('A'); + }); + }); + + describe('reverseString', () => { + it('should reverse string', () => { + expect(reverseString('hello')).toBe('olleh'); + }); + + it('should handle empty string', () => { + expect(reverseString('')).toBe(''); + }); + + it('should handle palindrome', () => { + expect(reverseString('racecar')).toBe('racecar'); + }); + }); + + describe('isPalindrome', () => { + it('should return true for palindrome', () => { + expect(isPalindrome('racecar')).toBe(true); + }); + + it('should return true for palindrome with spaces', () => { + expect(isPalindrome('A man a plan a canal Panama')).toBe(true); + }); + + it('should return false for non-palindrome', () => { + expect(isPalindrome('hello')).toBe(false); + }); + + it('should handle empty string', () => { + expect(isPalindrome('')).toBe(true); + }); + }); + + describe('countWords', () => { + it('should count words correctly', () => { + expect(countWords('hello world')).toBe(2); + }); + + it('should handle multiple spaces', () => { + expect(countWords('hello world test')).toBe(3); + }); + + it('should handle empty string', () => { + expect(countWords('')).toBe(0); + }); + + it('should handle single word', () => { + expect(countWords('hello')).toBe(1); + }); + }); + + describe('truncate', () => { + it('should truncate long string', () => { + expect(truncate('This is a very long string', 10)).toBe('This is...'); + }); + + it('should not truncate short string', () => { + expect(truncate('Short', 10)).toBe('Short'); + }); + + it('should handle exact length', () => { + expect(truncate('Exactly10!', 10)).toBe('Exactly10!'); + }); + }); +}); diff --git a/packages/core/package.json b/packages/core/package.json index 7e3d3dea..e8dad0d5 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -60,8 +60,14 @@ "@vitest/snapshot": "^3.2.4", "birpc": "2.5.0", "chai": "^5.2.1", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-instrument": "^6.0.3", + "istanbul-lib-report": "^3.0.1", + "istanbul-lib-source-maps": "^5.0.6", + "istanbul-reports": "^3.1.7", "pathe": "^2.0.3", "std-env": "^3.9.0", + "swc-plugin-coverage-instrument": "^0.0.28", "tinypool": "^1.1.1" }, "devDependencies": { @@ -72,6 +78,11 @@ "@rstest/tsconfig": "workspace:*", "@sinonjs/fake-timers": "^14.0.0", "@types/babel__code-frame": "^7.0.6", + "@types/istanbul-lib-coverage": "^2.0.6", + "@types/istanbul-lib-instrument": "^1.7.7", + "@types/istanbul-lib-report": "^3.0.3", + "@types/istanbul-lib-source-maps": "^4.0.4", + "@types/istanbul-reports": "^3.0.4", "@types/jsdom": "^21.1.7", "@types/sinonjs__fake-timers": "^8.1.5", "@types/source-map-support": "^0.5.10", diff --git a/packages/core/src/config.ts b/packages/core/src/config.ts index dcd18e70..d126dd1d 100644 --- a/packages/core/src/config.ts +++ b/packages/core/src/config.ts @@ -108,6 +108,9 @@ const createDefaultConfig = (): NormalizedConfig => ({ maxConcurrency: 5, printConsoleTrace: false, disableConsoleIntercept: false, + coverage: { + enabled: false, + }, }); export const withDefaultConfig = (config: RstestConfig): NormalizedConfig => { diff --git a/packages/core/src/core/rsbuild.ts b/packages/core/src/core/rsbuild.ts index 4efa09bf..ed290410 100644 --- a/packages/core/src/core/rsbuild.ts +++ b/packages/core/src/core/rsbuild.ts @@ -125,6 +125,7 @@ export const prepareRsbuild = async ( testEnvironment, performance, dev = {}, + coverage, }, } = context; const debugMode = isDebug(); @@ -221,6 +222,27 @@ export const prepareRsbuild = async ( ...(config.module.parser.javascript || {}), }; + if (coverage?.enabled && coverage?.provider === 'istanbul') { + const swcPluginCoverageInstrument = `${process.cwd()}/node_modules/@rstest/coverage-istanbul/node_modules/swc-plugin-coverage-instrument/target/wasm32-wasip1/release/swc_plugin_coverage.wasm`; + config.module.rules ??= []; + config.module.rules.push({ + test: /\.(js|ts)$/, + exclude: [/node_modules/], + loader: 'builtin:swc-loader', + options: { + jsc: { + parser: { + syntax: 'typescript', + }, + experimental: { + plugins: [[swcPluginCoverageInstrument, {}]], + }, + }, + }, + type: 'javascript/auto', + }); + } + config.resolve ??= {}; config.resolve.extensions ??= []; config.resolve.extensions.push('.cjs'); @@ -265,7 +287,6 @@ export const prepareRsbuild = async ( }, }, }); - if (!isolate) { rsbuildInstance.addPlugins([pluginCacheControl(Object.values(setupFiles))]); } diff --git a/packages/core/src/core/runTests.ts b/packages/core/src/core/runTests.ts index a6b590c8..a3749684 100644 --- a/packages/core/src/core/runTests.ts +++ b/packages/core/src/core/runTests.ts @@ -1,8 +1,11 @@ +import istanbulLibCoverage from 'istanbul-lib-coverage'; +import { createCoverageProvider } from '../coverage'; import { createPool } from '../pool'; import type { RstestContext } from '../types'; import { color, getSetupFiles, getTestEntries, logger } from '../utils'; import { createRsbuildServer, prepareRsbuild } from './rsbuild'; +const { createCoverageMap } = istanbulLibCoverage; export async function runTests( context: RstestContext, fileFilters: string[], @@ -75,6 +78,11 @@ export async function runTests( } = await getRsbuildStats(); const testStart = Date.now(); + // Initialize coverage collector + const coverageProvider = createCoverageProvider( + context.normalizedConfig.coverage || {}, + ); + const pool = await createPool({ entries, sourceMaps, @@ -93,6 +101,33 @@ export async function runTests( testTime, }; + // Generate coverage reports after all tests complete + if (coverageProvider) { + try { + // Collect coverage data from all test results + + const finalCoverageMap = createCoverageMap(); + + // Merge coverage data from all test files + for (const result of results) { + if ((result as any).coverage) { + finalCoverageMap.merge((result as any).coverage); + } + } + + // Generate coverage reports + await coverageProvider.generateReports( + finalCoverageMap, + context.normalizedConfig.coverage!, + ); + + // Cleanup + coverageProvider.cleanup(); + } catch (error) { + logger.error('Failed to generate coverage reports:', error); + } + } + if (results.some((r) => r.status === 'fail')) { process.exitCode = 1; } diff --git a/packages/core/src/coverage/index.ts b/packages/core/src/coverage/index.ts new file mode 100644 index 00000000..8dc4c3d5 --- /dev/null +++ b/packages/core/src/coverage/index.ts @@ -0,0 +1,23 @@ +import type { CoverageOptions } from '../types/coverage'; +import type { CoverageProvider } from './istanbul'; +import { IstanbulCoverageProvider } from './istanbul'; + +export function createCoverageProvider( + options: CoverageOptions, +): CoverageProvider | null { + if (!options.enabled) { + return null; + } + + switch (options.provider) { + case 'istanbul': + return new IstanbulCoverageProvider(); + case 'v8': + // TODO: Implement V8 coverage collector + throw new Error('V8 coverage provider is not implemented yet'); + default: + return new IstanbulCoverageProvider(); + } +} + +export type { CoverageProvider } from './istanbul'; diff --git a/packages/core/src/coverage/istanbul.ts b/packages/core/src/coverage/istanbul.ts new file mode 100644 index 00000000..f64140e2 --- /dev/null +++ b/packages/core/src/coverage/istanbul.ts @@ -0,0 +1,114 @@ +import istanbulLibCoverage from 'istanbul-lib-coverage'; +import type { CoverageOptions } from '../types/coverage'; + +const { createCoverageMap } = istanbulLibCoverage; + +import { createContext } from 'istanbul-lib-report'; +import reports from 'istanbul-reports'; + +interface CoverageMap { + files(): string[]; + merge(other: any): void; + toJSON(): any; +} + +// Global type declaration for coverage +declare global { + var __coverage__: any; +} + +export interface CoverageProvider { + /** + * Initialize coverage collection + */ + init(): void; + + /** + * Collect coverage data from global coverage object + */ + collect(): CoverageMap | null; + + /** + * Generate coverage reports + */ + generateReports( + coverageMap: CoverageMap, + options: CoverageOptions, + ): Promise; + + /** + * Clean up coverage data + */ + cleanup(): void; +} + +export class IstanbulCoverageProvider implements CoverageProvider { + private coverageMap: CoverageMap | null = null; + + init(): void { + // Initialize global coverage object + if (typeof globalThis !== 'undefined') { + (globalThis as any).__coverage__ = (globalThis as any).__coverage__ || {}; + } + } + + collect(): CoverageMap | null { + if ( + typeof globalThis === 'undefined' || + !(globalThis as any).__coverage__ + ) { + return null; + } + + try { + if (!this.coverageMap) { + this.coverageMap = createCoverageMap(); + } + // Merge current coverage data + if (this.coverageMap) { + this.coverageMap.merge((globalThis as any).__coverage__); + } + + return this.coverageMap; + } catch (error) { + console.warn('Failed to collect coverage data:', error); + return null; + } + } + + async generateReports( + coverageMap: CoverageMap, + options: CoverageOptions, + ): Promise { + console.log(options); + if (!coverageMap || coverageMap.files().length === 0) { + return; + } + + try { + const context = createContext({ + dir: 'coverage', + defaultSummarizer: 'nested', + coverageMap: createCoverageMap(coverageMap.toJSON()), + }); + const reportersList = ['html', 'json']; + for (const reporter of reportersList) { + const report = reports.create(reporter as any, { + // Add any specific options for the reporter here + }); + report.execute(context); + } + + console.log('\nCoverage reports generated in ./coverage directory'); + } catch (error) { + console.error('Failed to generate coverage reports:', error); + } + } + + cleanup(): void { + if (typeof globalThis !== 'undefined' && '__coverage__' in globalThis) { + delete (globalThis as any).__coverage__; + } + this.coverageMap = null; + } +} diff --git a/packages/core/src/pool/index.ts b/packages/core/src/pool/index.ts index abddbcfe..70680ce6 100644 --- a/packages/core/src/pool/index.ts +++ b/packages/core/src/pool/index.ts @@ -141,6 +141,7 @@ export const createPool = async ({ disableConsoleIntercept, testEnvironment, hookTimeout, + coverage, } = context.normalizedConfig; const runtimeConfig = { @@ -160,6 +161,7 @@ export const createPool = async ({ disableConsoleIntercept, testEnvironment, isolate, + coverage, }; const rpcMethods = { diff --git a/packages/core/src/runtime/runner/runner.ts b/packages/core/src/runtime/runner/runner.ts index 66647e1f..82c9933c 100644 --- a/packages/core/src/runtime/runner/runner.ts +++ b/packages/core/src/runtime/runner/runner.ts @@ -1,5 +1,6 @@ import { GLOBAL_EXPECT, getState, setState } from '@vitest/expect'; import type { SnapshotState } from '@vitest/snapshot'; +import type { CoverageProvider } from '../../coverage'; import type { AfterEachListener, BeforeEachListener, @@ -43,6 +44,7 @@ export class TestRunner { state: WorkerState; hooks: RunnerHooks; api: Rstest; + coverageProvider?: CoverageProvider; }): Promise { this.workerState = state; const { diff --git a/packages/core/src/runtime/worker/index.ts b/packages/core/src/runtime/worker/index.ts index 7e4ee9d1..4c5e3aa4 100644 --- a/packages/core/src/runtime/worker/index.ts +++ b/packages/core/src/runtime/worker/index.ts @@ -7,6 +7,7 @@ import type { WorkerState, } from '../../types'; import './setup'; +import { createCoverageProvider } from '../../coverage'; import { globalApis } from '../../utils/constants'; import { color, undoSerializableConfig } from '../../utils/helper'; import { formatTestError } from '../util'; @@ -296,6 +297,13 @@ const runInPool = async ( unhandledErrors, interopDefault, } = await preparePool(options); + // Initialize coverage collector if coverage is enabled + const coverageProvider = createCoverageProvider( + options.context.runtimeConfig.coverage || {}, + ); + if (coverageProvider) { + coverageProvider.init(); + } cleanups.push(cleanup); @@ -315,6 +323,14 @@ const runInPool = async ( await rpc.onTestFileStart(test); }, onTestFileResult: async (test) => { + // Collect coverage data after test file completes + if (coverageProvider) { + const coverageMap = coverageProvider.collect(); + if (coverageMap) { + // Attach coverage data to test result + (test as any).coverage = coverageMap.toJSON(); + } + } await rpc.onTestFileResult(test); }, onTestCaseResult: async (result) => { diff --git a/packages/core/src/types/config.ts b/packages/core/src/types/config.ts index 3405ddfb..70d0dbdb 100644 --- a/packages/core/src/types/config.ts +++ b/packages/core/src/types/config.ts @@ -1,4 +1,5 @@ import type { RsbuildConfig } from '@rsbuild/core'; +import type { CoverageOptions } from './coverage'; import type { BuiltInReporterNames, Reporter, @@ -183,6 +184,11 @@ export interface RstestConfig { */ onConsoleLog?: (content: string) => boolean | void; + /** + * Coverage options + */ + coverage?: CoverageOptions; + // Rsbuild configs plugins?: RsbuildConfig['plugins']; diff --git a/packages/core/src/types/coverage.ts b/packages/core/src/types/coverage.ts new file mode 100644 index 00000000..b3769606 --- /dev/null +++ b/packages/core/src/types/coverage.ts @@ -0,0 +1,13 @@ +export type CoverageOptions = { + /** + * Enable coverage collection. + * @default false + */ + enabled?: boolean; + + /** + * The provider to use for coverage collection. + * @default 'istanbul' + */ + provider?: 'istanbul' | 'v8'; +}; diff --git a/packages/core/src/types/index.ts b/packages/core/src/types/index.ts index 0ac0e93d..38099e48 100644 --- a/packages/core/src/types/index.ts +++ b/packages/core/src/types/index.ts @@ -1,6 +1,7 @@ export type * from './api'; export type * from './config'; export type * from './core'; +export type * from './coverage'; export type * from './environment'; export type * from './expect'; export type * from './mock'; diff --git a/packages/core/src/types/worker.ts b/packages/core/src/types/worker.ts index 0441e21c..a920224e 100644 --- a/packages/core/src/types/worker.ts +++ b/packages/core/src/types/worker.ts @@ -46,6 +46,7 @@ export type RuntimeConfig = Pick< | 'testEnvironment' | 'isolate' | 'hookTimeout' + | 'coverage' >; export type WorkerContext = { diff --git a/packages/coverage-istanbul/.gitignore b/packages/coverage-istanbul/.gitignore new file mode 100644 index 00000000..b538abcd --- /dev/null +++ b/packages/coverage-istanbul/.gitignore @@ -0,0 +1,14 @@ +# Local +.DS_Store +*.local +*.log* + +# Dist +node_modules +dist/ +storybook-static + +# IDE +.vscode/* +!.vscode/extensions.json +.idea diff --git a/packages/coverage-istanbul/README.md b/packages/coverage-istanbul/README.md new file mode 100644 index 00000000..ae4f5bbe --- /dev/null +++ b/packages/coverage-istanbul/README.md @@ -0,0 +1,23 @@ +# Rslib project + +## Setup + +Install the dependencies: + +```bash +pnpm install +``` + +## Get started + +Build the library: + +```bash +pnpm build +``` + +Build the library in watch mode: + +```bash +pnpm dev +``` diff --git a/packages/coverage-istanbul/package.json b/packages/coverage-istanbul/package.json new file mode 100644 index 00000000..ca15cfb1 --- /dev/null +++ b/packages/coverage-istanbul/package.json @@ -0,0 +1,30 @@ +{ + "name": "@rstest/coverage-istanbul", + "version": "0.0.1-alpha.0", + "type": "module", + "description": "Istanbul coverage provider for Rstest", + "author": "Travis Zhang", + "license": "MIT", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + } + }, + "types": "./dist/index.d.ts", + "files": [ + "dist" + ], + "scripts": { + "build": "rslib build", + "dev": "rslib build --watch" + }, + "dependencies": { + "swc-plugin-coverage-instrument": "^0.0.28" + }, + "devDependencies": { + "@rslib/core": "^0.11.0", + "@types/node": "^22.16.5", + "typescript": "^5.8.3" + } +} diff --git a/packages/coverage-istanbul/rslib.config.ts b/packages/coverage-istanbul/rslib.config.ts new file mode 100644 index 00000000..75a1f201 --- /dev/null +++ b/packages/coverage-istanbul/rslib.config.ts @@ -0,0 +1,11 @@ +import { defineConfig } from '@rslib/core'; + +export default defineConfig({ + lib: [ + { + format: 'esm', + syntax: ['node 18'], + dts: true, + }, + ], +}); diff --git a/packages/coverage-istanbul/src/index.ts b/packages/coverage-istanbul/src/index.ts new file mode 100644 index 00000000..fdf0e116 --- /dev/null +++ b/packages/coverage-istanbul/src/index.ts @@ -0,0 +1 @@ +export const squared = (n: number): number => n * n; diff --git a/packages/coverage-istanbul/tsconfig.json b/packages/coverage-istanbul/tsconfig.json new file mode 100644 index 00000000..8c5c4d6d --- /dev/null +++ b/packages/coverage-istanbul/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "lib": ["ES2021"], + "module": "ESNext", + "noEmit": true, + "strict": true, + "skipLibCheck": true, + "isolatedModules": true, + "resolveJsonModule": true, + "moduleResolution": "bundler", + "useDefineForClassFields": true, + "allowImportingTsExtensions": true + }, + "include": ["src"] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4e7ebeac..88274978 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -27,7 +27,7 @@ importers: version: 11.0.4 '@types/node': specifier: ^22.13.8 - version: 22.13.8 + version: 22.16.5 check-dependency-version-consistency: specifier: ^5.0.1 version: 5.0.1 @@ -70,9 +70,12 @@ importers: '@rstest/core': specifier: workspace:* version: link:../../packages/core + '@rstest/coverage-istanbul': + specifier: workspace:* + version: link:../../packages/coverage-istanbul '@types/node': specifier: ^22.13.8 - version: 22.13.8 + version: 22.16.5 typescript: specifier: ^5.8.3 version: 5.8.3 @@ -131,12 +134,30 @@ importers: chai: specifier: ^5.2.1 version: 5.2.1 + istanbul-lib-coverage: + specifier: ^3.2.2 + version: 3.2.2 + istanbul-lib-instrument: + specifier: ^6.0.3 + version: 6.0.3 + istanbul-lib-report: + specifier: ^3.0.1 + version: 3.0.1 + istanbul-lib-source-maps: + specifier: ^5.0.6 + version: 5.0.6 + istanbul-reports: + specifier: ^3.1.7 + version: 3.1.7 pathe: specifier: ^2.0.3 version: 2.0.3 std-env: specifier: ^3.9.0 version: 3.9.0 + swc-plugin-coverage-instrument: + specifier: ^0.0.28 + version: 0.0.28 tinypool: specifier: ^1.1.1 version: 1.1.1 @@ -149,10 +170,10 @@ importers: version: 0.3.29 '@microsoft/api-extractor': specifier: ^7.52.8 - version: 7.52.8(@types/node@22.13.8) + version: 7.52.8(@types/node@22.16.5) '@rslib/core': specifier: 0.11.0 - version: 0.11.0(@microsoft/api-extractor@7.52.8(@types/node@22.13.8))(typescript@5.8.3) + version: 0.11.0(@microsoft/api-extractor@7.52.8(@types/node@22.16.5))(typescript@5.8.3) '@rstest/tsconfig': specifier: workspace:* version: link:../../scripts/tsconfig @@ -162,6 +183,21 @@ importers: '@types/babel__code-frame': specifier: ^7.0.6 version: 7.0.6 + '@types/istanbul-lib-coverage': + specifier: ^2.0.6 + version: 2.0.6 + '@types/istanbul-lib-instrument': + specifier: ^1.7.7 + version: 1.7.7 + '@types/istanbul-lib-report': + specifier: ^3.0.3 + version: 3.0.3 + '@types/istanbul-lib-source-maps': + specifier: ^4.0.4 + version: 4.0.4 + '@types/istanbul-reports': + specifier: ^3.0.4 + version: 3.0.4 '@types/jsdom': specifier: ^21.1.7 version: 21.1.7 @@ -205,6 +241,22 @@ importers: specifier: ^4.0.3 version: 4.0.3 + packages/coverage-istanbul: + dependencies: + swc-plugin-coverage-instrument: + specifier: ^0.0.28 + version: 0.0.28 + devDependencies: + '@rslib/core': + specifier: ^0.11.0 + version: 0.11.0(@microsoft/api-extractor@7.52.8(@types/node@22.16.5))(typescript@5.8.3) + '@types/node': + specifier: ^22.16.5 + version: 22.16.5 + typescript: + specifier: ^5.8.3 + version: 5.8.3 + scripts/tsconfig: {} tests: @@ -214,7 +266,7 @@ importers: version: 1.4.8 '@rslib/core': specifier: 0.11.0 - version: 0.11.0(@microsoft/api-extractor@7.52.8(@types/node@22.13.8))(typescript@5.8.3) + version: 0.11.0(@microsoft/api-extractor@7.52.8(@types/node@22.16.5))(typescript@5.8.3) '@rstest/core': specifier: workspace:* version: link:../packages/core @@ -441,7 +493,7 @@ importers: version: link:../scripts/tsconfig '@types/node': specifier: ^22.13.8 - version: 22.13.8 + version: 22.16.5 '@types/react': specifier: ^19.1.8 version: 19.1.8 @@ -851,6 +903,10 @@ packages: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} + '@istanbuljs/schema@0.1.3': + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + '@jest/diff-sequences@30.0.1': resolution: {integrity: sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} @@ -1396,6 +1452,9 @@ packages: '@types/aria-query@5.0.4': resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + '@types/babel-types@7.0.16': + resolution: {integrity: sha512-5QXs9GBFTNTmilLlWBhnsprqpjfrotyrnzUdwDrywEL/DA4LuCWQT300BTOXA3Y9ngT9F2uvmCoIxI6z8DlJEA==} + '@types/babel__code-frame@7.0.6': resolution: {integrity: sha512-Anitqkl3+KrzcW2k77lRlg/GfLZLWXBuNgbEcIOU6M92yw42vsd3xV/Z/yAHEj8m+KUjL6bWOVOFqX8PFPJ4LA==} @@ -1450,9 +1509,15 @@ packages: '@types/istanbul-lib-coverage@2.0.6': resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} + '@types/istanbul-lib-instrument@1.7.7': + resolution: {integrity: sha512-xyV3cVIhVuVAT7wyJXT+lliOo4b7BpfsnfCDy0/nuuAX+J7RB2rWNDV/7hkmv62vwqAD2XQ2Fgt6OwWGWEYfvg==} + '@types/istanbul-lib-report@3.0.3': resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} + '@types/istanbul-lib-source-maps@4.0.4': + resolution: {integrity: sha512-p+nSH0hBMLvuqgnT0rbBnDcfO3IuOZrLU+Yf4x0BhGVmXynB+gm9D35gAvWeMuk+riik5Rj12NBQm8rnzIPH3g==} + '@types/istanbul-reports@3.0.4': resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} @@ -1489,8 +1554,8 @@ packages: '@types/node@20.19.4': resolution: {integrity: sha512-OP+We5WV8Xnbuvw0zC2m4qfB/BJvjyCwtNjhHdJxV1639SGSKrLmJkc3fMnp2Qy8nJyHp8RO6umxELN/dS1/EA==} - '@types/node@22.13.8': - resolution: {integrity: sha512-G3EfaZS+iOGYWLLRCEAXdWK9my08oHNZ+FHluRiggIYJPOXzhOiDgpVCUHaUvyIC5/fj7C/p637jdzC666AOKQ==} + '@types/node@22.16.5': + resolution: {integrity: sha512-bJFoMATwIGaxxx8VJPeM8TonI8t579oRvgAuT8zFugJsJZgzqv0Fu8Mhp68iecjzG7cnN3mO2dJQ5uUM2EFrgQ==} '@types/pixelmatch@5.2.6': resolution: {integrity: sha512-wC83uexE5KGuUODn6zkm9gMzTwdY5L0chiK+VrKcDfEjzxh1uadlWTvOmAbCpnM9zx/Ww3f8uKlYQVnO/TrqVg==} @@ -1844,8 +1909,8 @@ packages: browserslist-to-es-version@1.0.0: resolution: {integrity: sha512-i6dR03ClGy9ti97FSa4s0dpv01zW/t5VbvGjFfTLsrRQFsPgSeyGkCrlU7BTJuI5XDHVY5S2JgDnDsvQXifJ8w==} - browserslist@4.24.5: - resolution: {integrity: sha512-FDToo4Wo82hIdgc1CQ+NQD0hEhmpPjrZ3hiUgwgOG6IuTdlpr8jdjyG24P6cNP1yJpTLzS5OcGgSw0xmDU1/Tw==} + browserslist@4.25.1: + resolution: {integrity: sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -1874,8 +1939,8 @@ packages: resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} engines: {node: '>= 0.4'} - caniuse-lite@1.0.30001718: - resolution: {integrity: sha512-AflseV1ahcSunK53NfEs9gFWgOEmzr0f+kaMFA4xiLZlr9Hzt7HxcSpIFcnNCUkz6R6dWKa54rUz3HUmI3nVcw==} + caniuse-lite@1.0.30001727: + resolution: {integrity: sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==} ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -2067,6 +2132,15 @@ packages: supports-color: optional: true + debug@4.4.1: + resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + decimal.js@10.5.0: resolution: {integrity: sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==} @@ -2175,8 +2249,8 @@ packages: ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - electron-to-chromium@1.5.150: - resolution: {integrity: sha512-rOOkP2ZUMx1yL4fCxXQKDHQ8ZXwisb2OycOQVKHgvB3ZI4CvehOd4y2tfnnLDieJ3Zs1RL1Dlp3cMkyIn7nnXA==} + electron-to-chromium@1.5.187: + resolution: {integrity: sha512-cl5Jc9I0KGUoOoSbxvTywTa40uspGJt/BDBoDLoxJRSBpWh4FFXBsjNRHfQrONsV/OoEjDfHUmZQa2d6Ze4YgA==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -2767,6 +2841,26 @@ packages: resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} engines: {node: '>=0.10.0'} + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-instrument@6.0.3: + resolution: {integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==} + engines: {node: '>=10'} + + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-lib-source-maps@5.0.6: + resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==} + engines: {node: '>=10'} + + istanbul-reports@3.1.7: + resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} + engines: {node: '>=8'} + iterate-object@1.3.5: resolution: {integrity: sha512-eL23u8oFooYTq6TtJKjp2RYjZnCkUYQvC0T/6fJfWykXJ3quvdDdzKZ3CEjy8b3JGOvLTjDYMEMIp5243R906A==} @@ -2959,6 +3053,10 @@ packages: magic-string@0.30.17: resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + markdown-extensions@2.0.0: resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} engines: {node: '>=16'} @@ -3994,6 +4092,9 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + swc-plugin-coverage-instrument@0.0.28: + resolution: {integrity: sha512-ps70ske/LiIubyKOakw5rSOjHOIv6ecyyGQY0BctkVS2t776qtIVS2nqpAUaw3g5VMgAGoq/TShV12D3D7n3ag==} + symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} @@ -4162,9 +4263,6 @@ packages: engines: {node: '>=14.17'} hasBin: true - undici-types@6.20.0: - resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} - undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} @@ -4497,7 +4595,7 @@ snapshots: '@babel/traverse': 7.28.0 '@babel/types': 7.28.0 convert-source-map: 2.0.0 - debug: 4.3.7 + debug: 4.4.1 gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -4520,7 +4618,7 @@ snapshots: dependencies: '@babel/compat-data': 7.28.0 '@babel/helper-validator-option': 7.27.1 - browserslist: 4.24.5 + browserslist: 4.25.1 lru-cache: 5.1.1 semver: 6.3.1 @@ -4679,7 +4777,7 @@ snapshots: '@babel/parser': 7.28.0 '@babel/template': 7.27.2 '@babel/types': 7.28.0 - debug: 4.3.7 + debug: 4.4.1 transitivePeerDependencies: - supports-color @@ -4911,6 +5009,8 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 + '@istanbuljs/schema@0.1.3': {} + '@jest/diff-sequences@30.0.1': {} '@jest/expect-utils@30.0.3': @@ -4921,7 +5021,7 @@ snapshots: '@jest/pattern@30.0.1': dependencies: - '@types/node': 22.13.8 + '@types/node': 22.16.5 jest-regex-util: 30.0.1 '@jest/schemas@30.0.1': @@ -4934,7 +5034,7 @@ snapshots: '@jest/schemas': 30.0.1 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 22.13.8 + '@types/node': 22.16.5 '@types/yargs': 17.0.33 chalk: 4.1.2 @@ -5041,23 +5141,23 @@ snapshots: '@types/react': 19.1.8 react: 19.1.0 - '@microsoft/api-extractor-model@7.30.6(@types/node@22.13.8)': + '@microsoft/api-extractor-model@7.30.6(@types/node@22.16.5)': dependencies: '@microsoft/tsdoc': 0.15.1 '@microsoft/tsdoc-config': 0.17.1 - '@rushstack/node-core-library': 5.13.1(@types/node@22.13.8) + '@rushstack/node-core-library': 5.13.1(@types/node@22.16.5) transitivePeerDependencies: - '@types/node' - '@microsoft/api-extractor@7.52.8(@types/node@22.13.8)': + '@microsoft/api-extractor@7.52.8(@types/node@22.16.5)': dependencies: - '@microsoft/api-extractor-model': 7.30.6(@types/node@22.13.8) + '@microsoft/api-extractor-model': 7.30.6(@types/node@22.16.5) '@microsoft/tsdoc': 0.15.1 '@microsoft/tsdoc-config': 0.17.1 - '@rushstack/node-core-library': 5.13.1(@types/node@22.13.8) + '@rushstack/node-core-library': 5.13.1(@types/node@22.16.5) '@rushstack/rig-package': 0.5.3 - '@rushstack/terminal': 0.15.3(@types/node@22.13.8) - '@rushstack/ts-command-line': 5.0.1(@types/node@22.13.8) + '@rushstack/terminal': 0.15.3(@types/node@22.16.5) + '@rushstack/ts-command-line': 5.0.1(@types/node@22.16.5) lodash: 4.17.21 minimatch: 3.0.8 resolve: 1.22.10 @@ -5359,13 +5459,13 @@ snapshots: - supports-color - webpack - '@rslib/core@0.11.0(@microsoft/api-extractor@7.52.8(@types/node@22.13.8))(typescript@5.8.3)': + '@rslib/core@0.11.0(@microsoft/api-extractor@7.52.8(@types/node@22.16.5))(typescript@5.8.3)': dependencies: '@rsbuild/core': 1.4.8 - rsbuild-plugin-dts: 0.11.0(@microsoft/api-extractor@7.52.8(@types/node@22.13.8))(@rsbuild/core@1.4.8)(typescript@5.8.3) + rsbuild-plugin-dts: 0.11.0(@microsoft/api-extractor@7.52.8(@types/node@22.16.5))(@rsbuild/core@1.4.8)(typescript@5.8.3) tinyglobby: 0.2.14 optionalDependencies: - '@microsoft/api-extractor': 7.52.8(@types/node@22.13.8) + '@microsoft/api-extractor': 7.52.8(@types/node@22.16.5) typescript: 5.8.3 '@rspack/binding-darwin-arm64@1.4.8': @@ -5566,7 +5666,7 @@ snapshots: - react - react-dom - '@rushstack/node-core-library@5.13.1(@types/node@22.13.8)': + '@rushstack/node-core-library@5.13.1(@types/node@22.16.5)': dependencies: ajv: 8.13.0 ajv-draft-04: 1.0.0(ajv@8.13.0) @@ -5577,23 +5677,23 @@ snapshots: resolve: 1.22.10 semver: 7.5.4 optionalDependencies: - '@types/node': 22.13.8 + '@types/node': 22.16.5 '@rushstack/rig-package@0.5.3': dependencies: resolve: 1.22.10 strip-json-comments: 3.1.1 - '@rushstack/terminal@0.15.3(@types/node@22.13.8)': + '@rushstack/terminal@0.15.3(@types/node@22.16.5)': dependencies: - '@rushstack/node-core-library': 5.13.1(@types/node@22.13.8) + '@rushstack/node-core-library': 5.13.1(@types/node@22.16.5) supports-color: 8.1.1 optionalDependencies: - '@types/node': 22.13.8 + '@types/node': 22.16.5 - '@rushstack/ts-command-line@5.0.1(@types/node@22.13.8)': + '@rushstack/ts-command-line@5.0.1(@types/node@22.16.5)': dependencies: - '@rushstack/terminal': 0.15.3(@types/node@22.13.8) + '@rushstack/terminal': 0.15.3(@types/node@22.16.5) '@types/argparse': 1.0.38 argparse: 1.0.10 string-argv: 0.3.2 @@ -5709,6 +5809,8 @@ snapshots: '@types/aria-query@5.0.4': {} + '@types/babel-types@7.0.16': {} + '@types/babel__code-frame@7.0.6': {} '@types/babel__core@7.20.5': @@ -5738,11 +5840,11 @@ snapshots: '@types/connect@3.4.38': dependencies: - '@types/node': 22.13.8 + '@types/node': 22.16.5 '@types/cors@2.8.17': dependencies: - '@types/node': 22.13.8 + '@types/node': 22.16.5 '@types/debug@4.1.12': dependencies: @@ -5771,7 +5873,7 @@ snapshots: '@types/fs-extra@11.0.4': dependencies: '@types/jsonfile': 6.1.4 - '@types/node': 22.13.8 + '@types/node': 22.16.5 '@types/hast@3.0.4': dependencies: @@ -5779,10 +5881,21 @@ snapshots: '@types/istanbul-lib-coverage@2.0.6': {} + '@types/istanbul-lib-instrument@1.7.7': + dependencies: + '@types/babel-types': 7.0.16 + '@types/istanbul-lib-coverage': 2.0.6 + source-map: 0.6.1 + '@types/istanbul-lib-report@3.0.3': dependencies: '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-lib-source-maps@4.0.4': + dependencies: + '@types/istanbul-lib-coverage': 2.0.6 + source-map: 0.6.1 + '@types/istanbul-reports@3.0.4': dependencies: '@types/istanbul-lib-report': 3.0.3 @@ -5802,7 +5915,7 @@ snapshots: '@types/jsdom@21.1.7': dependencies: - '@types/node': 22.13.8 + '@types/node': 22.16.5 '@types/tough-cookie': 4.0.5 parse5: 7.3.0 @@ -5810,7 +5923,7 @@ snapshots: '@types/jsonfile@6.1.4': dependencies: - '@types/node': 22.13.8 + '@types/node': 22.16.5 '@types/mdast@4.0.4': dependencies: @@ -5826,13 +5939,13 @@ snapshots: dependencies: undici-types: 6.21.0 - '@types/node@22.13.8': + '@types/node@22.16.5': dependencies: - undici-types: 6.20.0 + undici-types: 6.21.0 '@types/pixelmatch@5.2.6': dependencies: - '@types/node': 22.13.8 + '@types/node': 22.16.5 '@types/react-dom@19.1.6(@types/react@19.1.8)': dependencies: @@ -6260,14 +6373,14 @@ snapshots: browserslist-to-es-version@1.0.0: dependencies: - browserslist: 4.24.5 + browserslist: 4.25.1 - browserslist@4.24.5: + browserslist@4.25.1: dependencies: - caniuse-lite: 1.0.30001718 - electron-to-chromium: 1.5.150 + caniuse-lite: 1.0.30001727 + electron-to-chromium: 1.5.187 node-releases: 2.0.19 - update-browserslist-db: 1.1.3(browserslist@4.24.5) + update-browserslist-db: 1.1.3(browserslist@4.25.1) buffer-builder@0.2.0: {} @@ -6292,7 +6405,7 @@ snapshots: call-bind-apply-helpers: 1.0.2 get-intrinsic: 1.3.0 - caniuse-lite@1.0.30001718: {} + caniuse-lite@1.0.30001727: {} ccount@2.0.1: {} @@ -6467,6 +6580,10 @@ snapshots: dependencies: ms: 2.1.3 + debug@4.4.1: + dependencies: + ms: 2.1.3 + decimal.js@10.5.0: {} decode-named-character-reference@1.1.0: @@ -6564,7 +6681,7 @@ snapshots: ee-first@1.1.1: {} - electron-to-chromium@1.5.150: {} + electron-to-chromium@1.5.187: {} emoji-regex@8.0.0: {} @@ -6583,7 +6700,7 @@ snapshots: engine.io@6.6.4: dependencies: '@types/cors': 2.8.17 - '@types/node': 22.13.8 + '@types/node': 22.16.5 accepts: 1.3.8 base64id: 2.0.0 cookie: 0.7.2 @@ -7124,14 +7241,14 @@ snapshots: http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.3 - debug: 4.3.7 + debug: 4.4.1 transitivePeerDependencies: - supports-color https-proxy-agent@7.0.6: dependencies: agent-base: 7.1.3 - debug: 4.3.7 + debug: 4.4.1 transitivePeerDependencies: - supports-color @@ -7228,6 +7345,37 @@ snapshots: isobject@3.0.1: {} + istanbul-lib-coverage@3.2.2: {} + + istanbul-lib-instrument@6.0.3: + dependencies: + '@babel/core': 7.28.0 + '@babel/parser': 7.28.0 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 7.7.2 + transitivePeerDependencies: + - supports-color + + istanbul-lib-report@3.0.1: + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + + istanbul-lib-source-maps@5.0.6: + dependencies: + '@jridgewell/trace-mapping': 0.3.29 + debug: 4.4.1 + istanbul-lib-coverage: 3.2.2 + transitivePeerDependencies: + - supports-color + + istanbul-reports@3.1.7: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + iterate-object@1.3.5: {} jackspeak@3.4.3: @@ -7282,7 +7430,7 @@ snapshots: jest-mock@30.0.2: dependencies: '@jest/types': 30.0.1 - '@types/node': 22.13.8 + '@types/node': 22.16.5 jest-util: 30.0.2 jest-regex-util@30.0.1: {} @@ -7290,7 +7438,7 @@ snapshots: jest-util@30.0.2: dependencies: '@jest/types': 30.0.1 - '@types/node': 22.13.8 + '@types/node': 22.16.5 chalk: 4.1.2 ci-info: 4.2.0 graceful-fs: 4.2.11 @@ -7298,7 +7446,7 @@ snapshots: jest-worker@27.5.1: dependencies: - '@types/node': 22.13.8 + '@types/node': 22.16.5 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -7439,6 +7587,10 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 + make-dir@4.0.0: + dependencies: + semver: 7.7.2 + markdown-extensions@2.0.0: {} markdown-table@3.0.4: {} @@ -7868,7 +8020,7 @@ snapshots: micromark@4.0.2: dependencies: '@types/debug': 4.1.12 - debug: 4.3.7 + debug: 4.4.1 decode-named-character-reference: 1.1.0 devlop: 1.1.0 micromark-core-commonmark: 2.0.3 @@ -8403,7 +8555,7 @@ snapshots: rrweb-cssom@0.8.0: {} - rsbuild-plugin-dts@0.11.0(@microsoft/api-extractor@7.52.8(@types/node@22.13.8))(@rsbuild/core@1.4.8)(typescript@5.8.3): + rsbuild-plugin-dts@0.11.0(@microsoft/api-extractor@7.52.8(@types/node@22.16.5))(@rsbuild/core@1.4.8)(typescript@5.8.3): dependencies: '@ast-grep/napi': 0.37.0 '@rsbuild/core': 1.4.8 @@ -8412,7 +8564,7 @@ snapshots: tinyglobby: 0.2.14 tsconfig-paths: 4.2.0 optionalDependencies: - '@microsoft/api-extractor': 7.52.8(@types/node@22.13.8) + '@microsoft/api-extractor': 7.52.8(@types/node@22.16.5) typescript: 5.8.3 rsbuild-plugin-google-analytics@1.0.3(@rsbuild/core@1.4.8): @@ -8768,6 +8920,8 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} + swc-plugin-coverage-instrument@0.0.28: {} + symbol-tree@3.2.4: {} sync-child-process@1.0.2: @@ -8898,8 +9052,6 @@ snapshots: typescript@5.8.3: {} - undici-types@6.20.0: {} - undici-types@6.21.0: {} unhead@2.0.12: @@ -8957,9 +9109,9 @@ snapshots: upath@2.0.1: {} - update-browserslist-db@1.1.3(browserslist@4.24.5): + update-browserslist-db@1.1.3(browserslist@4.25.1): dependencies: - browserslist: 4.24.5 + browserslist: 4.25.1 escalade: 3.2.0 picocolors: 1.1.1 @@ -9061,7 +9213,7 @@ snapshots: '@webassemblyjs/wasm-edit': 1.14.1 '@webassemblyjs/wasm-parser': 1.14.1 acorn: 8.14.1 - browserslist: 4.24.5 + browserslist: 4.25.1 chrome-trace-event: 1.0.4 enhanced-resolve: 5.18.2 es-module-lexer: 1.7.0