From 76cb9c2a39d477a64824a985ade40507e3bbade1 Mon Sep 17 00:00:00 2001 From: Adam Mathes Date: Fri, 13 Feb 2026 21:34:48 -0800 Subject: feat(vanilla): add testing infrastructure and tests (NK-wjnczv) --- vanilla/node_modules/@vitest/coverage-v8/LICENSE | 21 ++ .../@vitest/coverage-v8/dist/browser.d.ts | 5 + .../@vitest/coverage-v8/dist/browser.js | 58 ++++ .../@vitest/coverage-v8/dist/index.d.ts | 5 + .../node_modules/@vitest/coverage-v8/dist/index.js | 61 +++++ .../coverage-v8/dist/load-provider-CdgAx3rL.js | 11 + .../coverage-v8/dist/pathe.M-eThtNZ-BTaAGrLg.js | 104 ++++++++ .../@vitest/coverage-v8/dist/provider.d.ts | 25 ++ .../@vitest/coverage-v8/dist/provider.js | 296 +++++++++++++++++++++ .../node_modules/@vitest/coverage-v8/package.json | 76 ++++++ 10 files changed, 662 insertions(+) create mode 100644 vanilla/node_modules/@vitest/coverage-v8/LICENSE create mode 100644 vanilla/node_modules/@vitest/coverage-v8/dist/browser.d.ts create mode 100644 vanilla/node_modules/@vitest/coverage-v8/dist/browser.js create mode 100644 vanilla/node_modules/@vitest/coverage-v8/dist/index.d.ts create mode 100644 vanilla/node_modules/@vitest/coverage-v8/dist/index.js create mode 100644 vanilla/node_modules/@vitest/coverage-v8/dist/load-provider-CdgAx3rL.js create mode 100644 vanilla/node_modules/@vitest/coverage-v8/dist/pathe.M-eThtNZ-BTaAGrLg.js create mode 100644 vanilla/node_modules/@vitest/coverage-v8/dist/provider.d.ts create mode 100644 vanilla/node_modules/@vitest/coverage-v8/dist/provider.js create mode 100644 vanilla/node_modules/@vitest/coverage-v8/package.json (limited to 'vanilla/node_modules/@vitest/coverage-v8') diff --git a/vanilla/node_modules/@vitest/coverage-v8/LICENSE b/vanilla/node_modules/@vitest/coverage-v8/LICENSE new file mode 100644 index 0000000..0e5771d --- /dev/null +++ b/vanilla/node_modules/@vitest/coverage-v8/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021-Present VoidZero Inc. and Vitest contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vanilla/node_modules/@vitest/coverage-v8/dist/browser.d.ts b/vanilla/node_modules/@vitest/coverage-v8/dist/browser.d.ts new file mode 100644 index 0000000..e6c7069 --- /dev/null +++ b/vanilla/node_modules/@vitest/coverage-v8/dist/browser.d.ts @@ -0,0 +1,5 @@ +import { CoverageProviderModule } from 'vitest/node'; + +declare const mod: CoverageProviderModule; + +export { mod as default }; diff --git a/vanilla/node_modules/@vitest/coverage-v8/dist/browser.js b/vanilla/node_modules/@vitest/coverage-v8/dist/browser.js new file mode 100644 index 0000000..a57a3e1 --- /dev/null +++ b/vanilla/node_modules/@vitest/coverage-v8/dist/browser.js @@ -0,0 +1,58 @@ +import { cdp } from 'vitest/browser'; +import { l as loadProvider } from './load-provider-CdgAx3rL.js'; + +const session = cdp(); +let enabled = false; +const mod = { + async startCoverage() { + if (enabled) { + return; + } + enabled = true; + await session.send("Profiler.enable"); + await session.send("Profiler.startPreciseCoverage", { + callCount: true, + detailed: true + }); + }, + async takeCoverage() { + const coverage = await session.send("Profiler.takePreciseCoverage"); + const result = []; + // Reduce amount of data sent over rpc by doing some early result filtering + for (const entry of coverage.result) { + if (filterResult(entry)) { + result.push({ + ...entry, + url: decodeURIComponent(entry.url.replace(window.location.origin, "")) + }); + } + } + return { result }; + }, + stopCoverage() { + // Browser mode should not stop coverage as same V8 instance is shared between tests + }, + async getProvider() { + return loadProvider(); + } +}; +function filterResult(coverage) { + if (!coverage.url.startsWith(window.location.origin)) { + return false; + } + if (coverage.url.includes("/node_modules/")) { + return false; + } + if (coverage.url.includes("__vitest_browser__")) { + return false; + } + if (coverage.url.includes("__vitest__/assets")) { + return false; + } + if (coverage.url === window.location.href) { + return false; + } + return true; +} + +export { mod as default }; diff --git a/vanilla/node_modules/@vitest/coverage-v8/dist/index.d.ts b/vanilla/node_modules/@vitest/coverage-v8/dist/index.d.ts new file mode 100644 index 0000000..e6c7069 --- /dev/null +++ b/vanilla/node_modules/@vitest/coverage-v8/dist/index.d.ts @@ -0,0 +1,5 @@ +import { CoverageProviderModule } from 'vitest/node'; + +declare const mod: CoverageProviderModule; + +export { mod as default }; diff --git a/vanilla/node_modules/@vitest/coverage-v8/dist/index.js b/vanilla/node_modules/@vitest/coverage-v8/dist/index.js new file mode 100644 index 0000000..85d9c9d --- /dev/null +++ b/vanilla/node_modules/@vitest/coverage-v8/dist/index.js @@ -0,0 +1,61 @@ +import inspector from 'node:inspector/promises'; +import { fileURLToPath } from 'node:url'; +import { provider } from 'std-env'; +import { l as loadProvider } from './load-provider-CdgAx3rL.js'; +import { n as normalize } from './pathe.M-eThtNZ-BTaAGrLg.js'; + +const session = new inspector.Session(); +let enabled = false; +const mod = { + async startCoverage({ isolate }) { + if (isolate === false && enabled) { + return; + } + enabled = true; + session.connect(); + await session.post("Profiler.enable"); + await session.post("Profiler.startPreciseCoverage", { + callCount: true, + detailed: true + }); + }, + async takeCoverage(options) { + if (provider === "stackblitz") { + return { result: [] }; + } + const coverage = await session.post("Profiler.takePreciseCoverage"); + const result = []; + // Reduce amount of data sent over rpc by doing some early result filtering + for (const entry of coverage.result) { + if (filterResult(entry)) { + result.push({ + ...entry, + startOffset: options?.moduleExecutionInfo?.get(normalize(fileURLToPath(entry.url)))?.startOffset || 0 + }); + } + } + return { result }; + }, + async stopCoverage({ isolate }) { + if (isolate === false) { + return; + } + await session.post("Profiler.stopPreciseCoverage"); + await session.post("Profiler.disable"); + session.disconnect(); + }, + async getProvider() { + return loadProvider(); + } +}; +function filterResult(coverage) { + if (!coverage.url.startsWith("file://")) { + return false; + } + if (coverage.url.includes("/node_modules/")) { + return false; + } + return true; +} + +export { mod as default }; diff --git a/vanilla/node_modules/@vitest/coverage-v8/dist/load-provider-CdgAx3rL.js b/vanilla/node_modules/@vitest/coverage-v8/dist/load-provider-CdgAx3rL.js new file mode 100644 index 0000000..005a532 --- /dev/null +++ b/vanilla/node_modules/@vitest/coverage-v8/dist/load-provider-CdgAx3rL.js @@ -0,0 +1,11 @@ +// to not bundle the provider +const name = "./provider.js"; +async function loadProvider() { + const { V8CoverageProvider } = await import( + /* @vite-ignore */ + name +); + return new V8CoverageProvider(); +} + +export { loadProvider as l }; diff --git a/vanilla/node_modules/@vitest/coverage-v8/dist/pathe.M-eThtNZ-BTaAGrLg.js b/vanilla/node_modules/@vitest/coverage-v8/dist/pathe.M-eThtNZ-BTaAGrLg.js new file mode 100644 index 0000000..3f82a78 --- /dev/null +++ b/vanilla/node_modules/@vitest/coverage-v8/dist/pathe.M-eThtNZ-BTaAGrLg.js @@ -0,0 +1,104 @@ +const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//; +function normalizeWindowsPath(input = "") { + if (!input) { + return input; + } + return input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase()); +} + +const _UNC_REGEX = /^[/\\]{2}/; +const _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/; +const _DRIVE_LETTER_RE = /^[A-Za-z]:$/; +const normalize = function(path) { + if (path.length === 0) { + return "."; + } + path = normalizeWindowsPath(path); + const isUNCPath = path.match(_UNC_REGEX); + const isPathAbsolute = isAbsolute(path); + const trailingSeparator = path[path.length - 1] === "/"; + path = normalizeString(path, !isPathAbsolute); + if (path.length === 0) { + if (isPathAbsolute) { + return "/"; + } + return trailingSeparator ? "./" : "."; + } + if (trailingSeparator) { + path += "/"; + } + if (_DRIVE_LETTER_RE.test(path)) { + path += "/"; + } + if (isUNCPath) { + if (!isPathAbsolute) { + return `//./${path}`; + } + return `//${path}`; + } + return isPathAbsolute && !isAbsolute(path) ? `/${path}` : path; +}; +function normalizeString(path, allowAboveRoot) { + let res = ""; + let lastSegmentLength = 0; + let lastSlash = -1; + let dots = 0; + let char = null; + for (let index = 0; index <= path.length; ++index) { + if (index < path.length) { + char = path[index]; + } else if (char === "/") { + break; + } else { + char = "/"; + } + if (char === "/") { + if (lastSlash === index - 1 || dots === 1) ; else if (dots === 2) { + if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") { + if (res.length > 2) { + const lastSlashIndex = res.lastIndexOf("/"); + if (lastSlashIndex === -1) { + res = ""; + lastSegmentLength = 0; + } else { + res = res.slice(0, lastSlashIndex); + lastSegmentLength = res.length - 1 - res.lastIndexOf("/"); + } + lastSlash = index; + dots = 0; + continue; + } else if (res.length > 0) { + res = ""; + lastSegmentLength = 0; + lastSlash = index; + dots = 0; + continue; + } + } + if (allowAboveRoot) { + res += res.length > 0 ? "/.." : ".."; + lastSegmentLength = 2; + } + } else { + if (res.length > 0) { + res += `/${path.slice(lastSlash + 1, index)}`; + } else { + res = path.slice(lastSlash + 1, index); + } + lastSegmentLength = index - lastSlash - 1; + } + lastSlash = index; + dots = 0; + } else if (char === "." && dots !== -1) { + ++dots; + } else { + dots = -1; + } + } + return res; +} +const isAbsolute = function(p) { + return _IS_ABSOLUTE_RE.test(p); +}; + +export { normalize as n }; diff --git a/vanilla/node_modules/@vitest/coverage-v8/dist/provider.d.ts b/vanilla/node_modules/@vitest/coverage-v8/dist/provider.d.ts new file mode 100644 index 0000000..4b9f969 --- /dev/null +++ b/vanilla/node_modules/@vitest/coverage-v8/dist/provider.d.ts @@ -0,0 +1,25 @@ +import { CoverageMap } from 'istanbul-lib-coverage'; +import { ProxifiedModule } from 'magicast'; +import { Profiler } from 'node:inspector'; +import { ResolvedCoverageOptions, CoverageProvider, Vitest, ReportContext } from 'vitest/node'; +import { BaseCoverageProvider } from 'vitest/coverage'; + +interface ScriptCoverageWithOffset extends Profiler.ScriptCoverage { + startOffset: number; +} +declare class V8CoverageProvider extends BaseCoverageProvider> implements CoverageProvider { + name: "v8"; + version: string; + initialize(ctx: Vitest): void; + createCoverageMap(): CoverageMap; + generateCoverage({ allTestsRun }: ReportContext): Promise; + generateReports(coverageMap: CoverageMap, allTestsRun?: boolean): Promise; + parseConfigModule(configFilePath: string): Promise>; + private getCoverageMapForUncoveredFiles; + private remapCoverage; + private getSources; + private convertCoverage; +} + +export { V8CoverageProvider }; +export type { ScriptCoverageWithOffset }; diff --git a/vanilla/node_modules/@vitest/coverage-v8/dist/provider.js b/vanilla/node_modules/@vitest/coverage-v8/dist/provider.js new file mode 100644 index 0000000..4230309 --- /dev/null +++ b/vanilla/node_modules/@vitest/coverage-v8/dist/provider.js @@ -0,0 +1,296 @@ +import { existsSync, promises } from 'node:fs'; +import { fileURLToPath } from 'node:url'; +import { mergeProcessCovs } from '@bcoe/v8-coverage'; +import astV8ToIstanbul from 'ast-v8-to-istanbul'; +import libCoverage from 'istanbul-lib-coverage'; +import libReport from 'istanbul-lib-report'; +import reports from 'istanbul-reports'; +import { parseModule } from 'magicast'; +import { createDebug } from 'obug'; +import { provider } from 'std-env'; +import c from 'tinyrainbow'; +import { BaseCoverageProvider } from 'vitest/coverage'; +import { parseAstAsync } from 'vitest/node'; +import { n as normalize } from './pathe.M-eThtNZ-BTaAGrLg.js'; + +var version = "4.0.18"; + +const FILE_PROTOCOL = "file://"; +const debug = createDebug("vitest:coverage"); +class V8CoverageProvider extends BaseCoverageProvider { + name = "v8"; + version = version; + initialize(ctx) { + this._initialize(ctx); + } + createCoverageMap() { + return libCoverage.createCoverageMap({}); + } + async generateCoverage({ allTestsRun }) { + const start = debug.enabled ? performance.now() : 0; + const coverageMap = this.createCoverageMap(); + let merged = { result: [] }; + await this.readCoverageFiles({ + onFileRead(coverage) { + merged = mergeProcessCovs([merged, coverage]); + // mergeProcessCovs sometimes loses startOffset, e.g. in vue + merged.result.forEach((result) => { + if (!result.startOffset) { + const original = coverage.result.find((r) => r.url === result.url); + result.startOffset = original?.startOffset || 0; + } + }); + }, + onFinished: async (project, environment) => { + // Source maps can change based on projectName and transform mode. + // Coverage transform re-uses source maps so we need to separate transforms from each other. + const converted = await this.convertCoverage(merged, project, environment); + coverageMap.merge(converted); + merged = { result: [] }; + }, + onDebug: debug + }); + // Include untested files when all tests were run (not a single file re-run) + // or if previous results are preserved by "cleanOnRerun: false" + if (this.options.include != null && (allTestsRun || !this.options.cleanOnRerun)) { + const coveredFiles = coverageMap.files(); + const untestedCoverage = await this.getCoverageMapForUncoveredFiles(coveredFiles); + coverageMap.merge(untestedCoverage); + } + coverageMap.filter((filename) => { + const exists = existsSync(filename); + if (this.options.excludeAfterRemap) { + return exists && this.isIncluded(filename); + } + return exists; + }); + if (debug.enabled) { + debug(`Generate coverage total time ${(performance.now() - start).toFixed()} ms`); + } + return coverageMap; + } + async generateReports(coverageMap, allTestsRun) { + if (provider === "stackblitz") { + this.ctx.logger.log(c.blue(" % ") + c.yellow("@vitest/coverage-v8 does not work on Stackblitz. Report will be empty.")); + } + const context = libReport.createContext({ + dir: this.options.reportsDirectory, + coverageMap, + watermarks: this.options.watermarks + }); + if (this.hasTerminalReporter(this.options.reporter)) { + this.ctx.logger.log(c.blue(" % ") + c.dim("Coverage report from ") + c.yellow(this.name)); + } + for (const reporter of this.options.reporter) { + // Type assertion required for custom reporters + reports.create(reporter[0], { + skipFull: this.options.skipFull, + projectRoot: this.ctx.config.root, + ...reporter[1] + }).execute(context); + } + if (this.options.thresholds) { + await this.reportThresholds(coverageMap, allTestsRun); + } + } + async parseConfigModule(configFilePath) { + return parseModule(await promises.readFile(configFilePath, "utf8")); + } + async getCoverageMapForUncoveredFiles(testedFiles) { + const transform = this.createUncoveredFileTransformer(this.ctx); + const uncoveredFiles = await this.getUntestedFiles(testedFiles); + let index = 0; + const coverageMap = this.createCoverageMap(); + for (const chunk of this.toSlices(uncoveredFiles, this.options.processingConcurrency)) { + if (debug.enabled) { + index += chunk.length; + debug("Uncovered files %d/%d", index, uncoveredFiles.length); + } + await Promise.all(chunk.map(async (filename) => { + let timeout; + let start; + if (debug.enabled) { + start = performance.now(); + timeout = setTimeout(() => debug(c.bgRed(`File "${filename}" is taking longer than 3s`)), 3e3); + } + // Do not use pathToFileURL to avoid encoding filename parts + const url = `file://${filename[0] === "/" ? "" : "/"}${filename}`; + const sources = await this.getSources(url, transform); + coverageMap.merge(await this.remapCoverage(url, 0, sources, [])); + if (debug.enabled) { + clearTimeout(timeout); + const diff = performance.now() - start; + const color = diff > 500 ? c.bgRed : c.bgGreen; + debug(`${color(` ${diff.toFixed()} ms `)} ${filename}`); + } + })); + } + return coverageMap; + } + async remapCoverage(filename, wrapperLength, result, functions) { + let ast; + try { + ast = await parseAstAsync(result.code); + } catch (error) { + this.ctx.logger.error(`Failed to parse ${filename}. Excluding it from coverage.\n`, error); + return {}; + } + return await astV8ToIstanbul({ + code: result.code, + sourceMap: result.map, + ast, + coverage: { + functions, + url: filename + }, + ignoreClassMethods: this.options.ignoreClassMethods, + wrapperLength, + ignoreNode: (node, type) => { + // SSR transformed imports + if (type === "statement" && node.type === "VariableDeclarator" && node.id.type === "Identifier" && node.id.name.startsWith("__vite_ssr_import_")) { + return true; + } + // SSR transformed exports vite@>6.3.5 + if (type === "statement" && node.type === "ExpressionStatement" && node.expression.type === "AssignmentExpression" && node.expression.left.type === "MemberExpression" && node.expression.left.object.type === "Identifier" && node.expression.left.object.name === "__vite_ssr_exports__") { + return true; + } + // SSR transformed exports vite@^6.3.5 + if (type === "statement" && node.type === "VariableDeclarator" && node.id.type === "Identifier" && node.id.name === "__vite_ssr_export_default__") { + return true; + } + // CJS imports as ternaries - e.g. + // const React = __vite__cjsImport0_react.__esModule ? __vite__cjsImport0_react.default : __vite__cjsImport0_react; + if (type === "branch" && node.type === "ConditionalExpression" && node.test.type === "MemberExpression" && node.test.object.type === "Identifier" && node.test.object.name.startsWith("__vite__cjsImport") && node.test.property.type === "Identifier" && node.test.property.name === "__esModule") { + return true; + } + // in-source test with "if (import.meta.vitest)" + if ((type === "branch" || type === "statement") && node.type === "IfStatement" && node.test.type === "MemberExpression" && node.test.property.type === "Identifier" && node.test.property.name === "vitest") { + // SSR + if (node.test.object.type === "Identifier" && node.test.object.name === "__vite_ssr_import_meta__") { + return "ignore-this-and-nested-nodes"; + } + // Web + if (node.test.object.type === "MetaProperty" && node.test.object.meta.name === "import" && node.test.object.property.name === "meta") { + return "ignore-this-and-nested-nodes"; + } + } + // Browser mode's "import.meta.env =" + if (type === "statement" && node.type === "ExpressionStatement" && node.expression.type === "AssignmentExpression" && node.expression.left.type === "MemberExpression" && node.expression.left.object.type === "MetaProperty" && node.expression.left.object.meta.name === "import" && node.expression.left.object.property.name === "meta" && node.expression.left.property.type === "Identifier" && node.expression.left.property.name === "env") { + return true; + } + // SSR mode's "import.meta.env =" + if (type === "statement" && node.type === "ExpressionStatement" && node.expression.type === "AssignmentExpression" && node.expression.left.type === "MemberExpression" && node.expression.left.object.type === "Identifier" && node.expression.left.object.name === "__vite_ssr_import_meta__") { + return true; + } + // SWC's decorators + if (type === "statement" && node.type === "ExpressionStatement" && node.expression.type === "CallExpression" && node.expression.callee.type === "Identifier" && node.expression.callee.name === "_ts_decorate") { + return "ignore-this-and-nested-nodes"; + } + } + }); + } + async getSources(url, onTransform, functions = []) { + const transformResult = await onTransform(removeStartsWith(url, FILE_PROTOCOL)).catch(() => undefined); + const map = transformResult?.map; + const code = transformResult?.code; + if (code == null) { + const filePath = normalize(fileURLToPath(url)); + const original = await promises.readFile(filePath, "utf-8").catch(() => { + // If file does not exist construct a dummy source for it. + // These can be files that were generated dynamically during the test run and were removed after it. + const length = findLongestFunctionLength(functions); + return "/".repeat(length); + }); + return { code: original }; + } + // Vue needs special handling for "map.sources" + if (map) { + map.sources ||= []; + map.sources = map.sources.filter((source) => source != null).map((source) => new URL(source, url).href); + if (map.sources.length === 0) { + map.sources.push(url); + } + } + return { + code, + map + }; + } + async convertCoverage(coverage, project = this.ctx.getRootProject(), environment) { + if (environment === "__browser__" && !project.browser) { + throw new Error(`Cannot access browser module graph because it was torn down.`); + } + async function onTransform(filepath) { + if (environment === "__browser__" && project.browser) { + const result = await project.browser.vite.transformRequest(removeStartsWith(filepath, project.config.root)); + if (result) { + return { + ...result, + code: `${result.code}// ` + }; + } + } + return project.vite.environments[environment].transformRequest(filepath); + } + const scriptCoverages = []; + for (const result of coverage.result) { + if (environment === "__browser__") { + if (result.url.startsWith("/@fs")) { + result.url = `${FILE_PROTOCOL}${removeStartsWith(result.url, "/@fs")}`; + } else if (result.url.startsWith(project.config.root)) { + result.url = `${FILE_PROTOCOL}${result.url}`; + } else { + result.url = `${FILE_PROTOCOL}${project.config.root}${result.url}`; + } + } + if (this.isIncluded(fileURLToPath(result.url))) { + scriptCoverages.push({ + ...result, + url: decodeURIComponent(result.url) + }); + } + } + const coverageMap = this.createCoverageMap(); + let index = 0; + for (const chunk of this.toSlices(scriptCoverages, this.options.processingConcurrency)) { + if (debug.enabled) { + index += chunk.length; + debug("Converting %d/%d", index, scriptCoverages.length); + } + await Promise.all(chunk.map(async ({ url, functions, startOffset }) => { + let timeout; + let start; + if (debug.enabled) { + start = performance.now(); + timeout = setTimeout(() => debug(c.bgRed(`File "${fileURLToPath(url)}" is taking longer than 3s`)), 3e3); + } + const sources = await this.getSources(url, onTransform, functions); + coverageMap.merge(await this.remapCoverage(url, startOffset, sources, functions)); + if (debug.enabled) { + clearTimeout(timeout); + const diff = performance.now() - start; + const color = diff > 500 ? c.bgRed : c.bgGreen; + debug(`${color(` ${diff.toFixed()} ms `)} ${fileURLToPath(url)}`); + } + })); + } + return coverageMap; + } +} +/** +* Find the function with highest `endOffset` to determine the length of the file +*/ +function findLongestFunctionLength(functions) { + return functions.reduce((previous, current) => { + const maxEndOffset = current.ranges.reduce((endOffset, range) => Math.max(endOffset, range.endOffset), 0); + return Math.max(previous, maxEndOffset); + }, 0); +} +function removeStartsWith(filepath, start) { + if (filepath.startsWith(start)) { + return filepath.slice(start.length); + } + return filepath; +} + +export { V8CoverageProvider }; diff --git a/vanilla/node_modules/@vitest/coverage-v8/package.json b/vanilla/node_modules/@vitest/coverage-v8/package.json new file mode 100644 index 0000000..4bb7283 --- /dev/null +++ b/vanilla/node_modules/@vitest/coverage-v8/package.json @@ -0,0 +1,76 @@ +{ + "name": "@vitest/coverage-v8", + "type": "module", + "version": "4.0.18", + "description": "V8 coverage provider for Vitest", + "author": "Anthony Fu ", + "license": "MIT", + "funding": "https://opencollective.com/vitest", + "homepage": "https://github.com/vitest-dev/vitest/tree/main/packages/coverage-v8#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/vitest-dev/vitest.git", + "directory": "packages/coverage-v8" + }, + "bugs": { + "url": "https://github.com/vitest-dev/vitest/issues" + }, + "keywords": [ + "vite", + "vitest", + "test", + "coverage", + "v8" + ], + "sideEffects": false, + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "./browser": { + "types": "./dist/browser.d.ts", + "default": "./dist/browser.js" + }, + "./*": "./*" + }, + "main": "./dist/index.js", + "module": "./dist/index.js", + "types": "./dist/index.d.ts", + "files": [ + "dist" + ], + "peerDependencies": { + "@vitest/browser": "4.0.18", + "vitest": "4.0.18" + }, + "peerDependenciesMeta": { + "@vitest/browser": { + "optional": true + } + }, + "dependencies": { + "@bcoe/v8-coverage": "^1.0.2", + "ast-v8-to-istanbul": "^0.3.10", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.2.0", + "magicast": "^0.5.1", + "obug": "^2.1.1", + "std-env": "^3.10.0", + "tinyrainbow": "^3.0.3", + "@vitest/utils": "4.0.18" + }, + "devDependencies": { + "@types/istanbul-lib-coverage": "^2.0.6", + "@types/istanbul-lib-report": "^3.0.3", + "@types/istanbul-reports": "^3.0.4", + "pathe": "^2.0.3", + "@vitest/browser": "4.0.18", + "vitest": "4.0.18" + }, + "scripts": { + "build": "premove dist && rollup -c", + "dev": "rollup -c --watch --watch.include 'src/**'" + } +} \ No newline at end of file -- cgit v1.2.3