From 452a7730e0b162745e80919d2c23118ab7df4f46 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Wed, 16 Mar 2022 20:34:27 +0800 Subject: [PATCH] feat(nuxi): init `nuxi test` support (#3307) Co-authored-by: Pooya Parsa --- examples/with-test/app.vue | 16 ++++++++++++ examples/with-test/nuxt.config.ts | 4 +++ examples/with-test/package.json | 13 ++++++++++ examples/with-test/tests/basic.test.ts | 14 +++++++++++ examples/with-test/tsconfig.json | 3 +++ package.json | 1 + packages/nuxi/build.config.ts | 2 ++ packages/nuxi/src/commands/index.ts | 3 ++- packages/nuxi/src/commands/test.ts | 34 +++++++++++++++++++++++++ packages/test-utils/src/index.ts | 1 + packages/test-utils/src/run.ts | 35 ++++++++++++++++++++++++++ yarn.lock | 11 +++++++- 12 files changed, 135 insertions(+), 2 deletions(-) create mode 100644 examples/with-test/app.vue create mode 100644 examples/with-test/nuxt.config.ts create mode 100644 examples/with-test/package.json create mode 100644 examples/with-test/tests/basic.test.ts create mode 100644 examples/with-test/tsconfig.json create mode 100644 packages/nuxi/src/commands/test.ts create mode 100644 packages/test-utils/src/run.ts diff --git a/examples/with-test/app.vue b/examples/with-test/app.vue new file mode 100644 index 0000000000..19bf5ff27e --- /dev/null +++ b/examples/with-test/app.vue @@ -0,0 +1,16 @@ + + + + + diff --git a/examples/with-test/nuxt.config.ts b/examples/with-test/nuxt.config.ts new file mode 100644 index 0000000000..a3e4d68096 --- /dev/null +++ b/examples/with-test/nuxt.config.ts @@ -0,0 +1,4 @@ +import { defineNuxtConfig } from 'nuxt3' + +export default defineNuxtConfig({ +}) diff --git a/examples/with-test/package.json b/examples/with-test/package.json new file mode 100644 index 0000000000..060cc52311 --- /dev/null +++ b/examples/with-test/package.json @@ -0,0 +1,13 @@ +{ + "name": "example-with-test", + "private": true, + "scripts": { + "build": "nuxi build", + "dev": "nuxi dev", + "start": "nuxi preview" + }, + "devDependencies": { + "@nuxt/test-utils": "latest", + "nuxt3": "latest" + } +} diff --git a/examples/with-test/tests/basic.test.ts b/examples/with-test/tests/basic.test.ts new file mode 100644 index 0000000000..97afb12b9b --- /dev/null +++ b/examples/with-test/tests/basic.test.ts @@ -0,0 +1,14 @@ +import { fileURLToPath } from 'url' +import { describe, expect, it } from 'vitest' +import { setup, $fetch } from '@nuxt/test-utils' + +describe('example', async () => { + await setup({ + rootDir: fileURLToPath(new URL('..', import.meta.url)), + server: true + }) + + it('Renders Hello Nuxt', async () => { + expect(await $fetch('/')).toMatch('Hello Nuxt!') + }) +}) diff --git a/examples/with-test/tsconfig.json b/examples/with-test/tsconfig.json new file mode 100644 index 0000000000..4b34df1571 --- /dev/null +++ b/examples/with-test/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "./.nuxt/tsconfig.json" +} diff --git a/package.json b/package.json index 5caa5f6ec3..0ddf400ef5 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "jiti": "^1.13.0", "nitropack-dev": "link:../nitropack", "nuxt3": "workspace:./packages/nuxt3", + "@nuxt/test-utils": "workspace:./packages/test-utils", "vite": "^2.8.6", "unbuild": "^0.7.0" }, diff --git a/packages/nuxi/build.config.ts b/packages/nuxi/build.config.ts index 7a2e98b44c..58ea87d0f9 100644 --- a/packages/nuxi/build.config.ts +++ b/packages/nuxi/build.config.ts @@ -12,8 +12,10 @@ export default defineBuildConfig({ externals: [ '@nuxt/kit', '@nuxt/schema', + '@nuxt/test-utils', 'fsevents', // TODO: Fix rollup/unbuild issue + 'node:url', 'node:buffer', 'node:path', 'node:child_process', diff --git a/packages/nuxi/src/commands/index.ts b/packages/nuxi/src/commands/index.ts index 0d8e3987fe..652a613cf7 100644 --- a/packages/nuxi/src/commands/index.ts +++ b/packages/nuxi/src/commands/index.ts @@ -15,7 +15,8 @@ export const commands = { info: () => import('./info').then(_rDefault), init: () => import('./init').then(_rDefault), create: () => import('./init').then(_rDefault), - upgrade: () => import('./upgrade').then(_rDefault) + upgrade: () => import('./upgrade').then(_rDefault), + test: () => import('./test').then(_rDefault) } export type Command = keyof typeof commands diff --git a/packages/nuxi/src/commands/test.ts b/packages/nuxi/src/commands/test.ts new file mode 100644 index 0000000000..8fdd58af6c --- /dev/null +++ b/packages/nuxi/src/commands/test.ts @@ -0,0 +1,34 @@ +import { resolve } from 'pathe' +import { defineNuxtCommand } from './index' + +export default defineNuxtCommand({ + meta: { + name: 'test', + usage: 'npx nuxi test', + description: 'Run tests' + }, + async invoke (args) { + process.env.NODE_ENV = process.env.NODE_ENV || 'test' + const rootDir = resolve(args._[0] || '.') + const { runTests } = await importTestUtils() + await runTests({ + rootDir + }) + } +}) + +async function importTestUtils (): Promise { + let err + for (const pkg of ['@nuxt/test-utils-edge', '@nuxt/test-utils']) { + try { + const exports = await import(pkg) + // Detect old @nuxt/test-utils + if (!exports.runTests) { + throw new Error('Invalid version of `@nuxt/test-utils` is installed!') + } + return exports + } catch (_err) { err = _err } + } + console.error(err) + throw new Error('`@nuxt/test-utils-edge` seems missing. Run `npm i -D @nuxt/test-utils-edge` or `yarn add -D @nuxt/test-utils-edge` to install.') +} diff --git a/packages/test-utils/src/index.ts b/packages/test-utils/src/index.ts index fda71ddb41..55d9ebae53 100644 --- a/packages/test-utils/src/index.ts +++ b/packages/test-utils/src/index.ts @@ -3,3 +3,4 @@ export * from './context' export * from './nuxt' export * from './server' export * from './setup' +export * from './run' diff --git a/packages/test-utils/src/run.ts b/packages/test-utils/src/run.ts new file mode 100644 index 0000000000..c1ed7c1151 --- /dev/null +++ b/packages/test-utils/src/run.ts @@ -0,0 +1,35 @@ +export interface RunTestOptions { + rootDir: string, + runner?: 'vitest' +} + +const RunTestDefaults: Partial = { + runner: 'vitest' +} + +export async function runTests (opts: RunTestOptions) { + opts = { ...RunTestDefaults, ...opts } + + if (opts.runner !== 'vitest') { + throw new Error(`Unsupported runner: ${opts.runner}. Currently only vitest runner is supported.`) + } + const { startVitest } = await import('vitest/dist/node.js') + const succeeded = await startVitest( + [] /* argv */, + // Vitest options + { + root: opts.rootDir, + run: true + }, + // Vite options + { + esbuild: { + tsconfigRaw: '{}' + } + } + ) + + if (!succeeded) { + process.exit(1) + } +} diff --git a/yarn.lock b/yarn.lock index 48fdf7edb0..c621b88ee3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3194,7 +3194,7 @@ __metadata: languageName: node linkType: hard -"@nuxt/test-utils@workspace:packages/test-utils": +"@nuxt/test-utils@workspace:./packages/test-utils, @nuxt/test-utils@workspace:packages/test-utils": version: 0.0.0-use.local resolution: "@nuxt/test-utils@workspace:packages/test-utils" dependencies: @@ -10557,6 +10557,15 @@ __metadata: languageName: unknown linkType: soft +"example-with-test@workspace:examples/with-test": + version: 0.0.0-use.local + resolution: "example-with-test@workspace:examples/with-test" + dependencies: + "@nuxt/test-utils": latest + nuxt3: latest + languageName: unknown + linkType: soft + "example-with-universal-router@workspace:examples/with-universal-router": version: 0.0.0-use.local resolution: "example-with-universal-router@workspace:examples/with-universal-router"