Skip to content

Commit

Permalink
chore: improve helpers to test vite-node (#3842)
Browse files Browse the repository at this point in the history
  • Loading branch information
sheremet-va committed Jul 29, 2023
1 parent 103ad7c commit 54409a2
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 41 deletions.
3 changes: 2 additions & 1 deletion packages/vite-node/package.json
Expand Up @@ -45,7 +45,8 @@
"types": "./dist/source-map.d.ts",
"require": "./dist/source-map.cjs",
"import": "./dist/source-map.mjs"
}
},
"./*": "./*"
},
"main": "./dist/index.mjs",
"module": "./dist/index.mjs",
Expand Down
6 changes: 6 additions & 0 deletions packages/vite-node/src/hmr/emitter.ts
Expand Up @@ -37,6 +37,12 @@ export function viteNodeHmrPlugin(): Plugin {
_send(payload)
emitter.emit('message', payload)
}
if (process.env.VITE_NODE_WATCHER_DEBUG) {
server.watcher.on('ready', () => {
// eslint-disable-next-line no-console
console.log('[vie-node] watcher is ready')
})
}
},
}
}
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 36 additions & 4 deletions test/test-utils/index.ts
@@ -1,5 +1,6 @@
import { Console } from 'node:console'
import { Writable } from 'node:stream'
import fs from 'node:fs'
import { type UserConfig, type VitestRunMode, afterEach } from 'vitest'
import type { Vitest } from 'vitest/node'
import { startVitest } from 'vitest/node'
Expand Down Expand Up @@ -86,15 +87,15 @@ function captureLogs() {
}
}

export async function runVitestCli(_options?: Options | string, ...args: string[]) {
export async function runCli(command: string, _options?: Options | string, ...args: string[]) {
let options = _options

if (typeof _options === 'string') {
args.unshift(_options)
options = undefined
}

const subprocess = execa('vitest', args, options as Options)
const subprocess = execa(command, args, options as Options)

let setDone: (value?: unknown) => void
const isDone = new Promise(resolve => (setDone = resolve))
Expand All @@ -115,7 +116,7 @@ export async function runVitestCli(_options?: Options | string, ...args: string[
return resolve()

const timeout = setTimeout(() => {
reject(new Error(`Timeout when waiting for output "${expected}".\nReceived:\n${this.stdout}. \nStderr:\n${this.stderr}`))
reject(new Error(`Timeout when waiting for output "${expected}".\nReceived:\n${this.stdout} \nStderr:\n${this.stderr}`))
}, process.env.CI ? 20_000 : 4_000)

const listener = () => {
Expand All @@ -136,7 +137,7 @@ export async function runVitestCli(_options?: Options | string, ...args: string[
return resolve()

const timeout = setTimeout(() => {
reject(new Error(`Timeout when waiting for error "${expected}".\nReceived:\n${this.stderr}`))
reject(new Error(`Timeout when waiting for error "${expected}".\nReceived:\n${this.stderr}\nStdout:\n${this.stdout}`))
}, process.env.CI ? 20_000 : 4_000)

const listener = () => {
Expand Down Expand Up @@ -177,6 +178,14 @@ export async function runVitestCli(_options?: Options | string, ...args: string[
await vitest.isDone
})

if (command !== 'vitest') {
if (!args.includes('--watch'))
await vitest.isDone
else
await vitest.waitForStdout('[vie-node] watcher is ready')
return vitest
}

if (args.includes('--watch')) { // Wait for initial test run to complete
await vitest.waitForStdout('Waiting for file changes')
vitest.resetOutput()
Expand All @@ -187,3 +196,26 @@ export async function runVitestCli(_options?: Options | string, ...args: string[

return vitest
}

export async function runVitestCli(_options?: Options | string, ...args: string[]) {
return runCli('vitest', _options, ...args)
}

export async function runViteNodeCli(_options?: Options | string, ...args: string[]) {
process.env.VITE_NODE_WATCHER_DEBUG = 'true'
return runCli('vite-node', _options, ...args)
}

const originalFiles = new Map<string, string>()
afterEach(() => {
originalFiles.forEach((content, file) => {
fs.writeFileSync(file, content, 'utf-8')
})
})

export function editFile(file: string, callback: (content: string) => string) {
const content = fs.readFileSync(file, 'utf-8')
if (!originalFiles.has(file))
originalFiles.set(file, content)
fs.writeFileSync(file, callback(content), 'utf-8')
}
1 change: 1 addition & 0 deletions test/test-utils/package.json
Expand Up @@ -8,6 +8,7 @@
"execa": "^7.1.1",
"strip-ansi": "^7.0.1",
"vite": "latest",
"vite-node": "workspace:*",
"vitest": "workspace:*"
}
}
2 changes: 2 additions & 0 deletions test/vite-node/src/watched.js
@@ -0,0 +1,2 @@
// eslint-disable-next-line no-console
console.log('test 1')
12 changes: 5 additions & 7 deletions test/vite-node/test/circular.test.ts
@@ -1,17 +1,15 @@
import { expect, test } from 'vitest'
import { execa } from 'execa'
import { resolve } from 'pathe'

const cliPath = resolve(__dirname, '../../../packages/vite-node/src/cli.ts')
import { runViteNodeCli } from '../../test-utils'

test('circular 1', async () => {
const entryPath = resolve(__dirname, '../src/circular1/index.ts')
const result = await execa('npx', ['esno', cliPath, entryPath], { reject: true })
expect(result.stdout).toMatchInlineSnapshot('"A Bindex index"')
const cli = await runViteNodeCli(entryPath)
expect(cli.stdout).toContain('A Bindex index')
}, 60_000)

test('circular 2', async () => {
const entryPath = resolve(__dirname, '../src/circular2/index.ts')
const result = await execa('npx', ['esno', cliPath, entryPath], { reject: true })
expect(result.stdout).toMatchInlineSnapshot('"ac b"')
const cli = await runViteNodeCli(entryPath)
expect(cli.stdout).toContain('ac b')
}, 60_000)
54 changes: 32 additions & 22 deletions test/vite-node/test/cli.test.ts
@@ -1,38 +1,48 @@
import { execa } from 'execa'
import { resolve } from 'pathe'
import pkg from 'vite-node/package.json'
import { expect, it } from 'vitest'
import { editFile, runViteNodeCli } from '../../test-utils'

const cliPath = resolve(__dirname, '../../../packages/vite-node/src/cli.ts')
const entryPath = resolve(__dirname, '../src/cli-parse-args.js')

const version = (pkg as any).version

const parseResult = (s: string) => JSON.parse(s.replaceAll('\'', '"'))

it('basic', async () => {
const result = await execa('npx', ['esno', cliPath, entryPath], { reject: true })
expect(result.stdout).include('node')
expect(parseResult(result.stdout)).length(2)
}, 60_000)
const cli = await runViteNodeCli(entryPath)
expect(cli.stdout).toContain('node')
expect(parseResult(cli.stdout)).toHaveLength(2)
})

it('--help', async () => {
const r1 = await execa('npx', ['esno', cliPath, '--help', entryPath], { reject: true })
expect(r1.stdout).include('help')
const r2 = await execa('npx', ['esno', cliPath, '-h', entryPath], { reject: true })
expect(r2.stdout).include('help')
}, 60_000)
const cli1 = await runViteNodeCli('--help', entryPath)
expect(cli1.stdout).toContain('Usage:')
const cli2 = await runViteNodeCli('-h', entryPath)
expect(cli2.stdout).toContain('Usage:')
})

it('--version', async () => {
const r1 = await execa('npx', ['esno', cliPath, '--version', entryPath], { reject: true })
expect(r1.stdout).include('vite-node/')
const r2 = await execa('npx', ['esno', cliPath, '-v', entryPath], { reject: true })
expect(r2.stdout).include('vite-node/')
}, 60_000)
const cli1 = await runViteNodeCli('--version', entryPath)
expect(cli1.stdout).toContain(`vite-node/${version}`)
const cli2 = await runViteNodeCli('-v', entryPath)
expect(cli2.stdout).toContain(`vite-node/${version}`)
})

it('script args', async () => {
const r1 = await execa('npx', ['esno', cliPath, entryPath, '--version', '--help'], { reject: true })
expect(parseResult(r1.stdout)).include('--version').include('--help')
}, 60_000)
const cli1 = await runViteNodeCli(entryPath, '--version', '--help')
expect(parseResult(cli1.stdout)).include('--version').include('--help')
})

