Skip to content

Commit

Permalink
test: migrate to vitest (#8076)
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu authored May 11, 2022
1 parent bb603d3 commit 8148f67
Show file tree
Hide file tree
Showing 72 changed files with 714 additions and 2,323 deletions.
9 changes: 1 addition & 8 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,7 @@ module.exports = defineConfig({
'node/no-missing-import': [
'error',
{
allowModules: [
'types',
'estree',
'testUtils',
'less',
'sass',
'stylus'
],
allowModules: ['types', 'estree', 'less', 'sass', 'stylus'],
tryExtensions: ['.ts', '.js', '.jsx', '.tsx', '.d.ts']
}
],
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,10 @@ jobs:
run: pnpm run test-unit

- name: Test serve
run: pnpm run test-serve -- --runInBand
run: pnpm run test-serve

- name: Test build
run: pnpm run test-build -- --runInBand
run: pnpm run test-build

lint:
timeout-minutes: 10
Expand Down
12 changes: 6 additions & 6 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ If you want to use break point and explore code execution you can use the ["Run

5. The execution will stop and you'll use the [Debug toolbar](https://code.visualstudio.com/docs/editor/debugging#_debug-actions) to continue, step over, restart the process...

### Debugging errors in Jest tests using Playwright (Chromium)
### Debugging errors in Vitest tests using Playwright (Chromium)

Some errors are masked and hidden away because of the layers of abstraction and sandboxed nature added by Jest, Playwright, and Chromium. In order to see what's actually going wrong and the contents of the devtools console in those instances, follow this setup:
Some errors are masked and hidden away because of the layers of abstraction and sandboxed nature added by Vitest, Playwright, and Chromium. In order to see what's actually going wrong and the contents of the devtools console in those instances, follow this setup:

1. Add a `debugger` statement to the `scripts/jestPerTestSetup.ts` -> `afterAll` hook. This will pause execution before the tests quit and the Playwright browser instance exits.
1. Add a `debugger` statement to the `scripts/vitestSetup.ts` -> `afterAll` hook. This will pause execution before the tests quit and the Playwright browser instance exits.

1. Run the tests with the `debug-serve` script command which will enable remote debugging: `pnpm run debug-serve -- --runInBand resolve`.

Expand Down Expand Up @@ -69,15 +69,15 @@ And re-run `pnpm install` to link the package.

### Integration Tests

Each package under `playground/` contains a `__tests__` directory. The tests are run using [Jest](https://jestjs.io/) + [Playwright](https://playwright.dev/) with custom integrations to make writing tests simple. The detailed setup is inside `jest.config.js` and `scripts/jest*` files.
Each package under `playground/` contains a `__tests__` directory. The tests are run using [Vitest](https://vitest.dev/) + [Playwright](https://playwright.dev/) with custom integrations to make writing tests simple. The detailed setup is inside `vitest.config.e2e.js` and `scripts/vitest*` files.

Before running the tests, make sure that [Vite has been built](#repo-setup). On Windows, you may want to [activate Developer Mode](https://docs.microsoft.com/en-us/windows/apps/get-started/enable-your-device-for-development) to solve [issues with symlink creation for non-admins](https://github.com/vitejs/vite/issues/7390). Also you may want to [set git `core.symlinks` to `true` to solve issues with symlinks in git](https://github.com/vitejs/vite/issues/5242).

Each integration test can be run under either dev server mode or build mode.

- `pnpm test` by default runs every integration test in both serve and build mode, and also unit tests.

- `pnpm run test-serve` runs tests only under serve mode. This is just calling `jest` so you can pass any Jest flags to this command. Since Jest will attempt to run tests in parallel, if your machine has many cores this may cause flaky test failures with multiple Playwright instances running at the same time. You can force the tests to run in series with `pnpm run test-serve -- --runInBand`.
- `pnpm run test-serve` runs tests only under serve mode.

- `pnpm run test-build` runs tests only under build mode.

Expand Down Expand Up @@ -105,7 +105,7 @@ test('should work', async () => {

Some common test helpers, e.g. `testDir`, `isBuild` or `editFile` are available in `playground/testUtils.ts`.

Note: The test build environment uses a [different default set of Vite config](https://github.com/vitejs/vite/blob/9c6501d9c363eaa3c1e7708d531fb2a92b633db6/scripts/jestPerTestSetup.ts#L102-L122) to skip transpilation during tests to make it faster. This may produce a different result compared to the default production build.
Note: The test build environment uses a [different default set of Vite config](https://github.com/vitejs/vite/blob/9c6501d9c363eaa3c1e7708d531fb2a92b633db6/scripts/vitestSetup.ts#L102-L122) to skip transpilation during tests to make it faster. This may produce a different result compared to the default production build.

### Extending the Test Suite

Expand Down
24 changes: 0 additions & 24 deletions jest.config.ts

This file was deleted.

15 changes: 7 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
"format": "prettier --write .",
"lint": "eslint packages/*/{src,types}/**",
"test": "run-s test-unit test-serve test-build",
"test-serve": "jest",
"test-build": "cross-env VITE_TEST_BUILD=1 jest",
"test-serve": "vitest run -c vitest.config.e2e.ts",
"test-build": "cross-env VITE_TEST_BUILD=1 vitest run -c vitest.config.e2e.ts",
"test-unit": "vitest run",
"debug-serve": "cross-env VITE_DEBUG_SERVE=1 node --inspect-brk ./node_modules/.bin/jest",
"debug-build": "cross-env VITE_TEST_BUILD=1 VITE_PRESERVE_BUILD_ARTIFACTS=1 node --inspect-brk ./node_modules/.bin/jest",
"debug-serve": "cross-env VITE_DEBUG_SERVE=1 vitest run -c vitest.config.e2e.ts",
"debug-build": "cross-env VITE_TEST_BUILD=1 VITE_PRESERVE_BUILD_ARTIFACTS=1 vitest run -c vitest.config.e2e.ts",
"docs": "vitepress dev docs",
"build-docs": "vitepress build docs",
"serve-docs": "vitepress serve docs",
Expand All @@ -36,8 +36,8 @@
},
"devDependencies": {
"@microsoft/api-extractor": "^7.23.1",
"@types/babel__core": "^7.1.19",
"@types/fs-extra": "^9.0.13",
"@types/jest": "^27.5.0",
"@types/node": "^17.0.31",
"@types/prompts": "^2.4.0",
"@types/semver": "^7.3.9",
Expand All @@ -51,7 +51,7 @@
"eslint-plugin-node": "^11.1.0",
"execa": "^5.1.1",
"fs-extra": "^10.1.0",
"jest": "^27.5.1",
"kill-port": "^1.6.1",
"lint-staged": "^12.4.1",
"minimist": "^1.2.6",
"node-fetch": "^2.6.7",
Expand All @@ -65,12 +65,11 @@
"semver": "^7.3.7",
"simple-git-hooks": "^2.7.0",
"sirv": "^2.0.2",
"ts-jest": "^27.1.4",
"ts-node": "^10.7.0",
"typescript": "^4.6.4",
"vite": "workspace:*",
"vitepress": "^0.22.4",
"vitest": "^0.10.5"
"vitest": "^0.12.4"
},
"simple-git-hooks": {
"pre-commit": "pnpm exec lint-staged --concurrent false",
Expand Down
38 changes: 18 additions & 20 deletions packages/vite/src/node/__tests__/plugins/css.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,31 +179,29 @@ describe('hoist @ rules', () => {

test('dont hoist @import and @charset in comments', async () => {
const css = `
.foo{color:red;}
/*
@import "bla";
*/
@charset "utf-8";
/*
@charset "utf-8";
@import "bar";
*/
@import "baz";
`
.foo{color:red;}
/*
@import "bla";
*/
@charset "utf-8";
/*
@charset "utf-8";
@import "bar";
*/
@import "baz";`
const result = await hoistAtRules(css)
expect(result).toBe(
`@charset "utf-8";@import "baz";
expect(result).toMatchInlineSnapshot(`
"@charset \\"utf-8\\";@import \\"baz\\";
.foo{color:red;}
/*
@import "bla";
@import \\"bla\\";
*/
/*
@charset "utf-8";
@import "bar";
@charset \\"utf-8\\";
@import \\"bar\\";
*/
`
)
"
`)
})
})
2 changes: 1 addition & 1 deletion packages/vite/src/node/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ export async function createServer(
try {
await server.close()
} finally {
process.exit(0)
process.exit()
}
}

Expand Down
1 change: 1 addition & 0 deletions packages/vite/src/node/ssr/ssrModuleLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ async function nodeImport(
importer,
// Non-external modules can import ESM-only modules, but only outside
// of test runs, because we use Node `require` in Jest to avoid segfault.
// @ts-expect-error
typeof jest === 'undefined'
? { ...resolveOptions, tryEsmOnly: true }
: resolveOptions
Expand Down
2 changes: 2 additions & 0 deletions packages/vite/src/node/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -743,7 +743,9 @@ export const multilineCommentsRE = /\/\*(.|[\r\n])*?\*\//gm
export const singlelineCommentsRE = /\/\/.*/g
export const requestQuerySplitRE = /\?(?!.*[\/|\}])/

// @ts-expect-error
export const usingDynamicImport = typeof jest === 'undefined'

/**
* Dynamically import files. It will make sure it's not being compiled away by TS/Rollup.
*
Expand Down
100 changes: 43 additions & 57 deletions playground/assets/__tests__/assets.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,11 +175,9 @@ describe('css url() references', () => {
expect(bg).toMatch(assetMatch)
})

if (isBuild) {
test('preserve postfix query/hash', () => {
expect(findAssetFile(/\.css$/, 'foo')).toMatch(`woff2?#iefix`)
})
}
test.runIf(isBuild)('preserve postfix query/hash', () => {
expect(findAssetFile(/\.css$/, 'foo')).toMatch(`woff2?#iefix`)
})
})

describe('image', () => {
Expand Down Expand Up @@ -254,17 +252,13 @@ describe('unicode url', () => {
})
})

describe('encodeURI', () => {
if (isBuild) {
test('img src with encodeURI', async () => {
const img = await page.$('.encodeURI')
expect(
await (
await img.getAttribute('src')
).startsWith('data:image/png;base64')
).toBe(true)
})
}
describe.runIf(isBuild)('encodeURI', () => {
test('img src with encodeURI', async () => {
const img = await page.$('.encodeURI')
expect(
await (await img.getAttribute('src')).startsWith('data:image/png;base64')
).toBe(true)
})
})

test('new URL(..., import.meta.url)', async () => {
Expand All @@ -286,51 +280,43 @@ test('new URL(`non-existent`, import.meta.url)', async () => {
)
})

if (isBuild) {
test('manifest', async () => {
const manifest = readManifest('foo')
const entry = manifest['index.html']

for (const file of listAssets('foo')) {
if (file.endsWith('.css')) {
expect(entry.css).toContain(`assets/${file}`)
} else if (!file.endsWith('.js')) {
expect(entry.assets).toContain(`assets/${file}`)
}
test.runIf(isBuild)('manifest', async () => {
const manifest = readManifest('foo')
const entry = manifest['index.html']

for (const file of listAssets('foo')) {
if (file.endsWith('.css')) {
expect(entry.css).toContain(`assets/${file}`)
} else if (!file.endsWith('.js')) {
expect(entry.assets).toContain(`assets/${file}`)
}
})
}
}
})

describe('css and assets in css in build watch', () => {
if (isBuild) {
test('css will not be lost and css does not contain undefined', async () => {
editFile('index.html', (code) => code.replace('Assets', 'assets'), true)
await notifyRebuildComplete(watcher)
const cssFile = findAssetFile(/index\.\w+\.css$/, 'foo')
expect(cssFile).not.toBe('')
expect(cssFile).not.toMatch(/undefined/)
})
describe.runIf(isBuild)('css and assets in css in build watch', () => {
test('css will not be lost and css does not contain undefined', async () => {
editFile('index.html', (code) => code.replace('Assets', 'assets'), true)
await notifyRebuildComplete(watcher)
const cssFile = findAssetFile(/index\.\w+\.css$/, 'foo')
expect(cssFile).not.toBe('')
expect(cssFile).not.toMatch(/undefined/)
})

test('import module.css', async () => {
expect(await getColor('#foo')).toBe('red')
editFile(
'css/foo.module.css',
(code) => code.replace('red', 'blue'),
true
)
await notifyRebuildComplete(watcher)
await page.reload()
expect(await getColor('#foo')).toBe('blue')
})
test('import module.css', async () => {
expect(await getColor('#foo')).toBe('red')
editFile('css/foo.module.css', (code) => code.replace('red', 'blue'), true)
await notifyRebuildComplete(watcher)
await page.reload()
expect(await getColor('#foo')).toBe('blue')
})

test('import with raw query', async () => {
expect(await page.textContent('.raw-query')).toBe('foo')
editFile('static/foo.txt', (code) => code.replace('foo', 'zoo'), true)
await notifyRebuildComplete(watcher)
await page.reload()
expect(await page.textContent('.raw-query')).toBe('zoo')
})
}
test('import with raw query', async () => {
expect(await page.textContent('.raw-query')).toBe('foo')
editFile('static/foo.txt', (code) => code.replace('foo', 'zoo'), true)
await notifyRebuildComplete(watcher)
await page.reload()
expect(await page.textContent('.raw-query')).toBe('zoo')
})
})

test('inline style test', async () => {
Expand Down
Loading

0 comments on commit 8148f67

Please sign in to comment.