vitest
Advanced tools
Comparing version 0.0.23 to 0.0.24
@@ -0,6 +1,14 @@ | ||
import { UserOptions } from './types'; | ||
export * from './types'; | ||
export * from './suite'; | ||
export * from './config'; | ||
export * from './integrations/chai'; | ||
export * from './integrations/sinon'; | ||
declare module 'vite' { | ||
interface UserConfig { | ||
/** | ||
* Options for Vitest | ||
*/ | ||
test?: UserOptions; | ||
} | ||
} | ||
declare global { | ||
@@ -7,0 +15,0 @@ namespace Chai { |
@@ -1,6 +0,4 @@ | ||
/* eslint-disable @typescript-eslint/no-namespace */ | ||
export * from './types'; | ||
export * from './suite'; | ||
export * from './config'; | ||
export * from './integrations/chai'; | ||
export * from './integrations/sinon'; |
@@ -74,3 +74,3 @@ /* eslint-disable no-console */ | ||
const failedSuites = suites.filter(i => i.error); | ||
const runable = tasks.filter(i => i.state === 'pass' || i.state === 'fail'); | ||
const runnable = tasks.filter(i => i.state === 'pass' || i.state === 'fail'); | ||
const passed = tasks.filter(i => i.state === 'pass'); | ||
@@ -106,5 +106,5 @@ const failed = tasks.filter(i => i.state === 'fail'); | ||
} | ||
console.log(c.bold(c.green(`Passed ${passed.length} / ${runable.length}`))); | ||
console.log(c.bold(c.green(`Passed ${passed.length} / ${runnable.length}`))); | ||
if (failed.length) | ||
console.log(c.bold(c.red(`Failed ${failed.length} / ${runable.length}`))); | ||
console.log(c.bold(c.red(`Failed ${failed.length} / ${runnable.length}`))); | ||
if (skipped.length) | ||
@@ -111,0 +111,0 @@ console.log(c.yellow(`Skipped ${skipped.length}`)); |
import { File, ResolvedConfig, Task, RunnerContext, Suite } from '../types'; | ||
export declare function runTask(task: Task, ctx: RunnerContext): Promise<void>; | ||
export declare function collectFiles(paths: string[]): Promise<Record<string, File>>; | ||
export declare function runSite(suite: Suite, ctx: RunnerContext): Promise<void>; | ||
export declare function runSuite(suite: Suite, ctx: RunnerContext): Promise<void>; | ||
export declare function runFile(file: File, ctx: RunnerContext): Promise<void>; | ||
@@ -6,0 +6,0 @@ export declare function runFiles(filesMap: Record<string, File>, ctx: RunnerContext): Promise<void>; |
@@ -68,5 +68,6 @@ import fg from 'fast-glob'; | ||
if (i.mode === 'skip') | ||
i.tasks.forEach(t => t.mode === 'run' && (t.state = 'skip')); | ||
i.tasks.forEach(t => t.mode === 'run' && (t.mode = 'skip')); | ||
else | ||
interpretOnlyMode(i.tasks); | ||
i.tasks.forEach(t => t.mode === 'skip' && (t.state = 'skip')); | ||
}); | ||
@@ -88,3 +89,3 @@ return files; | ||
} | ||
export async function runSite(suite, ctx) { | ||
export async function runSuite(suite, ctx) { | ||
var _a, _b; | ||
@@ -118,12 +119,12 @@ const { reporter } = ctx; | ||
const { reporter } = ctx; | ||
const runableSuites = file.suites.filter(i => i.mode === 'run'); | ||
if (runableSuites.length === 0) | ||
const runnableSuites = file.suites.filter(i => i.mode === 'run'); | ||
if (runnableSuites.length === 0) | ||
return; | ||
await ((_a = reporter.onFileBegin) === null || _a === void 0 ? void 0 : _a.call(reporter, file, ctx)); | ||
if (ctx.config.parallel) { | ||
await Promise.all(file.suites.map(suite => runSite(suite, ctx))); | ||
await Promise.all(file.suites.map(suite => runSuite(suite, ctx))); | ||
} | ||
else { | ||
for (const suite of file.suites) | ||
await runSite(suite, ctx); | ||
await runSuite(suite, ctx); | ||
} | ||
@@ -162,3 +163,3 @@ await ((_b = reporter.onFileEnd) === null || _b === void 0 ? void 0 : _b.call(reporter, file, ctx)); | ||
if (config.global) | ||
(await import('../global')).registerApiGlobally(); | ||
(await import('../integrations/global')).registerApiGlobally(); | ||
if (config.jsdom) | ||
@@ -210,7 +211,7 @@ (await import('../integrations/jsdom')).setupJSDOM(globalThis); | ||
const snapshot = getSnapshotManager(); | ||
const pathes = Array.from(changedTests); | ||
const paths = Array.from(changedTests); | ||
changedTests.clear(); | ||
await ((_b = (_a = ctx.reporter).onWatcherRerun) === null || _b === void 0 ? void 0 : _b.call(_a, pathes, id, ctx)); | ||
pathes.forEach(i => moduleCache.delete(i)); | ||
const files = await collectFiles(pathes); | ||
await ((_b = (_a = ctx.reporter).onWatcherRerun) === null || _b === void 0 ? void 0 : _b.call(_a, paths, id, ctx)); | ||
paths.forEach(i => moduleCache.delete(i)); | ||
const files = await collectFiles(paths); | ||
Object.assign(ctx.filesMap, files); | ||
@@ -217,0 +218,0 @@ await runFiles(files, ctx); |
@@ -35,3 +35,3 @@ import { context } from './context'; | ||
suite: {}, | ||
state: mode !== 'run' ? mode : undefined, | ||
state: (mode !== 'run' && mode !== 'only') ? mode : undefined, | ||
fn, | ||
@@ -41,3 +41,3 @@ }); | ||
function test(name, fn) { | ||
collectTask(name, fn, mode); | ||
collectTask(name, fn, 'run'); | ||
} | ||
@@ -44,0 +44,0 @@ test.skip = (name, fn) => collectTask(name, fn, 'skip'); |
export declare type Awaitable<T> = Promise<T> | T; | ||
export interface UserOptions { | ||
/** | ||
* Include globs for test files | ||
* | ||
* @default ['**\/*.test.ts'] | ||
*/ | ||
includes?: string[]; | ||
/** | ||
* Exclude globs for test files | ||
* @default ['**\/node_modules\/**'] | ||
*/ | ||
excludes?: string[]; | ||
@@ -5,0 +14,0 @@ /** |
{ | ||
"name": "vitest", | ||
"version": "0.0.23", | ||
"version": "0.0.24", | ||
"description": "A blazing fast unit test framework powered by Vite", | ||
@@ -41,2 +41,12 @@ "keywords": [ | ||
], | ||
"scripts": { | ||
"prepare": "esmo scripts/generate-types.ts", | ||
"build": "rimraf dist && tsc -p src/tsconfig.json", | ||
"lint": "eslint \"{src,test}/**/*.ts\"", | ||
"prepublishOnly": "nr build", | ||
"release": "bumpp --commit --push --tag && esmo scripts/publish.ts", | ||
"test": "node bin/vitest.mjs --dev", | ||
"test:update": "nr test -u", | ||
"watch": "tsc -p src/tsconfig.json --watch" | ||
}, | ||
"dependencies": { | ||
@@ -59,3 +69,3 @@ "@jest/test-result": "^27.4.2", | ||
"devDependencies": { | ||
"@antfu/eslint-config": "^0.11.1", | ||
"@antfu/eslint-config": "^0.12.1", | ||
"@antfu/ni": "^0.11.0", | ||
@@ -68,3 +78,3 @@ "@types/jsdom": "^16.2.13", | ||
"bumpp": "^7.1.1", | ||
"eslint": "^8.3.0", | ||
"eslint": "^8.4.0", | ||
"esno": "^0.12.1", | ||
@@ -74,11 +84,3 @@ "rimraf": "^3.0.2", | ||
"vite": "^2.6.14" | ||
}, | ||
"scripts": { | ||
"build": "rimraf dist && tsc -p src/tsconfig.json", | ||
"lint": "eslint \"{src,test}/**/*.ts\"", | ||
"release": "bumpp --commit --push --tag && pnpm publish", | ||
"test": "node bin/vitest.mjs --dev", | ||
"test:update": "nr test -u", | ||
"watch": "tsc -p src/tsconfig.json --watch" | ||
} | ||
} | ||
} |
171
README.md
@@ -7,170 +7,3 @@ # vitest | ||
## Features | ||
- [Vite](https://vitejs.dev/)'s config, transformers, resolvers, and plugins. | ||
- [Jest Snapshot](https://jestjs.io/docs/snapshot-testing) | ||
- [Chai](https://www.chaijs.com/) for assertions | ||
- [Sinon](https://sinonjs.org/) for mocking | ||
- [JSDOM](https://github.com/jsdom/jsdom) for DOM mocking | ||
- Async suite / test, top level await | ||
- ESM friendly | ||
- Out-of-box TypeScript support | ||
- Suite and Test filtering (skip, only, todo) | ||
```ts | ||
import { it, describe, expect, assert } from 'vitest' | ||
describe('suite name', () => { | ||
it('foo', () => { | ||
expect(1 + 1).toEqual(2) | ||
expect(true).to.be.true | ||
}) | ||
it('bar', () => { | ||
assert.equal(Math.sqrt(4), 2) | ||
}) | ||
it('snapshot', () => { | ||
expect({ foo: 'bar' }).toMatchSnapshot() | ||
}) | ||
}) | ||
``` | ||
```bash | ||
$ npx vitest | ||
``` | ||
## Configuration | ||
`vitest` will read your root `vite.config.ts` when it present to match with the plugins and setup as your Vite app. If you want to it to have a different configuration for testing, you could either: | ||
- Create `vitest.config.ts`, which will have the higher priority | ||
- Pass `--config` option to CLI, e.g. `vitest --config ./path/to/vitest.config.ts` | ||
- Use `process.env.VITEST` to conditionally apply differnet configuration in `vite.config.ts` | ||
To configure `vitest` itself, add `test` property in your Vite config | ||
```ts | ||
// vite.config.ts | ||
import { defineConfig } from 'vite' | ||
export default defineConfig({ | ||
test: { | ||
// ... | ||
} | ||
}) | ||
``` | ||
## Global APIs | ||
By default, `vitest` does not provide global APIs for explicitness. If you prefer to use the APIs globally like Jest, you can pass the `--global` option to CLI or add `global: true` in the config. | ||
```ts | ||
// vite.config.ts | ||
import { defineConfig } from 'vite' | ||
export default defineConfig({ | ||
test: { | ||
global: true | ||
} | ||
}) | ||
``` | ||
To get TypeScript working with the global APIs, add `vitest/global` to the `types` filed in your `tsconfig.json` | ||
```json | ||
// tsconfig.json | ||
{ | ||
"compilerOptions": { | ||
"types": [ | ||
"vitest/global" | ||
] | ||
} | ||
} | ||
``` | ||
## Filtering | ||
### Skipping suites and tasks | ||
Use `.skip` to avoid running certain suites or tests | ||
```ts | ||
describe.skip('skipped suite', () => { | ||
it('task', () => { | ||
// Suite skipped, no error | ||
assert.equal(Math.sqrt(4), 3) | ||
}) | ||
}) | ||
describe('suite', () => { | ||
it.skip('skipped task', () => { | ||
// Task skipped, no error | ||
assert.equal(Math.sqrt(4), 3) | ||
}) | ||
}) | ||
``` | ||
### Selecting suites and tests to run | ||
Use `.only` to only run certain suites or tests | ||
```ts | ||
// Only this suite (and others marked with only) are run | ||
describe.only('suite', () => { | ||
it('task', () => { | ||
assert.equal(Math.sqrt(4), 3) | ||
}) | ||
}) | ||
describe('another suite', () => { | ||
it('skipped task', () => { | ||
// Task skipped, as tests are running in Only mode | ||
assert.equal(Math.sqrt(4), 3) | ||
}) | ||
it.only('task', () => { | ||
// Only this task (and others marked with only) are run | ||
assert.equal(Math.sqrt(4), 2) | ||
}) | ||
}) | ||
``` | ||
### Unimplemented suites and tests | ||
Use `.todo` to stub suites and tests that should be implemented | ||
```ts | ||
// An entry will be shown in the report for this suite | ||
describe.todo('unimplemented suite') | ||
// An entry will be shown in the report for this task | ||
describe('suite', () => { | ||
it.todo('unimplemented task') | ||
}) | ||
``` | ||
## TODO | ||
- [x] Reporter & Better output | ||
- [x] Task filter | ||
- [x] Mock | ||
- [x] Global Mode & Types | ||
- [ ] Concurrent Executing | ||
- [x] CLI Help | ||
- [x] JSDom | ||
- [x] Watch | ||
- [ ] Source Map | ||
- [ ] Coverage | ||
## Sponsors | ||
<p align="center"> | ||
<a href="https://cdn.jsdelivr.net/gh/antfu/static/sponsors.svg"> | ||
<img src='https://cdn.jsdelivr.net/gh/antfu/static/sponsors.svg'/> | ||
</a> | ||
</p> | ||
## License | ||
[MIT](./LICENSE) License © 2021 [Anthony Fu](https://github.com/antfu) | ||
> **This project is currently in closed beta exclusively for Sponsors.** | ||
> Become a Sponsor of [@patak-js](https://github.com/sponsors/patak-js) or [@antfu](https://github.com/sponsors/antfu) to access the source code and issues tracker. |
Sorry, the diff of this file is not supported yet
65896
9