it('script args in -- after', async () => {
const r1 = await execa('npx', ['esno', cliPath, entryPath, '--', '--version', '--help'], { reject: true })
expect(parseResult(r1.stdout)).include('--version').include('--help')
}, 60_000)
const cli1 = await runViteNodeCli(entryPath, '--', '--version', '--help')
expect(parseResult(cli1.stdout)).include('--version').include('--help')
})

it('correctly runs --watch', async () => {
const entryPath = resolve(__dirname, '../src/watched.js')
const cli = await runViteNodeCli('--watch', entryPath)
await cli.waitForStdout('test 1')
editFile(entryPath, c => c.replace('test 1', 'test 2'))
await cli.waitForStdout('test 2')
})
12 changes: 5 additions & 7 deletions test/vite-node/test/self-export.test.ts
@@ -1,24 +1,22 @@
import { expect, it } from 'vitest'
import { execa } from 'execa'
import { resolve } from 'pathe'
import ansiEscapes, { HelloWorld } from '../src/self-export'
import { runViteNodeCli } from '../../test-utils'

it('should export self', () => {
expect(ansiEscapes.HelloWorld).eq(HelloWorld)
expect(Reflect.get(ansiEscapes, 'default').HelloWorld).eq(HelloWorld)
expect(HelloWorld).eq(1)
})

const cliPath = resolve(__dirname, '../../../packages/vite-node/src/cli.ts')

it('example 1', async () => {
const entryPath = resolve(__dirname, '../src/self-export-example1.ts')
const result = await execa('npx', ['esno', cliPath, entryPath], { reject: true })
expect(result.stdout).includes('Function')
const cli = await runViteNodeCli(entryPath)
await cli.waitForStdout('Function')
}, 60_000)

it('example 2', async () => {
const entryPath = resolve(__dirname, '../src/self-export-example2.ts')
const result = await execa('npx', ['esno', cliPath, entryPath], { reject: true })
expect(result.stdout).includes('HelloWorld: 1').includes('default')
const cli = await runViteNodeCli(entryPath)
await cli.waitForStdout('HelloWorld: 1')
}, 60_000)

0 comments on commit 54409a2

Please sign in to comment.