Skip to content

Commit

Permalink
Merge branch 'main' into chore/node18-20
Browse files Browse the repository at this point in the history
  • Loading branch information
ghiscoding committed Oct 23, 2023
2 parents 6c4a64b + fc51ad0 commit 619bea5
Show file tree
Hide file tree
Showing 72 changed files with 5,205 additions and 906 deletions.
5 changes: 0 additions & 5 deletions docs/advanced/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ Vitest instance requires the current test mode. It can be either:
- `test` when running runtime tests
- `benchmark` when running benchmarks
- `typecheck` when running type tests
### mode
Expand All @@ -64,10 +63,6 @@ Test mode will only call functions inside `test` or `it`, and throws an error wh
Benchmark mode calls `bench` functions and throws an error, when it encounters `test` or `it`. This mode uses `benchmark.include` and `benchmark.exclude` options in the config to find benchmark files.
#### typecheck
Typecheck mode doesn't _run_ tests. It only analyses types and gives a summary. This mode uses `typecheck.include` and `typecheck.exclude` options in the config to find files to analyze.
### start
You can start running tests or benchmarks with `start` method. You can pass an array of strings to filter test files.
4 changes: 2 additions & 2 deletions docs/api/expect.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ type Awaitable<T> = T | PromiseLike<T>
})
```

Everything in JavaScript is truthy, except `false`, `0`, `''`, `null`, `undefined`, and `NaN`.
Everything in JavaScript is truthy, except `false`, `null`, `undefined`, `NaN`, `0`, `-0`, `0n`, `""` and `document.all`.

## toBeFalsy

Expand Down Expand Up @@ -224,7 +224,7 @@ type Awaitable<T> = T | PromiseLike<T>
})
```

Everything in JavaScript is truthy, except `false`, `0`, `''`, `null`, `undefined`, and `NaN`.
Everything in JavaScript is truthy, except `false`, `null`, `undefined`, `NaN`, `0`, `-0`, `0n`, `""` and `document.all`.

## toBeNull

