Skip to content

Commit 6ff5c36

Browse files
committed
fix(test): resolve test utils from project
1 parent 00b2828 commit 6ff5c36

3 files changed

Lines changed: 83 additions & 28 deletions

File tree

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
importprocessfrom'node:process'
2+
import{pathToFileURL}from'node:url'
23

34
import{defineCommand}from'citty'
4-
5-
import{logger}from'../utils/logger'
5+
import{resolveModulePath}from'exsolve'
66

77
import{resolveRootDir}from'../utils/paths'
8-
import{logLevelArgs,rootDirArgs}from'./_shared'
8+
import{rootDirArgs}from'./_shared'
99

1010
exportdefaultdefineCommand({
1111
meta: {
@@ -14,7 +14,6 @@ export default defineCommand({
1414
},
1515
args: {
1616
...rootDirArgs,
17-
...logLevelArgs,
1817
dev: {
1918
type: 'boolean',
2019
description: 'Run in dev mode',
@@ -29,35 +28,28 @@ export default defineCommand({
2928

3029
constcwd=resolveRootDir(ctx.args)
3130

32-
const{ runTests }=awaitimportTestUtils()
31+
const{ runTests }=awaitimportTestUtils(cwd)
3332
awaitrunTests({
3433
rootDir: cwd,
3534
dev: ctx.args.dev,
3635
watch: ctx.args.watch,
37-
...{},
3836
})
3937
},
4038
})
4139

42-
asyncfunctionimportTestUtils(): Promise<typeofimport('@nuxt/test-utils')>{
43-
leterr
44-
for(constpkgof[
45-
'@nuxt/test-utils-nightly',
46-
'@nuxt/test-utils-edge',
47-
'@nuxt/test-utils',
48-
]){
49-
try{
50-
constexports=awaitimport(pkg)
51-
// Detect old @nuxt/test-utils
52-
if(!exports.runTests){
53-
thrownewError('Invalid version of `@nuxt/test-utils` is installed!')
54-
}
55-
returnexports
40+
exportasyncfunctionimportTestUtils(rootDir: string): Promise<typeofimport('@nuxt/test-utils')>{
41+
for(constpkgof['@nuxt/test-utils-nightly','@nuxt/test-utils-edge','@nuxt/test-utils']){
42+
constentry=resolveModulePath(pkg,{from: rootDir,try: true})
43+
if(!entry){
44+
continue
5645
}
57-
catch(_err){
58-
err=_err
46+
47+
constexports=awaitimport(pathToFileURL(entry).href)
48+
if(typeofexports.runTests!=='function'){
49+
thrownewTypeError(`The installed version of \`${pkg}\` does not support \`nuxt test\`.`)
5950
}
51+
returnexports
6052
}
61-
logger.error(String(err))
62-
thrownewError('`@nuxt/test-utils` seems missing. Run `npm i -D @nuxt/test-utils` or `yarn add -D @nuxt/test-utils` to install.')
53+
54+
thrownewError('`@nuxt/test-utils` is not installed in this project. Install it as a development dependency to use `nuxt test`.')
6355
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import{mkdir,rm,writeFile}from'node:fs/promises'
2+
import{tmpdir}from'node:os'
3+
import{join}from'node:path'
4+
5+
import{afterEach,describe,expect,it}from'vitest'
6+
7+
import{importTestUtils}from'../../../src/commands/test'
8+
9+
consttempDirs: string[]=[]
10+
11+
asyncfunctioncreateProject(packageName?: string,source='export function runTests() {}'){
12+
constrootDir=join(tmpdir(),`nuxt-test-command-${crypto.randomUUID()}`)
13+
tempDirs.push(rootDir)
14+
awaitmkdir(rootDir,{recursive: true})
15+
16+
if(packageName){
17+
constpackageDir=join(rootDir,'node_modules', ...packageName.split('/'))
18+
awaitmkdir(packageDir,{recursive: true})
19+
awaitwriteFile(join(packageDir,'package.json'),JSON.stringify({name: packageName,type: 'module',exports: './index.js'}))
20+
awaitwriteFile(join(packageDir,'index.js'),source)
21+
}
22+
23+
returnrootDir
24+
}
25+
26+
afterEach(async()=>{
27+
awaitPromise.all(tempDirs.splice(0).map(dir=>rm(dir,{recursive: true,force: true})))
28+
})
29+
30+
describe('importTestUtils',()=>{
31+
it('loads test utils from the project',async()=>{
32+
constrootDir=awaitcreateProject('@nuxt/test-utils')
33+
34+
expect((awaitimportTestUtils(rootDir)).runTests).toBeTypeOf('function')
35+
})
36+
37+
it('prefers nightly when multiple variants are installed',async()=>{
38+
constrootDir=awaitcreateProject('@nuxt/test-utils-nightly','export function runTests() {}; export const channel = "nightly"')
39+
constpackageDir=join(rootDir,'node_modules','@nuxt','test-utils')
40+
awaitmkdir(packageDir,{recursive: true})
41+
awaitwriteFile(join(packageDir,'package.json'),JSON.stringify({name: '@nuxt/test-utils',type: 'module',exports: './index.js'}))
42+
awaitwriteFile(join(packageDir,'index.js'),'export function runTests() {}; export const channel = "stable"')
43+
44+
expect((awaitimportTestUtils(rootDir)asany).channel).toBe('nightly')
45+
})
46+
47+
it('does not fall back when an installed variant fails to load',async()=>{
48+
constrootDir=awaitcreateProject('@nuxt/test-utils-nightly','import "missing-dependency"; export function runTests() {}')
49+
50+
awaitexpect(importTestUtils(rootDir)).rejects.toThrow(/missing-dependency/)
51+
})
52+
53+
it('reports an incompatible installed version',async()=>{
54+
constrootDir=awaitcreateProject('@nuxt/test-utils','export const setup = true')
55+
56+
awaitexpect(importTestUtils(rootDir)).rejects.toThrow('The installed version of `@nuxt/test-utils` does not support `nuxt test`.')
57+
})
58+
59+
it('reports a missing project dependency',async()=>{
60+
constrootDir=awaitcreateProject()
61+
62+
awaitexpect(importTestUtils(rootDir)).rejects.toThrow('`@nuxt/test-utils` is not installed in this project.')
63+
})
64+
})

‎packages/nuxt-cli/test/unit/help.spec.ts‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ describe('help', () => {
369369
})
370370

371371
it('nuxt test',async()=>{
372-
expect(awaitusage(commands.test,main)).toMatchInlineSnapshot(`
372+
expect((awaitusage(commands.test,main)).replaceAll(/+$/gm,'')).toMatchInlineSnapshot(`
373373
"Run tests (nuxt test v0.0.0)
374374
375375
USAGE nuxt test [OPTIONS] [ROOTDIR]
@@ -380,9 +380,8 @@ describe('help', () => {
380380
381381
OPTIONS
382382
383-
--logLevel=<silent|info|verbose> Specify build-time log level
384-
--dev Run in dev mode
385-
--watch Watch mode
383+
--dev Run in dev mode
384+
--watch Watch mode
386385
"
387386
`)
388387
})

0 commit comments

Comments
 (0)