vitest 0.0.71 → 0.0.75

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.gh.md CHANGED
@@ -11,6 +11,14 @@ A blazing fast unit test framework powered by Vite.
11
11
  <p align="center">
12
12
  <a href="https://www.npmjs.com/package/vitest"><img src="https://img.shields.io/npm/v/vitest?color=a1b858&label="></a>
13
13
  <p>
14
+ <h2 align="center">
15
+ <a href="https://preview.vitest.dev">Open the Docs</a>
16
+ </h2>
17
+ <h3 align="center">
18
+ <a href=https://discord.com/invite/2zYZNngd7y"><i>Get involved!</i></a>
19
+ </h3>
20
+ <br>
21
+ <br>
14
22
 
15
23
  > 💖 **This project is currently in closed beta exclusively for Sponsors.**<br>
16
24
  > Become a Sponsor of [@patak-dev](https://github.com/sponsors/patak-dev) or [@antfu](https://github.com/sponsors/antfu) to access the source code and issues tracker.
@@ -19,7 +27,8 @@ A blazing fast unit test framework powered by Vite.
19
27
 
20
28
  > Vitest requires Vite v2.7 and Node v16
21
29
 
22
- [**Join the Discord!**](https://discord.com/invite/2zYZNngd7y)
30
+
31
+ Switch to Vitest by following the [Getting Started Guide](https://preview.vitest.dev/guide) or learn [why we are building a new test runner](https://preview.vitest.dev/guide).
23
32
 
24
33
  ## Features
25
34
 
@@ -74,281 +83,6 @@ $ npx vitest
74
83
  - [unplugin-vue-components](https://github.com/antfu/unplugin-vue-components)
75
84
  - [vitesse-lite](https://github.com/antfu/vitesse-lite)
76
85
 
77
- ## Configuration
78
-
79
- `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:
80
-
81
- - Create `vitest.config.ts`, which will have the higher priority
82
- - Pass `--config` option to CLI, e.g. `vitest --config ./path/to/vitest.config.ts`
83
- - Use `process.env.VITEST` to conditionally apply different configuration in `vite.config.ts`
84
-
85
- To configure `vitest` itself, add `test` property in your Vite config
86
-
87
- ```ts
88
- // vite.config.ts
89
- import { defineConfig } from 'vite'
90
-
91
- export default defineConfig({
92
- test: {
93
- // ...
94
- }
95
- })
96
- ```
97
-
98
- ## Global APIs
99
-
100
- 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.
101
-
102
- ```ts
103
- // vite.config.ts
104
- import { defineConfig } from 'vite'
105
-
106
- export default defineConfig({
107
- test: {
108
- global: true
109
- }
110
- })
111
- ```
112
-
113
- To get TypeScript working with the global APIs, add `vitest/global` to the `types` filed in your `tsconfig.json`
114
-
115
- ```jsonc
116
- // tsconfig.json
117
- {
118
- "compilerOptions": {
119
- "types": [
120
- "vitest/global"
121
- ]
122
- }
123
- }
124
- ```
125
-
126
- If you are already using [`unplugin-auto-import`](https://github.com/antfu/unplugin-vue-components) in your project, you can also use it directly for auto importing those APIs.
127
-
128
- ```ts
129
- // vite.config.ts
130
- import { defineConfig } from 'vite'
131
- import AutoImport from 'unplugin-auto-import/vite'
132
-
133
- export default defineConfig({
134
- plugins: [
135
- AutoImport({
136
- imports: ['vitest'],
137
- dts: true // generate TypeScript declaration
138
- })
139
- ]
140
- })
141
- ```
142
-
143
- ## Browser Mocking
144
-
145
- Vitest supports both [happy-dom](https://github.com/capricorn86/happy-dom) or [jsdom](https://github.com/jsdom/jsdom) for mocking DOM and browser APIs. They don't come with Vitest, you might need to install them:
146
-
147
- ```bash
148
- $ npm i -D happy-dom
149
- # or
150
- $ npm i -D jsdom
151
- ```
152
-
153
- After that, change the `environment` option in your config file:
154
-
155
- ```ts
156
- // vite.config.ts
157
- import { defineConfig } from 'vite'
158
-
159
- export default defineConfig({
160
- test: {
161
- environment: 'happy-dom' // or 'jsdom', 'node'
162
- }
163
- })
164
- ```
165
-
166
- ## Watch Mode
167
-
168
- ```bash
169
- $ vitest -w
170
- ```
171
-
172
- Vitest smartly searches the module graph and only rerun the related tests (just like how HMR works in Vite!).
173
-
174
- ## Coverage
175
-
176
- Vitest works perfectly with [c8](https://github.com/bcoe/c8)
177
-
178
- ```bash
179
- $ npm i -D c8
180
- $ c8 vitest
181
- ```
182
-
183
- ```json
184
- {
185
- "scripts": {
186
- "test": "vitest",
187
- "coverage": "c8 vitest"
188
- }
189
- }
190
- ```
191
-
192
- For convenience, we also provide a shorthand for passing `--coverage` option to CLI, which will wrap the process with `c8` for you. Note when using the shorthand, you will lose the ability to pass additional options to `c8`.
193
-
194
- ```bash
195
- $ vitest --coverage
196
- ```
197
-
198
- For more configuration available, please refer to [c8](https://github.com/bcoe/c8)'s documentation.
199
-
200
- ## Filtering
201
-
202
- ### CLI
203
-
204
- You can use CLI to filter test files my name:
205
-
206
- ```bash
207
- $ vitest basic
208
- ```
209
-
210
- Will only execute test files that contain `basic`, e.g.
211
-
212
- ```
213
- basic.test.ts
214
- basic-foo.test.ts
215
- ```
216
-
217
- ### Specifying a Timeout
218
-
219
- You can optionally pass a timeout in milliseconds as third argument to tests. The default is 5 seconds.
220
-
221
- ```ts
222
- test('name', async() => { ... }, 1000)
223
- ```
224
-
225
- Hooks also can receive a timeout, with the same 5 seconds default.
226
-
227
- ```ts
228
- beforeAll( async() => { ... }, 1000)
229
- ```
230
-
231
- ### Skipping suites and tests
232
-
233
- Use `.skip` to avoid running certain suites or tests
234
-
235
- ```ts
236
- describe.skip('skipped suite', () => {
237
- it('test', () => {
238
- // Suite skipped, no error
239
- assert.equal(Math.sqrt(4), 3)
240
- })
241
- })
242
-
243
- describe('suite', () => {
244
- it.skip('skipped test', () => {
245
- // Test skipped, no error
246
- assert.equal(Math.sqrt(4), 3)
247
- })
248
- })
249
- ```
250
-
251
- ### Selecting suites and tests to run
252
-
253
- Use `.only` to only run certain suites or tests
254
-
255
- ```ts
256
- // Only this suite (and others marked with only) are run
257
- describe.only('suite', () => {
258
- it('test', () => {
259
- assert.equal(Math.sqrt(4), 3)
260
- })
261
- })
262
-
263
- describe('another suite', () => {
264
- it('skipped test', () => {
265
- // Test skipped, as tests are running in Only mode
266
- assert.equal(Math.sqrt(4), 3)
267
- })
268
-
269
- it.only('test', () => {
270
- // Only this test (and others marked with only) are run
271
- assert.equal(Math.sqrt(4), 2)
272
- })
273
- })
274
- ```
275
-
276
- ### Unimplemented suites and tests
277
-
278
- Use `.todo` to stub suites and tests that should be implemented
279
-
280
- ```ts
281
- // An entry will be shown in the report for this suite
282
- describe.todo('unimplemented suite')
283
-
284
- // An entry will be shown in the report for this test
285
- describe('suite', () => {
286
- it.todo('unimplemented test')
287
- })
288
- ```
289
-
290
- ### Running tests concurrently
291
-
292
- Use `.concurrent` in consecutive tests to run them in parallel
293
-
294
- ```ts
295
- // The two tests marked with concurrent will be run in parallel
296
- describe('suite', () => {
297
- it('serial test', () => {
298
- assert.equal(Math.sqrt(4), 3)
299
- })
300
- it.concurrent('concurrent test 1', () => {
301
- assert.equal(Math.sqrt(4), 3)
302
- })
303
- it.concurrent('concurrent test 2', () => {
304
- assert.equal(Math.sqrt(4), 3)
305
- })
306
- })
307
- ```
308
-
309
- If you use `.concurrent` in a suite, every tests in it will be run in parallel
310
- ```ts
311
- // The two tests marked with concurrent will be run in parallel
312
- describe.concurrent('suite', () => {
313
- it('concurrent test 1', () => {
314
- assert.equal(Math.sqrt(4), 3)
315
- })
316
- it('concurrent test 2', () => {
317
- assert.equal(Math.sqrt(4), 3)
318
- })
319
- // No effect, same as not using .concurrent
320
- it.concurrent('concurrent test 3', () => {
321
- assert.equal(Math.sqrt(4), 3)
322
- })
323
- })
324
- ```
325
-
326
- You can also use `.skip`, `.only`, and `.todo` with concurrent suite and tests. All the following combinations are valid:
327
- ```js
328
- describe.concurrent(...)
329
-
330
- describe.skip.concurrent(...)
331
- describe.concurrent.skip(...)
332
-
333
- describe.only.concurrent(...)
334
- describe.concurrent.only(...)
335
-
336
- describe.todo.concurrent(...)
337
- describe.concurrent.todo(...)
338
-
339
- it.concurrent(...)
340
-
341
- it.skip.concurrent(...)
342
- it.concurrent.skip(...)
343
-
344
- it.only.concurrent(...)
345
- it.concurrent.only(...)
346
-
347
- it.todo.concurrent(...)
348
- it.concurrent.todo(...)
349
- ```
350
-
351
-
352
86
  ## Sponsors
353
87
 
354
88
  <p align="center">
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import require$$2, { EventEmitter } from 'events';
2
- import { s as stringWidth, a as ansiStyles, b as stripAnsi, c as sliceAnsi, d as c, F as F_POINTER, e as F_DOWN, f as F_DOWN_RIGHT, g as F_DOT, h as F_CHECK, i as F_CROSS, j as cliTruncate, k as F_RIGHT, p as printError } from './error-fb6ff2e6.js';
2
+ import { s as stringWidth, a as ansiStyles, b as stripAnsi, c as sliceAnsi, d as c, F as F_POINTER, e as F_DOWN, f as F_LONG_DASH, g as F_DOWN_RIGHT, h as F_DOT, i as F_CHECK, j as F_CROSS, k as cliTruncate, l as F_RIGHT, p as printError } from './error-eb493046.js';
3
3
  import { performance } from 'perf_hooks';
4
4
  import path, { isAbsolute, relative, dirname, basename, resolve } from 'path';
5
5
  import { g as getNames, s as slash, a as getTests, b as getSuites, t as toArray, h as hasFailed } from './utils-9dcc4050.js';
@@ -632,7 +632,7 @@ const cac = (name = "") => new CAC(name);
632
632
 
633
633
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
634
634
 
635
- var version = "0.0.71";
635
+ var version = "0.0.75";
636
636
 
637
637
  const ESC = '\u001B[';
638
638
  const OSC = '\u001B]';
@@ -1451,6 +1451,24 @@ const spinnerMap = new WeakMap();
1451
1451
  const outputMap = new WeakMap();
1452
1452
  const pointer = c.yellow(F_POINTER);
1453
1453
  const skipped = c.yellow(F_DOWN);
1454
+ function divider(text, left, right) {
1455
+ let length = process.stdout.columns;
1456
+ if (!length || isNaN(length))
1457
+ length = 10;
1458
+ if (text) {
1459
+ const textLength = stripAnsi(text).length;
1460
+ if (left == null && right != null) {
1461
+ left = length - textLength - right;
1462
+ } else {
1463
+ left = left ?? Math.floor((length - textLength) / 2);
1464
+ right = length - textLength - left;
1465
+ }
1466
+ left = Math.max(0, left);
1467
+ right = Math.max(0, right);
1468
+ return `${F_LONG_DASH.repeat(left)}${text}${F_LONG_DASH.repeat(right)}`;
1469
+ }
1470
+ return F_LONG_DASH.repeat(length);
1471
+ }
1454
1472
  function formatTestPath(root, path) {
1455
1473
  var _a;
1456
1474
  if (isAbsolute(path))
@@ -1573,7 +1591,8 @@ function renderTree(tasks, level = 0) {
1573
1591
  const createRenderer = (_tasks) => {
1574
1592
  let tasks = _tasks;
1575
1593
  let timer;
1576
- const log = createLogUpdate(process.stdout);
1594
+ const stdout = process.stdout;
1595
+ const log = createLogUpdate(stdout);
1577
1596
  function update() {
1578
1597
  log(renderTree(tasks));
1579
1598
  }
@@ -1595,13 +1614,17 @@ const createRenderer = (_tasks) => {
1595
1614
  timer = void 0;
1596
1615
  }
1597
1616
  log.clear();
1598
- console.log(renderTree(tasks));
1617
+ stdout.write(`${renderTree(tasks)}
1618
+ `);
1599
1619
  return this;
1620
+ },
1621
+ clear() {
1622
+ log.clear();
1600
1623
  }
1601
1624
  };
1602
1625
  };
1603
1626
  function getFullName(task) {
1604
- return getNames(task).join(c.gray(" > "));
1627
+ return getNames(task).join(c.dim(" > "));
1605
1628
  }
1606
1629
  const spinnerFrames = process.platform === "win32" ? ["-", "\\", "|", "/"] : ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
1607
1630
  function elegantSpinner() {
@@ -1618,11 +1641,23 @@ class DefaultReporter {
1618
1641
  this.ctx = ctx;
1619
1642
  this.start = 0;
1620
1643
  this.end = 0;
1644
+ this.console = globalThis.console;
1645
+ this.isFirstWatchRun = true;
1621
1646
  const mode = ctx.config.watch ? c.yellow(" DEV ") : c.cyan(" RUN ");
1622
- console.log(`${c.inverse(c.bold(mode))} ${c.gray(this.ctx.config.root)}
1647
+ this.log(`${c.inverse(c.bold(mode))} ${c.gray(this.ctx.config.root)}
1623
1648
  `);
1624
1649
  this.start = performance.now();
1625
1650
  }
1651
+ log(...args) {
1652
+ if (this.ctx.config.silent)
1653
+ return;
1654
+ this.console.log(...args);
1655
+ }
1656
+ error(...args) {
1657
+ if (this.ctx.config.silent)
1658
+ return;
1659
+ this.console.error(...args);
1660
+ }
1626
1661
  relative(path) {
1627
1662
  return relative(this.ctx.config.root, path);
1628
1663
  }
@@ -1641,16 +1676,16 @@ class DefaultReporter {
1641
1676
  return;
1642
1677
  const task = this.ctx.state.idMap[pack[0]];
1643
1678
  if (task.type === "test" && ((_a = task.result) == null ? void 0 : _a.state) && ((_b = task.result) == null ? void 0 : _b.state) !== "run") {
1644
- console.log(` ${getStateSymbol(task)} ${getFullName(task)}`);
1679
+ this.log(` ${getStateSymbol(task)} ${getFullName(task)}`);
1645
1680
  if (task.result.state === "fail")
1646
- console.log(c.red(` ${F_RIGHT} ${(_c = task.result.error) == null ? void 0 : _c.message}`));
1681
+ this.log(c.red(` ${F_RIGHT} ${(_c = task.result.error) == null ? void 0 : _c.message}`));
1647
1682
  }
1648
1683
  }
1649
1684
  async onFinished(files = this.ctx.state.getFiles()) {
1650
1685
  var _a, _b;
1651
1686
  this.end = performance.now();
1652
1687
  await this.stopListRender();
1653
- console.log();
1688
+ this.log();
1654
1689
  const suites = getSuites(files);
1655
1690
  const tests = getTests(files);
1656
1691
  const failedSuites = suites.filter((i) => {
@@ -1661,24 +1696,27 @@ class DefaultReporter {
1661
1696
  var _a2;
1662
1697
  return ((_a2 = i.result) == null ? void 0 : _a2.state) === "fail";
1663
1698
  });
1699
+ const failedTotal = failedSuites.length + failedTests.length;
1700
+ let current = 1;
1701
+ const errorDivider = () => this.error(`${c.red(c.dim(divider(`[${current++}/${failedTotal}]`, void 0, 1)))}
1702
+ `);
1664
1703
  if (failedSuites.length) {
1665
- console.error(c.bold(c.red(`
1666
- Failed to run ${failedSuites.length} suites:`)));
1704
+ this.error(c.red(divider(c.bold(c.inverse(` Failed Suites ${failedSuites.length} `)))));
1705
+ this.error();
1667
1706
  for (const suite of failedSuites) {
1668
- console.error(c.red(`
1707
+ this.error(c.red(`
1669
1708
  - ${getFullName(suite)}`));
1670
1709
  await printError((_a = suite.result) == null ? void 0 : _a.error);
1671
- console.log();
1710
+ errorDivider();
1672
1711
  }
1673
1712
  }
1674
1713
  if (failedTests.length) {
1675
- console.error(c.bold(c.red(`
1676
- Failed Tests (${failedTests.length})`)));
1714
+ this.error(c.red(divider(c.bold(c.inverse(` Failed Tests ${failedTests.length} `)))));
1715
+ this.error();
1677
1716
  for (const test of failedTests) {
1678
- console.error(`${c.red(`
1679
- ${c.inverse(" FAIL ")}`)} ${getFullName(test)}`);
1717
+ this.error(`${c.red(c.bold(c.inverse(" FAIL ")))} ${getFullName(test)}`);
1680
1718
  await printError((_b = test.result) == null ? void 0 : _b.error);
1681
- console.log();
1719
+ errorDivider();
1682
1720
  }
1683
1721
  }
1684
1722
  const executionTime = this.end - this.start;
@@ -1694,17 +1732,17 @@ ${c.inverse(" FAIL ")}`)} ${getFullName(test)}`);
1694
1732
  };
1695
1733
  const snapshotOutput = renderSnapshotSummary(this.ctx.config.root, this.ctx.snapshot.summary);
1696
1734
  if (snapshotOutput.length) {
1697
- console.log(snapshotOutput.map((t, i) => i === 0 ? `${padTitle("Snapshots")} ${t}` : `${padTitle("")} ${t}`).join("\n"));
1735
+ this.log(snapshotOutput.map((t, i) => i === 0 ? `${padTitle("Snapshots")} ${t}` : `${padTitle("")} ${t}`).join("\n"));
1698
1736
  if (snapshotOutput.length > 1)
1699
- console.log();
1737
+ this.log();
1700
1738
  }
1701
- console.log(padTitle("Test Files"), getStateString(files));
1702
- console.log(padTitle("Tests"), getStateString(tests));
1739
+ this.log(padTitle("Test Files"), getStateString(files));
1740
+ this.log(padTitle("Tests"), getStateString(tests));
1703
1741
  if (this.watchFilters)
1704
- console.log(padTitle("Time"), time(threadTime));
1742
+ this.log(padTitle("Time"), time(threadTime));
1705
1743
  else
1706
- console.log(padTitle("Time"), time(executionTime) + c.gray(` (in thread ${time(threadTime)}, ${(executionTime / threadTime * 100).toFixed(2)}%)`));
1707
- console.log();
1744
+ this.log(padTitle("Time"), time(executionTime) + c.gray(` (in thread ${time(threadTime)}, ${(executionTime / threadTime * 100).toFixed(2)}%)`));
1745
+ this.log();
1708
1746
  }
1709
1747
  async onWatcherStart() {
1710
1748
  await this.stopListRender();
@@ -1713,24 +1751,36 @@ ${c.inverse(" FAIL ")}`)} ${getFullName(test)}`);
1713
1751
  return ((_a = i.result) == null ? void 0 : _a.state) === "fail";
1714
1752
  });
1715
1753
  if (failed.length)
1716
- console.log(`
1754
+ this.log(`
1717
1755
  ${c.bold(c.inverse(c.red(" FAIL ")))}${c.red(` ${failed.length} tests failed. Watching for file changes...`)}`);
1718
1756
  else
1719
- console.log(`
1757
+ this.log(`
1720
1758
  ${c.bold(c.inverse(c.green(" PASS ")))}${c.green(" Waiting for file changes...")}`);
1759
+ if (this.isFirstWatchRun) {
1760
+ this.isFirstWatchRun = false;
1761
+ this.log(c.gray("press any key to exit..."));
1762
+ }
1721
1763
  }
1722
1764
  async onWatcherRerun(files, trigger) {
1723
1765
  await this.stopListRender();
1724
1766
  this.watchFilters = files;
1725
- console.clear();
1726
- console.log(c.blue("Re-running tests...") + c.dim(` [ ${this.relative(trigger)} ]
1767
+ this.console.clear();
1768
+ this.log(c.blue("Re-running tests...") + c.dim(` [ ${this.relative(trigger)} ]
1727
1769
  `));
1728
1770
  }
1729
1771
  async stopListRender() {
1730
1772
  var _a;
1731
1773
  (_a = this.renderer) == null ? void 0 : _a.stop();
1732
1774
  this.renderer = void 0;
1733
- await new Promise((resolve) => setTimeout(resolve, 100));
1775
+ await new Promise((resolve) => setTimeout(resolve, 10));
1776
+ }
1777
+ onUserConsoleLog(log) {
1778
+ var _a;
1779
+ (_a = this.renderer) == null ? void 0 : _a.clear();
1780
+ const task = log.taskId ? this.ctx.state.idMap[log.taskId] : void 0;
1781
+ this.log(c.gray(log.type + c.dim(` | ${task ? getFullName(task) : "unknown test"}`)));
1782
+ process[log.type].write(`${log.content}
1783
+ `);
1734
1784
  }
1735
1785
  }
1736
1786
 
@@ -2172,7 +2222,8 @@ function createFakePool(ctx) {
2172
2222
  }
2173
2223
  function createWorkerPool(ctx) {
2174
2224
  const options = {
2175
- filename: workerPath
2225
+ filename: workerPath,
2226
+ useAtomics: false
2176
2227
  };
2177
2228
  if (ctx.config.maxThreads != null)
2178
2229
  options.maxThreads = ctx.config.maxThreads;
@@ -2203,7 +2254,7 @@ function createChannel(ctx) {
2203
2254
  const port = channel.port2;
2204
2255
  const workerPort = channel.port1;
2205
2256
  port.on("message", async ({ id, method, args = [] }) => {
2206
- var _a, _b, _c, _d;
2257
+ var _a, _b, _c, _d, _e, _f;
2207
2258
  async function send(fn) {
2208
2259
  try {
2209
2260
  port.postMessage({ id, result: await fn() });
@@ -2224,6 +2275,9 @@ function createChannel(ctx) {
2224
2275
  ctx.state.updateTasks([args[0]]);
2225
2276
  (_d = (_c = ctx.reporter).onTaskUpdate) == null ? void 0 : _d.call(_c, args[0]);
2226
2277
  return;
2278
+ case "log":
2279
+ (_f = (_e = ctx.reporter).onUserConsoleLog) == null ? void 0 : _f.call(_e, args[0]);
2280
+ return;
2227
2281
  }
2228
2282
  console.error("Unhandled message", method, args);
2229
2283
  });
@@ -2255,6 +2309,7 @@ async function startWatcher(ctx, pool) {
2255
2309
  let timer;
2256
2310
  const changedTests = new Set();
2257
2311
  const seen = new Set();
2312
+ let isFirstRun = true;
2258
2313
  let promise;
2259
2314
  server.watcher.on("change", (id) => {
2260
2315
  id = slash(id);
@@ -2286,6 +2341,7 @@ async function startWatcher(ctx, pool) {
2286
2341
  seen.clear();
2287
2342
  return;
2288
2343
  }
2344
+ isFirstRun = false;
2289
2345
  ctx.state.getFiles().forEach((file) => {
2290
2346
  var _a2;
2291
2347
  if (((_a2 = file.result) == null ? void 0 : _a2.state) === "fail")
@@ -2295,7 +2351,9 @@ async function startWatcher(ctx, pool) {
2295
2351
  const tests = Array.from(changedTests);
2296
2352
  changedTests.clear();
2297
2353
  seen.clear();
2298
- promise = start(tests, id, invalidates);
2354
+ promise = start(tests, id, invalidates).then(() => {
2355
+ promise = void 0;
2356
+ });
2299
2357
  await promise;
2300
2358
  }, WATCHER_DEBOUNCE);
2301
2359
  }
@@ -2306,8 +2364,18 @@ async function startWatcher(ctx, pool) {
2306
2364
  await ((_b = reporter.onFinished) == null ? void 0 : _b.call(reporter, ctx.state.getFiles(tests)));
2307
2365
  await ((_c = reporter.onWatcherStart) == null ? void 0 : _c.call(reporter));
2308
2366
  }
2309
- if (process.stdin.isTTY)
2310
- listenToKeybard();
2367
+ if (process.stdin.isTTY) {
2368
+ readline.emitKeypressEvents(process.stdin);
2369
+ process.stdin.setRawMode(true);
2370
+ process.stdin.on("keypress", (str) => {
2371
+ if (str === "" || str === "")
2372
+ process.exit();
2373
+ if (promise)
2374
+ return;
2375
+ if (isFirstRun)
2376
+ process.exit();
2377
+ });
2378
+ }
2311
2379
  await new Promise(() => {
2312
2380
  });
2313
2381
  }
@@ -2328,16 +2396,6 @@ function getAffectedTests(ctx, id, set = new Set(), seen = new Set()) {
2328
2396
  }
2329
2397
  return set;
2330
2398
  }
2331
- function listenToKeybard() {
2332
- readline.emitKeypressEvents(process.stdin);
2333
- process.stdin.setRawMode(true);
2334
- process.stdin.on("keypress", (str, key) => {
2335
- if (str === "" || str === "")
2336
- process.exit();
2337
- if (str === "\r")
2338
- process.exit();
2339
- });
2340
- }
2341
2399
 
2342
2400
  async function start(ctx) {
2343
2401
  var _a, _b;
@@ -2414,7 +2472,7 @@ var __spreadValues = (a, b) => {
2414
2472
  };
2415
2473
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
2416
2474
  const cli = cac("vitest");
2417
- cli.version(version).option("-r, --root <path>", "root path").option("-c, --config <path>", "path to config file").option("-u, --update", "update snapshot").option("--global", "inject apis globally").option("--dom", "mock browser api with happy-dom").option("--environment <env>", "runner environment", {
2475
+ cli.version(version).option("-r, --root <path>", "root path").option("-c, --config <path>", "path to config file").option("-u, --update", "update snapshot").option("-w, --watch", "watch mode").option("--threads", "enabled threads", { default: true }).option("--silent", "silent").option("--global", "inject apis globally").option("--dom", "mock browser api with happy-dom").option("--environment <env>", "runner environment", {
2418
2476
  default: "node"
2419
2477
  }).help();
2420
2478
  cli.command("run [...filters]").action(run);
@@ -2423,20 +2481,25 @@ cli.command("dev [...filters]").action(dev);
2423
2481
  cli.command("[...filters]").action(dev);
2424
2482
  cli.parse();
2425
2483
  async function dev(cliFilters, argv) {
2426
- argv.watch = !process.env.CI;
2484
+ if (argv.watch == null)
2485
+ argv.watch = !process.env.CI && !process.env.NODE_V8_COVERAGE;
2427
2486
  await run(cliFilters, argv);
2428
2487
  }
2429
2488
  async function run(cliFilters, argv) {
2430
2489
  process.env.VITEST = "true";
2431
- console.log(c.magenta(c.bold("\nVitest is in closed beta exclusively for Sponsors")));
2432
- console.log(c.yellow("Learn more at https://vitest.dev\n"));
2490
+ process.env.NODE_ENV = "test";
2491
+ if (!argv.silent) {
2492
+ console.log(c.magenta(c.bold("\nVitest is in closed beta exclusively for Sponsors")));
2493
+ console.log(c.yellow("Learn more at https://vitest.dev\n"));
2494
+ }
2433
2495
  const { config, server } = await initViteServer(__spreadProps(__spreadValues({}, argv), { cliFilters }));
2434
2496
  const ctx = process.__vitest__ = {
2435
2497
  server,
2436
2498
  config,
2437
2499
  state: new StateManager(),
2438
2500
  snapshot: new SnapshotManager(config),
2439
- reporter: config.reporter
2501
+ reporter: config.reporter,
2502
+ console: globalThis.console
2440
2503
  };
2441
2504
  ctx.reporter = ctx.reporter || new DefaultReporter(ctx);
2442
2505
  try {
package/dist/entry.js CHANGED
@@ -1,3 +1,5 @@
1
+ import { Console } from 'console';
2
+ import { Writable } from 'stream';
1
3
  import { importModule } from 'local-pkg';
2
4
  import chai, { expect, util } from 'chai';
3
5
  import SinonChai from 'sinon-chai';
@@ -5,7 +7,7 @@ import Subset from 'chai-subset';
5
7
  import path, { basename } from 'path';
6
8
  import { g as getNames, i as interpretOnlyMode, p as partitionSuiteChildren, c as hasTests, h as hasFailed } from './utils-9dcc4050.js';
7
9
  import fs from 'fs';
8
- import { d as c$1, l as generateDiff } from './error-fb6ff2e6.js';
10
+ import { d as c$1, m as generateDiff } from './error-eb493046.js';
9
11
  import { performance } from 'perf_hooks';
10
12
  import { j as setHooks, c as createSuiteHooks, h as clearContext, d as defaultSuite, k as context, l as getHooks, m as getFn } from './suite-819c135e.js';
11
13
  import { n as nanoid } from './index-6427e0f2.js';
@@ -2829,7 +2831,7 @@ class SnapshotState {
2829
2831
  this._uncheckedKeys.delete(key);
2830
2832
  const receivedSerialized = addExtraLineBreaks(serialize(received, void 0, this._snapshotFormat));
2831
2833
  const expected = isInline ? inlineSnapshot : this._snapshotData[key];
2832
- const pass = expected === receivedSerialized;
2834
+ const pass = (expected == null ? void 0 : expected.trim()) === (receivedSerialized == null ? void 0 : receivedSerialized.trim());
2833
2835
  const hasSnapshot = expected !== void 0;
2834
2836
  const snapshotIsPersisted = isInline || fs.existsSync(this._snapshotPath);
2835
2837
  if (pass && !isInline) {
@@ -2907,13 +2909,15 @@ class SnapshotClient {
2907
2909
  clearTest() {
2908
2910
  this.test = void 0;
2909
2911
  }
2910
- assert(received, message) {
2912
+ assert(received, message, inlineSnapshot) {
2911
2913
  if (!this.test)
2912
- throw new Error("Snapshot can't not be used outside of test");
2914
+ throw new Error("Snapshot cannot be used outside of test");
2915
+ const testName = getNames(this.test).slice(1).join(" > ");
2913
2916
  const { actual, expected, key, pass } = this.snapshotState.match({
2914
- testName: getNames(this.test).slice(1).join(" > "),
2917
+ testName,
2915
2918
  received,
2916
- isInline: false
2919
+ isInline: !!inlineSnapshot,
2920
+ inlineSnapshot: inlineSnapshot == null ? void 0 : inlineSnapshot.trim()
2917
2921
  });
2918
2922
  if (!pass) {
2919
2923
  expect(actual.trim()).equals(expected ? expected.trim() : "", message || `Snapshot name: \`${key}\``);
@@ -2968,6 +2972,10 @@ function SnapshotPlugin() {
2968
2972
  getSnapshotClient().assert(expected, message);
2969
2973
  });
2970
2974
  }
2975
+ utils.addMethod(chai.Assertion.prototype, "toMatchInlineSnapshot", function(inlineSnapshot, message) {
2976
+ const expected = utils.flag(this, "object");
2977
+ getSnapshotClient().assert(expected, message, inlineSnapshot);
2978
+ });
2971
2979
  };
2972
2980
  }
2973
2981
 
@@ -3473,6 +3481,9 @@ function JestChaiExpect() {
3473
3481
  def("toHaveLength", function(length) {
3474
3482
  return this.have.length(length);
3475
3483
  });
3484
+ def("toHaveProperty", function(...args) {
3485
+ return this.have.deep.nested.property(...args);
3486
+ });
3476
3487
  def("toBeCloseTo", function(number, numDigits = 2) {
3477
3488
  utils.expectTypes(this, ["number"]);
3478
3489
  return this.closeTo(number, numDigits);
@@ -3581,11 +3592,47 @@ async function setupChai() {
3581
3592
  installed = true;
3582
3593
  }
3583
3594
 
3595
+ let globalSetup = false;
3584
3596
  async function setupGlobalEnv(config) {
3597
+ if (globalSetup)
3598
+ return;
3599
+ globalSetup = true;
3600
+ setupConsoleLogSpy();
3585
3601
  await setupChai();
3586
3602
  if (config.global)
3587
3603
  (await import('./global-e40b54d6.js')).registerApiGlobally();
3588
3604
  }
3605
+ function setupConsoleLogSpy() {
3606
+ const stdout = new Writable({
3607
+ write(data, encoding, callback) {
3608
+ var _a;
3609
+ send("log", {
3610
+ type: "stdout",
3611
+ content: String(data),
3612
+ taskId: (_a = process.__vitest_worker__.current) == null ? void 0 : _a.id
3613
+ });
3614
+ callback();
3615
+ }
3616
+ });
3617
+ const stderr = new Writable({
3618
+ write(data, encoding, callback) {
3619
+ var _a;
3620
+ send("log", {
3621
+ type: "stderr",
3622
+ content: String(data),
3623
+ taskId: (_a = process.__vitest_worker__.current) == null ? void 0 : _a.id
3624
+ });
3625
+ callback();
3626
+ }
3627
+ });
3628
+ const newConsole = new Console({
3629
+ stdout,
3630
+ stderr,
3631
+ colorMode: true,
3632
+ groupIndentation: 2
3633
+ });
3634
+ globalThis.console = newConsole;
3635
+ }
3589
3636
  async function withEnv(name, fn) {
3590
3637
  const env = await environments[name].setup(globalThis);
3591
3638
  try {
@@ -3668,6 +3715,7 @@ async function runTest(test) {
3668
3715
  };
3669
3716
  updateTask(test);
3670
3717
  getSnapshotClient().setTest(test);
3718
+ process.__vitest_worker__.current = test;
3671
3719
  try {
3672
3720
  await callHook(test.suite, "beforeEach", [test, test.suite]);
3673
3721
  await getFn(test)();
@@ -3684,6 +3732,7 @@ async function runTest(test) {
3684
3732
  }
3685
3733
  getSnapshotClient().clearTest();
3686
3734
  test.result.end = performance.now();
3735
+ process.__vitest_worker__.current = void 0;
3687
3736
  updateTask(test);
3688
3737
  }
3689
3738
  async function runSuite(suite) {
@@ -1246,15 +1246,15 @@ function cliTruncate(text, columns, options) {
1246
1246
 
1247
1247
  const F_RIGHT = "\u2192";
1248
1248
  const F_DOWN = "\u2193";
1249
- const F_UP = "\u2191";
1250
1249
  const F_DOWN_RIGHT = "\u21B3";
1251
1250
  const F_POINTER = "\u276F";
1252
1251
  const F_DOT = "\xB7";
1253
1252
  const F_CHECK = "\u221A";
1254
1253
  const F_CROSS = "\xD7";
1254
+ const F_LONG_DASH = "\u23AF";
1255
1255
 
1256
1256
  async function printError(error) {
1257
- const { server } = process.__vitest__;
1257
+ const ctx = process.__vitest__;
1258
1258
  let e = error;
1259
1259
  if (typeof error === "string") {
1260
1260
  e = {
@@ -1263,17 +1263,18 @@ async function printError(error) {
1263
1263
  };
1264
1264
  }
1265
1265
  let codeFramePrinted = false;
1266
- const stacks = parseStack(e.stack || e.stackStr || "");
1267
- const nearest = stacks.find((stack) => server.moduleGraph.getModuleById(stack.file));
1266
+ const stackStr = e.stack || e.stackStr || "";
1267
+ const stacks = parseStack(stackStr);
1268
+ const nearest = stacks.find((stack) => !stack.file.includes("vitest/dist") && ctx.server.moduleGraph.getModuleById(stack.file));
1268
1269
  if (nearest) {
1269
- const mod = server.moduleGraph.getModuleById(nearest.file);
1270
- const transformResult = mod == null ? void 0 : mod.ssrTransformResult;
1271
- const pos = await getOriginalPos(transformResult == null ? void 0 : transformResult.map, nearest);
1270
+ const pos = await getSourcePos(ctx, nearest);
1272
1271
  if (pos && existsSync(nearest.file)) {
1273
1272
  const sourceCode = await promises.readFile(nearest.file, "utf-8");
1274
- displayErrorMessage(e);
1275
- displayFilePath(nearest.file, pos);
1276
- displayCodeFrame(sourceCode, pos);
1273
+ printErrorMessage(e);
1274
+ await printStack(ctx, stacks, nearest, (s) => {
1275
+ if (s === nearest)
1276
+ ctx.console.log(c.yellow(generateCodeFrame(sourceCode, 4, pos)));
1277
+ });
1277
1278
  codeFramePrinted = true;
1278
1279
  }
1279
1280
  }
@@ -1282,18 +1283,31 @@ async function printError(error) {
1282
1283
  if (e.showDiff)
1283
1284
  displayDiff(e.actual, e.expected);
1284
1285
  }
1286
+ async function getSourcePos(ctx, nearest) {
1287
+ const mod = ctx.server.moduleGraph.getModuleById(nearest.file);
1288
+ const transformResult = mod == null ? void 0 : mod.ssrTransformResult;
1289
+ const pos = await getOriginalPos(transformResult == null ? void 0 : transformResult.map, nearest);
1290
+ return pos;
1291
+ }
1285
1292
  function displayDiff(actual, expected) {
1286
1293
  console.error(c.gray(generateDiff(stringify(actual), stringify(expected))));
1287
1294
  }
1288
- function displayErrorMessage(error) {
1295
+ function printErrorMessage(error) {
1289
1296
  const errorName = error.name || error.nameStr || "Unknown Error";
1290
1297
  console.error(c.red(`${c.bold(errorName)}: ${error.message}`));
1291
1298
  }
1292
- function displayFilePath(filePath, pos) {
1293
- console.log(c.gray(`${filePath}:${pos.line}:${pos.column}`));
1294
- }
1295
- function displayCodeFrame(sourceCode, pos) {
1296
- console.log(c.yellow(generateCodeFrame(sourceCode, pos)));
1299
+ async function printStack(ctx, stack, highlight, onStack) {
1300
+ if (!stack.length)
1301
+ return;
1302
+ for (const frame of stack) {
1303
+ const pos = await getSourcePos(ctx, frame) || frame;
1304
+ const color = frame === highlight ? c.yellow : c.gray;
1305
+ ctx.console.log(color(` ${c.dim(F_POINTER)} ${[frame.method, c.dim(`${frame.file}:${pos.line}:${pos.column}`)].filter(Boolean).join(" ")}`));
1306
+ onStack == null ? void 0 : onStack(frame);
1307
+ if (frame.file in ctx.state.filesMap)
1308
+ break;
1309
+ }
1310
+ ctx.console.log();
1297
1311
  }
1298
1312
  function getOriginalPos(map, { line, column }) {
1299
1313
  return new Promise((resolve) => {
@@ -1319,12 +1333,12 @@ function posToNumber(source, pos) {
1319
1333
  start += lines[i].length + 1;
1320
1334
  return start + column;
1321
1335
  }
1322
- function generateCodeFrame(source, start = 0, end, range = 2) {
1336
+ function generateCodeFrame(source, indent = 0, start = 0, end, range = 2) {
1323
1337
  start = posToNumber(source, start);
1324
1338
  end = end || start;
1325
1339
  const lines = source.split(splitRE);
1326
1340
  let count = 0;
1327
- const res = [];
1341
+ let res = [];
1328
1342
  function lineNo(no = "") {
1329
1343
  return c.gray(`${String(no).padStart(3, " ")}| `);
1330
1344
  }
@@ -1337,15 +1351,15 @@ function generateCodeFrame(source, start = 0, end, range = 2) {
1337
1351
  const lineLength = lines[j].length;
1338
1352
  if (lineLength > 200)
1339
1353
  return "";
1340
- res.push(lineNo(j + 1) + cliTruncate(lines[j], process.stdout.columns - 5));
1354
+ res.push(lineNo(j + 1) + cliTruncate(lines[j], process.stdout.columns - 5 - indent));
1341
1355
  if (j === i) {
1342
1356
  const pad = start - (count - lineLength);
1343
1357
  const length = Math.max(1, end > count ? lineLength - pad : end - start);
1344
- res.push(lineNo() + " ".repeat(pad) + F_UP.repeat(length));
1358
+ res.push(lineNo() + " ".repeat(pad) + c.red("^".repeat(length)));
1345
1359
  } else if (j > i) {
1346
1360
  if (end > count) {
1347
1361
  const length = Math.max(1, Math.min(end - count, lineLength));
1348
- res.push(lineNo() + F_UP.repeat(length));
1362
+ res.push(lineNo() + c.red("^".repeat(length)));
1349
1363
  }
1350
1364
  count += lineLength + 1;
1351
1365
  }
@@ -1353,13 +1367,15 @@ function generateCodeFrame(source, start = 0, end, range = 2) {
1353
1367
  break;
1354
1368
  }
1355
1369
  }
1370
+ if (indent)
1371
+ res = res.map((line) => " ".repeat(indent) + line);
1356
1372
  return res.join("\n");
1357
1373
  }
1358
1374
  function stringify(obj) {
1359
1375
  return String(obj);
1360
1376
  }
1361
1377
  const stackFnCallRE = /at (.*) \((.+):(\d+):(\d+)\)$/;
1362
- const stackBarePathRE = /at ()(.+):(\d+):(\d+)$/;
1378
+ const stackBarePathRE = /at ?(.*) (.+):(\d+):(\d+)$/;
1363
1379
  function parseStack(stack) {
1364
1380
  const lines = stack.split("\n");
1365
1381
  const stackFrames = lines.map((raw) => {
@@ -1412,4 +1428,4 @@ function notBlank(line) {
1412
1428
  return typeof line !== "undefined" && line !== null;
1413
1429
  }
1414
1430
 
1415
- export { F_POINTER as F, ansiStyles as a, stripAnsi as b, sliceAnsi as c, c as d, F_DOWN as e, F_DOWN_RIGHT as f, F_DOT as g, F_CHECK as h, F_CROSS as i, cliTruncate as j, F_RIGHT as k, generateDiff as l, printError as p, stringWidth as s };
1431
+ export { F_POINTER as F, ansiStyles as a, stripAnsi as b, sliceAnsi as c, c as d, F_DOWN as e, F_LONG_DASH as f, F_DOWN_RIGHT as g, F_DOT as h, F_CHECK as i, F_CROSS as j, cliTruncate as k, F_RIGHT as l, generateDiff as m, printError as p, stringWidth as s };
package/dist/index.d.ts CHANGED
@@ -149,6 +149,12 @@ interface VitestContext {
149
149
  state: StateManager;
150
150
  snapshot: SnapshotManager;
151
151
  reporter: Reporter;
152
+ console: Console;
153
+ }
154
+ interface UserConsoleLog {
155
+ content: string;
156
+ type: 'stdout' | 'stderr';
157
+ taskId?: string;
152
158
  }
153
159
 
154
160
  declare type RunMode = 'run' | 'skip' | 'only' | 'todo';
@@ -239,6 +245,7 @@ interface Reporter {
239
245
  onTaskUpdate?: (pack: TaskResultPack) => Awaitable<void>;
240
246
  onWatcherStart?: () => Awaitable<void>;
241
247
  onWatcherRerun?: (files: string[], trigger: string) => Awaitable<void>;
248
+ onUserConsoleLog?: (log: UserConsoleLog) => Awaitable<void>;
242
249
  }
243
250
 
244
251
  declare type SnapshotData = Record<string, string>;
@@ -372,8 +379,25 @@ interface UserOptions {
372
379
  */
373
380
  minThreads?: number;
374
381
  interpretDefault?: boolean;
382
+ /**
383
+ * Default timeout of a test in milliseconds
384
+ *
385
+ * @default 5000
386
+ */
375
387
  testTimeout?: number;
388
+ /**
389
+ * Default timeout of a hook in milliseconds
390
+ *
391
+ * @default 5000
392
+ */
376
393
  hookTimeout?: number;
394
+ /**
395
+ * Silent mode
396
+ * TODO: implement this
397
+ *
398
+ * @default false
399
+ */
400
+ silent?: boolean;
377
401
  }
378
402
  interface CliOptions extends UserOptions {
379
403
  /**
@@ -407,8 +431,8 @@ interface WorkerContext {
407
431
  invalidates?: string[];
408
432
  }
409
433
  interface RpcMap {
410
- workerReady: [[], void];
411
434
  fetch: [[id: string], TransformResult | null | undefined];
435
+ log: [[UserConsoleLog], void];
412
436
  onCollected: [[files: File[]], void];
413
437
  onFinished: [[], void];
414
438
  onTaskUpdate: [[pack: TaskResultPack], void];
@@ -527,6 +551,7 @@ declare global {
527
551
  config: ResolvedConfig;
528
552
  rpc: RpcCall;
529
553
  send: RpcSend;
554
+ current?: Test;
530
555
  };
531
556
  }
532
557
  }
@@ -551,6 +576,7 @@ declare global {
551
576
  }
552
577
  interface Assertion {
553
578
  toMatchSnapshot(message?: string): Assertion;
579
+ toMatchInlineSnapshot(snapshot?: string, message?: string): Assertion;
554
580
  matchSnapshot(message?: string): Assertion;
555
581
  toEqual(expected: any): void;
556
582
  toStrictEqual(expected: any): void;
@@ -572,6 +598,7 @@ declare global {
572
598
  toBeInstanceOf(c: any): void;
573
599
  toBeCalledTimes(n: number): void;
574
600
  toHaveLength(l: number): void;
601
+ toHaveProperty(p: string, value?: any): void;
575
602
  toBeCloseTo(number: number, numDigits?: number): void;
576
603
  toHaveBeenCalledTimes(n: number): void;
577
604
  toHaveBeenCalledOnce(): void;
@@ -599,4 +626,4 @@ declare global {
599
626
  }
600
627
  }
601
628
 
602
- export { Arrayable, Awaitable, CliOptions, ComputeMode, Environment, EnvironmentReturn, File, GlobalContext, HookListener, ModuleCache, Nullable, Reporter, ResolvedConfig, RpcCall, RpcMap, RpcPayload, RpcSend, RunMode, SnapshotData, SnapshotMatchOptions, SnapshotResult, SnapshotStateOptions, SnapshotSummary, SnapshotUpdateState, Suite, SuiteCollector, SuiteHooks, Task, TaskBase, TaskResult, TaskResultPack, TaskState, Test, TestCollector, TestFactory, TestFunction, UncheckedSnapshot, UserOptions, VitestContext, WorkerContext, afterAll, afterEach, beforeAll, beforeEach, clearContext, createSuiteHooks, defaultSuite, describe, it, mock, spy, stub, suite, test };
629
+ export { Arrayable, Awaitable, CliOptions, ComputeMode, Environment, EnvironmentReturn, File, GlobalContext, HookListener, ModuleCache, Nullable, Reporter, ResolvedConfig, RpcCall, RpcMap, RpcPayload, RpcSend, RunMode, SnapshotData, SnapshotMatchOptions, SnapshotResult, SnapshotStateOptions, SnapshotSummary, SnapshotUpdateState, Suite, SuiteCollector, SuiteHooks, Task, TaskBase, TaskResult, TaskResultPack, TaskState, Test, TestCollector, TestFactory, TestFunction, UncheckedSnapshot, UserConsoleLog, UserOptions, VitestContext, WorkerContext, afterAll, afterEach, beforeAll, beforeEach, clearContext, createSuiteHooks, defaultSuite, describe, it, mock, spy, stub, suite, test };
package/dist/worker.js CHANGED
@@ -53,6 +53,18 @@ async function interpretedImport(path, interpretDefault) {
53
53
  }
54
54
  return mod;
55
55
  }
56
+ let SOURCEMAPPING_URL = "sourceMa";
57
+ SOURCEMAPPING_URL += "ppingURL";
58
+ async function withInlineSourcemap(result) {
59
+ const { code, map } = result;
60
+ if (code.includes(`${SOURCEMAPPING_URL}=`))
61
+ return result;
62
+ if (map)
63
+ result.code = `${code}
64
+
65
+ //# ${SOURCEMAPPING_URL}=data:application/json;charset=utf-8;base64,${Buffer.from(JSON.stringify(map), "utf-8").toString("base64")}`;
66
+ return result;
67
+ }
56
68
  async function executeInViteNode(options) {
57
69
  const { moduleCache, root, files, fetch } = options;
58
70
  const externaled = new Set(builtinModules);
@@ -79,6 +91,8 @@ ${[...callstack, dep].reverse().map((p) => `- ${p}`).join("\n")}`);
79
91
  const result2 = await fetch(id);
80
92
  if (!result2)
81
93
  throw new Error(`failed to load ${id}`);
94
+ if (process.env.NODE_V8_COVERAGE)
95
+ withInlineSourcemap(result2);
82
96
  const url = pathToFileURL(fsPath).href;
83
97
  const exports = {};
84
98
  setCache(fsPath, { transformResult: result2, exports });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vitest",
3
- "version": "0.0.71",
3
+ "version": "0.0.75",
4
4
  "description": "A blazing fast unit test framework powered by Vite",
5
5
  "keywords": [
6
6
  "vite",
@@ -51,7 +51,8 @@
51
51
  "test": "node bin/vitest.mjs -r test/core",
52
52
  "test:all": "cross-env CI=true pnpm -r --stream --filter !vitest run test --",
53
53
  "test:ci": "cross-env CI=true pnpm -r --stream --filter !vitest --filter !@vitest/test-fails run test --",
54
- "typecheck": "tsc --noEmit && nr lint"
54
+ "typecheck": "tsc --noEmit && nr lint",
55
+ "ci": "ni && nr typecheck && nr lint && nr build && nr test:all"
55
56
  },
56
57
  "dependencies": {
57
58
  "@types/chai": "^4.3.0",