Skip to content

Commit

Permalink
Merge branch 'main' into fix/disable-strict
Browse files Browse the repository at this point in the history
  • Loading branch information
sheremet-va committed Aug 14, 2023
2 parents 9697173 + dbf0e97 commit cd4ad31
Show file tree
Hide file tree
Showing 44 changed files with 1,778 additions and 1,231 deletions.
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
* text=auto eol=lf

test/reporters/fixtures/indicator-position.test.js eol=crlf
2 changes: 1 addition & 1 deletion docs/api/vi.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ import { vi } from 'vitest'

## vi.fn

- **Type:** `(fn?: Function) => CallableMockInstance`
- **Type:** `(fn?: Function) => Mock`

Creates a spy on a function, though can be initiated without one. Every time a function is invoked, it stores its call arguments, returns, and instances. Also, you can manipulate its behavior with [methods](/api/mock).
If no function is given, mock will return `undefined`, when invoked.
Expand Down
57 changes: 56 additions & 1 deletion docs/config/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,14 +196,69 @@ When Vitest encounters the external library listed in `include`, it will be bund
- Your `alias` configuration is now respected inside bundled packages
- Code in your tests is running closer to how it's running in the browser

Be aware that only packages in `deps.optimizer?.[mode].include` option are bundled (some plugins populate this automatically, like Svelte). You can read more about available options in [Vite](https://vitejs.dev/config/dep-optimization-options.html) docs. By default, Vitest uses `optimizer.web` for `jsdom` and `happy-dom` environments, and `optimizer.ssr` for `node` and `edge` environments, but it is configurable by [`transformMode`](#transformmode).
Be aware that only packages in `deps.optimizer?.[mode].include` option are bundled (some plugins populate this automatically, like Svelte). You can read more about available options in [Vite](https://vitejs.dev/config/dep-optimization-options.html) docs (Vitest doesn't support `disable` and `noDiscovery` options). By default, Vitest uses `optimizer.web` for `jsdom` and `happy-dom` environments, and `optimizer.ssr` for `node` and `edge` environments, but it is configurable by [`transformMode`](#transformmode).

This options also inherits your `optimizeDeps` configuration (for web Vitest will extend `optimizeDeps`, for ssr - `ssr.optimizeDeps`). If you redefine `include`/`exclude` option in `deps.optimizer` it will extend your `optimizeDeps` when running tests. Vitest automatically removes the same options from `include`, if they are listed in `exclude`.

::: tip
You will not be able to edit your `node_modules` code for debugging, since the code is actually located in your `cacheDir` or `test.cache.dir` directory. If you want to debug with `console.log` statements, edit it directly or force rebundling with `deps.optimizer?.[mode].force` option.
:::

#### deps.optimizer.{mode}.enabled

- **Type:** `boolean`
- **Default:** `true`

Enable dependency optimization.

#### deps.web

- **Type:** `{ transformAssets?, ... }`
- **Version:** Since Vite 0.34.2

Options that are applied to external files when transform mode is set to `web`. By default, `jsdom` and `happy-dom` use `web` mode, while `node` and `edge` environments use `ssr` transform mode, so these options will have no affect on files inside those environments.

Usually, files inside `node_modules` are externalized, but these options also affect files in [`server.deps.external`](#server-deps-external).

#### deps.web.transformAssets

- **Type:** `boolean`
- **Default:** `true`

Should Vitest process assets (.png, .svg, .jpg, etc) files and resolve them like Vite does in the browser.

hese module will have a default export equal to the path to the asset, if no query is specified.

::: warning
At the moment, this option only works with [`experimentalVmThreads`](#experimentalvmthreads) pool.
:::

#### deps.web.transformCss

- **Type:** `boolean`
- **Default:** `true`

Should Vitest process CSS (.css, .scss, .sass, etc) files and resolve them like Vite does in the browser.

If CSS files are disabled with [`css`](#css) options, this option will just silence `UNKNOWN_EXTENSION` errors.

::: warning
At the moment, this option only works with [`experimentalVmThreads`](#experimentalvmthreads) pool.
:::

#### deps.web.transformGlobPattern

- **Type:** `RegExp | RegExp[]`
- **Default:** `[]`

Regexp pattern to match external files that should be transformed.

By default, files inside `node_modules` are externalized and not transformed, unless it's CSS or an asset, and corresponding option is not disabled.

::: warning
At the moment, this option only works with [`experimentalVmThreads`](#experimentalvmthreads) pool.
:::

#### deps.registerNodeLoader<NonProjectOption />

- **Type:** `boolean`
Expand Down
2 changes: 1 addition & 1 deletion docs/guide/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ export default defineConfig({
Even if you do not use Vite yourself, Vitest relies heavily on it for its transformation pipeline. For that reason, you can also configure any property described in [Vite documentation](https://vitejs.dev/config/).
:::
If you are already using Vite, add `test` property in your Vite config. You'll also need to add a reference to Vitest types using a [triple slash command](https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html#-reference-types-) at the top of your config file.
If you are already using Vite, add `test` property in your Vite config. You'll also need to add a reference to Vitest types using a [triple slash directive](https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html#-reference-types-) at the top of your config file.
```ts
/// <reference types="vitest" />
Expand Down
4 changes: 0 additions & 4 deletions docs/guide/migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,6 @@ If you are only partially mocking a package, you might have previously used Jest
+ const { cloneDeep } = await vi.importActual('lodash/cloneDeep')
```

**Jasmine API**

Jest exports various [`jasmine`](https://jasmine.github.io/) globals (such as `jasmine.any()`). Any such instances will need to be migrated to [their Vitest counterparts](/api/).

**Envs**

Just like Jest, Vitest sets `NODE_ENV` to `test`, if it wasn't set before. Vitest also has a counterpart for `JEST_WORKER_ID` called `VITEST_POOL_ID` (always less than or equal to `maxThreads`), so if you rely on it, don't forget to rename it. Vitest also exposes `VITEST_WORKER_ID` which is a unique ID of a running worker - this number is not affected by `maxThreads`, and will increase with each created worker.
Expand Down
13 changes: 13 additions & 0 deletions packages/vite-node/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,19 @@ export class ViteNodeServer {
return this.transformPromiseMap.get(id)!
}

async transformModule(id: string, transformMode?: 'web' | 'ssr') {
if (transformMode !== 'web')
throw new Error('`transformModule` only supports `transformMode: "web"`.')

const normalizedId = normalizeModuleId(id)
const mod = this.server.moduleGraph.getModuleById(normalizedId)
const result = mod?.transformResult || await this.server.transformRequest(normalizedId)

return {
code: result?.code,
}
}

getTransformMode(id: string) {
const withoutQuery = id.split('?')[0]

Expand Down
4 changes: 2 additions & 2 deletions packages/vitest/src/integrations/vi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,13 @@ interface VitestUtils {
/**
* Makes value available on global namespace.
* Useful, if you want to have global variables available, like `IntersectionObserver`.
* You can return it back to original value with `vi.unstubGlobals`, or by enabling `unstubGlobals` config option.
* You can return it back to original value with `vi.unstubAllGlobals`, or by enabling `unstubGlobals` config option.
*/
stubGlobal(name: string | symbol | number, value: unknown): this

/**
* Changes the value of `import.meta.env` and `process.env`.
* You can return it back to original value with `vi.unstubEnvs`, or by enabling `unstubEnvs` config option.
* You can return it back to original value with `vi.unstubAllEnvs`, or by enabling `unstubEnvs` config option.
*/
stubEnv(name: string, value: string): this

Expand Down
24 changes: 20 additions & 4 deletions packages/vitest/src/node/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,11 @@ export function resolveConfig(
if (!resolved.deps.moduleDirectories.includes('/node_modules/'))
resolved.deps.moduleDirectories.push('/node_modules/')

resolved.deps.web ??= {}
resolved.deps.web.transformAssets ??= true
resolved.deps.web.transformCss ??= true
resolved.deps.web.transformGlobPattern ??= []

resolved.server ??= {}
resolved.server.deps ??= {}

Expand Down Expand Up @@ -213,10 +218,21 @@ export function resolveConfig(
snapshotEnvironment: null as any,
}

resolved.experimentalVmWorkerMemoryLimit = stringToBytes(
getWorkerMemoryLimit(resolved),
totalmem(),
)
const memory = totalmem()
const limit = getWorkerMemoryLimit(resolved)

if (typeof memory === 'number') {
resolved.experimentalVmWorkerMemoryLimit = stringToBytes(
limit,
resolved.watch ? memory / 2 : memory,
)
}
else if (limit > 1) {
resolved.experimentalVmWorkerMemoryLimit = stringToBytes(limit)
}
else {
// just ignore "experimentalVmWorkerMemoryLimit" value because we cannot detect memory limit
}

if (options.resolveSnapshotPath)
delete (resolved as UserConfig).resolveSnapshotPath
Expand Down
15 changes: 9 additions & 6 deletions packages/vitest/src/node/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,10 +179,12 @@ function printModuleWarningForPackage(logger: Logger, path: string, name: string
+ '\n'
+ c.green(`export default {
test: {
deps: {
inline: [
${c.yellow(c.bold(`"${name}"`))}
]
server: {
deps: {
inline: [
${c.yellow(c.bold(`"${name}"`))}
]
}
}
}
}\n`)))
Expand Down Expand Up @@ -251,6 +253,7 @@ export function generateCodeFrame(
const start = positionToOffset(source, lineNumber, columnNumber)
const end = start
const lines = source.split(lineSplitRE)
const nl = /\r\n/.test(source) ? 2 : 1
let count = 0
let res: string[] = []

Expand All @@ -261,7 +264,7 @@ export function generateCodeFrame(
}

for (let i = 0; i < lines.length; i++) {
count += lines[i].length + 1
count += lines[i].length + nl
if (count >= start) {
for (let j = i - range; j <= i + range || end > count; j++) {
if (j < 0 || j >= lines.length)
Expand All @@ -277,7 +280,7 @@ export function generateCodeFrame(

if (j === i) {
// push underline
const pad = start - (count - lineLength)
const pad = start - (count - lineLength) + (nl - 1)
const length = Math.max(1, end > count ? lineLength - pad : end - start)
res.push(lineNo() + ' '.repeat(pad) + c.red('^'.repeat(length)))
}
Expand Down
3 changes: 3 additions & 0 deletions packages/vitest/src/node/pools/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ export function createMethodsRPC(project: WorkspaceProject): RuntimeRPC {
resolveId(id, importer, transformMode) {
return project.vitenode.resolveId(id, importer, transformMode)
},
transform(id, environment) {
return project.vitenode.transformModule(id, environment)
},
onPathsCollected(paths) {
ctx.state.collectPaths(paths)
project.report('onPathsCollected', paths)
Expand Down
4 changes: 2 additions & 2 deletions packages/vitest/src/node/pools/vm-threads.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import type { WorkspaceProject } from '../workspace'
import { createMethodsRPC } from './rpc'

const workerPath = pathToFileURL(resolve(distDir, './vm.js')).href
const suppressLoaderWarningsPath = resolve(rootDir, './suppress-warnings.cjs')
const suppressWarningsPath = resolve(rootDir, './suppress-warnings.cjs')

function createWorkerChannel(project: WorkspaceProject) {
const channel = new MessageChannel()
Expand Down Expand Up @@ -61,7 +61,7 @@ export function createVmThreadsPool(ctx: Vitest, { execArgv, env }: PoolProcessO
'--experimental-import-meta-resolve',
'--experimental-vm-modules',
'--require',
suppressLoaderWarningsPath,
suppressWarningsPath,
...execArgv,
],

Expand Down
4 changes: 2 additions & 2 deletions packages/vitest/src/node/workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,10 +293,10 @@ export class WorkspaceProject {
...this.config.deps,
optimizer: {
web: {
enabled: this.config.deps?.optimizer?.web?.enabled ?? false,
enabled: this.config.deps?.optimizer?.web?.enabled ?? true,
},
ssr: {
enabled: this.config.deps?.optimizer?.ssr?.enabled ?? false,
enabled: this.config.deps?.optimizer?.ssr?.enabled ?? true,
},
},
},
Expand Down
24 changes: 18 additions & 6 deletions packages/vitest/src/runtime/execute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import type { ViteNodeRunnerOptions } from 'vite-node'
import { normalize, relative, resolve } from 'pathe'
import { processError } from '@vitest/utils/error'
import type { MockMap } from '../types/mocker'
import type { ResolvedConfig, ResolvedTestEnvironment, WorkerGlobalState } from '../types'
import type { ResolvedConfig, ResolvedTestEnvironment, RuntimeRPC, WorkerGlobalState } from '../types'
import { distDir } from '../paths'
import { getWorkerState } from '../utils/global'
import { VitestMocker } from './mocker'
import { ExternalModulesExecutor } from './external-executor'
import { FileMap } from './vm/file-map'

const entryUrl = pathToFileURL(resolve(distDir, 'entry.js')).href

Expand All @@ -20,6 +21,7 @@ export interface ExecuteOptions extends ViteNodeRunnerOptions {
moduleDirectories?: string[]
context?: vm.Context
state: WorkerGlobalState
transform: RuntimeRPC['transform']
}

export async function createVitestExecutor(options: ExecuteOptions) {
Expand All @@ -39,6 +41,7 @@ let _viteNode: {
export const packageCache = new Map<string, any>()
export const moduleCache = new ModuleCacheMap()
export const mockMap: MockMap = new Map()
export const fileMap = new FileMap()

export async function startViteNode(options: ContextExecutorOptions) {
if (_viteNode)
Expand Down Expand Up @@ -98,6 +101,9 @@ export async function startVitestExecutor(options: ContextExecutorOptions) {
resolveId(id, importer) {
return rpc().resolveId(id, importer, getTransformMode())
},
transform(id) {
return rpc().transform(id, 'web')
},
packageCache,
moduleCache,
mockMap,
Expand Down Expand Up @@ -146,7 +152,11 @@ export class VitestExecutor extends ViteNodeRunner {
}

constructor(public options: ExecuteOptions) {
super(options)
super({
...options,
// interop is done inside the external executor instead
interopDefault: options.context ? false : options.interopDefault,
})

this.mocker = new VitestMocker(this)

Expand All @@ -168,10 +178,6 @@ export class VitestExecutor extends ViteNodeRunner {
}
}
else {
this.externalModules = new ExternalModulesExecutor({
context: options.context,
packageCache: options.packageCache,
})
const clientStub = vm.runInContext(
`(defaultClient) => ({ ...defaultClient, updateStyle: ${updateStyle.toString()}, removeStyle: ${removeStyle.toString()} })`,
options.context,
Expand All @@ -181,6 +187,12 @@ export class VitestExecutor extends ViteNodeRunner {
'@vite/client': clientStub,
}
this.primitives = vm.runInContext('({ Object, Reflect, Symbol })', options.context)
this.externalModules = new ExternalModulesExecutor({
...options,
fileMap,
context: options.context,
packageCache: options.packageCache,
})
}
}

Expand Down
Loading

0 comments on commit cd4ad31

Please sign in to comment.