Expand Down
22 changes: 20 additions & 2 deletions docs/config/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,7 @@ export default defineConfig({

### poolMatchGlobs

- **Type:** `[string, 'threads' | 'forks' | 'vmThreads'][]`
- **Type:** `[string, 'threads' | 'forks' | 'vmThreads' | 'typescript'][]`
- **Default:** `[]`
- **Version:** Since Vitest 0.29.4

Expand Down Expand Up @@ -1319,7 +1319,7 @@ Run all tests in a specific browser. Possible options in different providers:

- **Type:** `boolean`
- **Default:** `process.env.CI`
- **CLI:** `--browser.headless`, `--brower.headless=false`
- **CLI:** `--browser.headless`, `--browser.headless=false`

Run the browser in a `headless` mode. If you are running Vitest in CI, it will be enabled by default.

Expand Down Expand Up @@ -1637,6 +1637,24 @@ Changes the order in which setup files are executed.

Options for configuring [typechecking](/guide/testing-types) test environment.

#### typecheck.enabled

- **Type**: `boolean`
- **Default**: `false`
- **CLI**: `--typecheck`, `--typecheck.enabled`
- **Version**: Since Vitest 1.0.0-beta.3

Enable typechecking alongside your regular tests.

#### typecheck.only

- **Type**: `boolean`
- **Default**: `false`
- **CLI**: `--typecheck.only`
- **Version**: Since Vitest 1.0.0-beta.3

Run only typecheck tests, when typechecking is enabled. When using CLI, this option will automatically enable typechecking.

#### typecheck.checker

- **Type**: `'tsc' | 'vue-tsc' | string`
Expand Down
3 changes: 3 additions & 0 deletions docs/guide/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ Run only [benchmark](https://vitest.dev/guide/features.html#benchmarking-experim
| `--inspect-brk` | Enables Node.js inspector with break |
| `--bail <number>` | Stop test execution when given number of tests have failed |
| `--retry <times>` | Retry the test specific number of times if it fails |
| `--typecheck [options]` | Custom options for typecheck pool. If passed without options, enables typechecking |
| `--typecheck.enabled` | Enable typechecking alongside tests (default: `false`) |
| `--typecheck.only` | Run only typecheck tests. This automatically enables typecheck (default: `false`) |
| `-h, --help` | Display available CLI options |

::: tip
Expand Down
3 changes: 3 additions & 0 deletions docs/guide/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ You can try Vitest online on [StackBlitz](https://vitest.new). It runs Vitest di
```bash [pnpm]
pnpm add -D vitest
```
```bash [bun]
bun add -D vitest
```
:::

:::tip
Expand Down
10 changes: 5 additions & 5 deletions docs/guide/testing-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,12 @@ assertType<string>(answr) //

## Run typechecking

Add this command to your `scripts` section in `package.json`:
To enabled typechecking, just add `--typecheck` flag to your Vitest command in `package.json`:

```json
{
"scripts": {
"typecheck": "vitest typecheck"
"test": "vitest --typecheck"
}
}
```
Expand All @@ -80,13 +80,13 @@ Now you can run typecheck:

```sh
# npm
npm run typecheck
npm run test

# yarn
yarn typecheck
yarn test

# pnpm
pnpm run typecheck
pnpm run test
```

Vitest uses `tsc --noEmit` or `vue-tsc --noEmit`, depending on your configuration, so you can remove these scripts from your pipeline.
2 changes: 1 addition & 1 deletion docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"https-localhost": "^4.7.1",
"unocss": "^0.53.4",
"unplugin-vue-components": "^0.25.1",
"vite": "^4.0.0",
"vite": "^4.5.0",
"vite-plugin-pwa": "^0.16.4",
"vitepress": "1.0.0-beta.5",
"workbox-window": "^7.0.0"
Expand Down
3 changes: 3 additions & 0 deletions examples/react-storybook/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@
"@storybook/addon-actions": "^6.5.5",
"@storybook/addon-essentials": "^6.5.5",
"@storybook/addon-links": "^6.5.5",
"@storybook/addons": "^6.5.5",
"@storybook/builder-vite": "^0.1.35",
"@storybook/client-api": "^6.5.5",
"@storybook/preview-web": "^6.5.5",
"@storybook/react": "^6.5.5",
"@storybook/testing-library": "^0.0.11",
"@storybook/testing-react": "^1.3.0",
Expand Down
7 changes: 4 additions & 3 deletions netlify.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
[build.environment]
NPM_FLAGS = "--version"
NODE_VERSION = "16"
NODE_VERSION = "18"
# don't need playwright for docs build
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD = "1"

[build]
publish = "docs/.vitepress/dist"
command = "npx pnpm@7.8.0 i --store=node_modules/.pnpm-store --no-frozen-lockfile && npm run docs:build"
command = "pnpm docs:build"
ignore = "git diff --quiet $COMMIT_REF $CACHED_COMMIT_REF -- docs/ package.json pnpm-lock.yaml"

[[redirects]]
Expand Down
9 changes: 4 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"type": "module",
"version": "1.0.0-beta.2",
"private": true,
"packageManager": "pnpm@8.7.4",
"packageManager": "pnpm@8.9.2",
"description": "Next generation testing framework powered by Vite",
"scripts": {
"ci": "ni && nr typecheck && nr lint && nr build && nr test:all",
Expand Down Expand Up @@ -56,12 +56,11 @@
"fast-glob": "^3.3.0",
"if-node-version": "^1.1.1",
"lint-staged": "^13.2.3",
"magic-string": "^0.30.1",
"magic-string": "^0.30.5",
"node-fetch-native": "^1.4.0",
"npm-run-all": "^4.1.5",
"ofetch": "^1.3.3",
"pathe": "^1.1.1",
"pnpm": "8.6.6",
"rimraf": "^5.0.1",
"rollup": "^3.29.4",
"rollup-plugin-dts": "^6.0.2",
Expand All @@ -71,12 +70,12 @@
"ts-node": "^10.9.1",
"tsup": "^6.7.0",
"typescript": "^5.1.6",
"vite": "^4.2.1",
"vite": "^4.5.0",
"vitest": "workspace:*"
},
"pnpm": {
"overrides": {
"vite": "^4.4.10",
"vite": "$vite",
"vitest": "workspace:*"
},
"peerDependencyRules": {
Expand Down
2 changes: 1 addition & 1 deletion packages/browser/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
},
"dependencies": {
"estree-walker": "^3.0.3",
"magic-string": "^0.30.4",
"magic-string": "^0.30.5",
"sirv": "^2.0.3"
},
"devDependencies": {
Expand Down
10 changes: 8 additions & 2 deletions packages/browser/src/client/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,14 @@ export function createBrowserRunner(original: any, coverageModule: CoverageHandl
async onAfterRunFiles() {
await super.onAfterRun?.()
const coverage = await coverageModule?.takeCoverage?.()
if (coverage)
await rpc().onAfterSuiteRun({ coverage })

if (coverage) {
await rpc().onAfterSuiteRun({
coverage,
transformMode: 'web',
projectName: this.config.name,
})
}
}

onCollected(files: File[]): unknown {
Expand Down
80 changes: 60 additions & 20 deletions packages/coverage-istanbul/src/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { BaseCoverageProvider } from 'vitest/coverage'
import c from 'picocolors'
import libReport from 'istanbul-lib-report'
import reports from 'istanbul-reports'
import type { CoverageMap } from 'istanbul-lib-coverage'
import type { CoverageMap, CoverageMapData } from 'istanbul-lib-coverage'
import libCoverage from 'istanbul-lib-coverage'
import libSourceMaps from 'istanbul-lib-source-maps'
import { type Instrumenter, createInstrumenter } from 'istanbul-lib-instrument'
Expand All @@ -16,6 +16,8 @@ import _TestExclude from 'test-exclude'
import { COVERAGE_STORE_KEY } from './constants'

type Options = ResolvedCoverageOptions<'istanbul'>
type CoverageByTransformMode = Record<AfterSuiteRunMeta['transformMode'], CoverageMapData[]>
type ProjectName = NonNullable<AfterSuiteRunMeta['projectName']> | typeof DEFAULT_PROJECT

interface TestExclude {
new(opts: {
Expand All @@ -31,6 +33,8 @@ interface TestExclude {
}
}

const DEFAULT_PROJECT = Symbol.for('default-project')

export class IstanbulCoverageProvider extends BaseCoverageProvider implements CoverageProvider {
name = 'istanbul'

Expand All @@ -45,7 +49,7 @@ export class IstanbulCoverageProvider extends BaseCoverageProvider implements Co
* If storing in memory causes issues, we can simply write these into fs in `onAfterSuiteRun`
* and read them back when merging coverage objects in `onAfterAllFilesRun`.
*/
coverages: any[] = []
coverages = new Map<ProjectName, CoverageByTransformMode>()

initialize(ctx: Vitest) {
const config: CoverageIstanbulOptions = ctx.config.coverage
Expand Down Expand Up @@ -106,36 +110,52 @@ export class IstanbulCoverageProvider extends BaseCoverageProvider implements Co
return { code, map }
}

onAfterSuiteRun({ coverage }: AfterSuiteRunMeta) {
this.coverages.push(coverage)
/*
* Coverage and meta information passed from Vitest runners.
* Note that adding new entries here and requiring on those without
* backwards compatibility is a breaking change.
*/
onAfterSuiteRun({ coverage, transformMode, projectName }: AfterSuiteRunMeta) {
if (transformMode !== 'web' && transformMode !== 'ssr')
throw new Error(`Invalid transform mode: ${transformMode}`)

let entry = this.coverages.get(projectName || DEFAULT_PROJECT)

if (!entry) {
entry = { web: [], ssr: [] }
this.coverages.set(projectName || DEFAULT_PROJECT, entry)
}

entry[transformMode].push(coverage as CoverageMapData)
}

async clean(clean = true) {
if (clean && existsSync(this.options.reportsDirectory))
await fs.rm(this.options.reportsDirectory, { recursive: true, force: true, maxRetries: 10 })

this.coverages = []
this.coverages = new Map()
}

async reportCoverage({ allTestsRun }: ReportContext = {}) {
const mergedCoverage: CoverageMap = this.coverages.reduce((coverage, previousCoverageMap) => {
const map = libCoverage.createCoverageMap(coverage)
map.merge(previousCoverageMap)
return map
}, libCoverage.createCoverageMap({}))

if (this.options.all && allTestsRun)
await this.includeUntestedFiles(mergedCoverage)

includeImplicitElseBranches(mergedCoverage)
const coverageMaps = await Promise.all(
Array.from(this.coverages.values()).map(coverages => [
mergeAndTransformCoverage(coverages.ssr),
mergeAndTransformCoverage(coverages.web),
]).flat(),
)

if (this.options.all && allTestsRun) {
const coveredFiles = coverageMaps.map(map => map.files()).flat()
const uncoveredCoverage = await this.getCoverageMapForUncoveredFiles(coveredFiles)

coverageMaps.push(await mergeAndTransformCoverage([uncoveredCoverage]))
}

const sourceMapStore = libSourceMaps.createSourceMapStore()
const coverageMap: CoverageMap = await sourceMapStore.transformCoverage(mergedCoverage)
const coverageMap = mergeCoverageMaps(...coverageMaps)

const context = libReport.createContext({
dir: this.options.reportsDirectory,
coverageMap,
sourceFinder: sourceMapStore.sourceFinder,
watermarks: this.options.watermarks,
})

Expand Down Expand Up @@ -181,19 +201,21 @@ export class IstanbulCoverageProvider extends BaseCoverageProvider implements Co
}
}

async includeUntestedFiles(coverageMap: CoverageMap) {
async getCoverageMapForUncoveredFiles(coveredFiles: string[]) {
// Load, instrument and collect empty coverages from all files which
// are not already in the coverage map
const includedFiles = await this.testExclude.glob(this.ctx.config.root)
const uncoveredFiles = includedFiles
.map(file => resolve(this.ctx.config.root, file))
.filter(file => !coverageMap.data[file])
.filter(file => !coveredFiles.includes(file))

const transformResults = await Promise.all(uncoveredFiles.map(async (filename) => {
const transformResult = await this.ctx.vitenode.transformRequest(filename)
return { transformResult, filename }
}))

const coverageMap = libCoverage.createCoverageMap({})

for (const { transformResult, filename } of transformResults) {
const sourceMap = transformResult?.map

Expand All @@ -209,9 +231,27 @@ export class IstanbulCoverageProvider extends BaseCoverageProvider implements Co
coverageMap.addFileCoverage(lastCoverage)
}
}

return coverageMap.data
}
}

async function mergeAndTransformCoverage(coverages: CoverageMapData[]) {
const mergedCoverage = mergeCoverageMaps(...coverages)
includeImplicitElseBranches(mergedCoverage)

const sourceMapStore = libSourceMaps.createSourceMapStore()
return await sourceMapStore.transformCoverage(mergedCoverage)
}

function mergeCoverageMaps(...coverageMaps: (CoverageMap | CoverageMapData)[]) {
return coverageMaps.reduce<CoverageMap>((coverage, previousCoverageMap) => {
const map = libCoverage.createCoverageMap(coverage)
map.merge(previousCoverageMap)
return map
}, libCoverage.createCoverageMap({}))
}

/**
* Remove possible query parameters from filenames
* - From `/src/components/Header.component.ts?vue&type=script&src=true&lang.ts`
Expand Down
2 changes: 1 addition & 1 deletion packages/coverage-v8/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
"istanbul-lib-report": "^3.0.1",
"istanbul-lib-source-maps": "^4.0.1",
"istanbul-reports": "^3.1.5",
"magic-string": "^0.30.4",
"magic-string": "^0.30.5",
"picocolors": "^1.0.0",
"std-env": "^3.3.3",
"test-exclude": "^6.0.0",
Expand Down
Loading

0 comments on commit 619bea5

Please sign in to comment.