Run dev tests against default CNA templates (#45211)
This commit is contained in:
parent
45a9373113
commit
f9c10469a2
8 changed files with 139 additions and 34 deletions
|
@ -73,7 +73,9 @@ module.exports = (actionInfo) => {
|
|||
})
|
||||
|
||||
const pkgPaths = new Map()
|
||||
const pkgs = await fs.readdir(path.join(repoDir, 'packages'))
|
||||
const pkgs = (await fs.readdir(path.join(repoDir, 'packages'))).filter(
|
||||
(item) => !item.startsWith('.')
|
||||
)
|
||||
|
||||
pkgs.forEach((pkgDirname) => {
|
||||
const { name } = require(path.join(
|
||||
|
|
|
@ -5,7 +5,7 @@ const eslint = new ESLint()
|
|||
const isWin = process.platform === 'win32'
|
||||
|
||||
module.exports = {
|
||||
'**/*.{js,jsx,ts,tsx}': (filenames) => {
|
||||
'**/*.{js,jsx,mjs,ts,tsx,mts}': (filenames) => {
|
||||
const escapedFileNames = filenames
|
||||
.map((filename) => (isWin ? filename : escape([filename])))
|
||||
.join(' ')
|
||||
|
|
|
@ -70,7 +70,16 @@ export const installTemplate = async ({
|
|||
/**
|
||||
* Default dependencies.
|
||||
*/
|
||||
const dependencies = ['react', 'react-dom', 'next', '@next/font']
|
||||
const dependencies = [
|
||||
'react',
|
||||
'react-dom',
|
||||
`next${
|
||||
process.env.NEXT_PRIVATE_TEST_VERSION
|
||||
? `@${process.env.NEXT_PRIVATE_TEST_VERSION}`
|
||||
: ''
|
||||
}`,
|
||||
'@next/font',
|
||||
]
|
||||
/**
|
||||
* TypeScript projects will have type definitions and other devDependencies.
|
||||
*/
|
||||
|
|
|
@ -16,7 +16,10 @@ const main = async () => {
|
|||
const getPackageJsonPath = (pkgDirname: string) =>
|
||||
path.join(pkgsDir, pkgDirname, `package.json`)
|
||||
|
||||
const allPkgDirnames = await fs.readdir(pkgsDir)
|
||||
const allPkgDirnames = (await fs.readdir(pkgsDir)).filter(
|
||||
(item) => !item.startsWith('.')
|
||||
)
|
||||
|
||||
if (!allPkgDirnames.includes(currentPkgDirname)) {
|
||||
throw new Error(`Unknown package '${currentPkgDirname}'`)
|
||||
}
|
||||
|
|
|
@ -22,7 +22,11 @@ const cli = require.resolve('create-next-app/dist/index.js')
|
|||
/**
|
||||
* Run the built version of `create-next-app` with the given arguments.
|
||||
*/
|
||||
export const createNextApp = (args: string[], options?: SpawnOptions) => {
|
||||
export const createNextApp = (
|
||||
args: string[],
|
||||
options?: SpawnOptions,
|
||||
testVersion?: string
|
||||
) => {
|
||||
const conf = new Conf({ projectName: 'create-next-app' })
|
||||
conf.clear()
|
||||
|
||||
|
@ -39,6 +43,11 @@ export const createNextApp = (args: string[], options?: SpawnOptions) => {
|
|||
CONTINUOUS_INTEGRATION: '',
|
||||
RUN_ID: '',
|
||||
BUILD_NUMBER: '',
|
||||
...(testVersion
|
||||
? {
|
||||
NEXT_PRIVATE_TEST_VERSION: testVersion,
|
||||
}
|
||||
: {}),
|
||||
...options.env,
|
||||
},
|
||||
})
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
* JavaScript (default), TypeScript, and appDir.
|
||||
*/
|
||||
|
||||
import path from 'path'
|
||||
import fs from 'fs-extra'
|
||||
import {
|
||||
createNextApp,
|
||||
projectFilesShouldExist,
|
||||
|
@ -16,6 +18,37 @@ import {
|
|||
} from './lib/utils'
|
||||
|
||||
import { useTempDir } from '../../../test/lib/use-temp-dir'
|
||||
import { fetchViaHTTP, findPort, killApp, launchApp } from 'next-test-utils'
|
||||
import resolveFrom from 'resolve-from'
|
||||
import { getPkgPaths } from '../../../test/lib/create-next-install'
|
||||
|
||||
const startsWithoutError = async (
|
||||
appDir: string,
|
||||
modes = ['default', 'turbo']
|
||||
) => {
|
||||
for (const mode of modes) {
|
||||
appDir = await fs.realpath(appDir)
|
||||
const appPort = await findPort()
|
||||
const app = await launchApp(appDir, appPort, {
|
||||
turbo: mode === 'turbo',
|
||||
cwd: appDir,
|
||||
nextBin: resolveFrom(appDir, 'next/dist/bin/next'),
|
||||
})
|
||||
|
||||
try {
|
||||
const res = await fetchViaHTTP(appPort, '/')
|
||||
expect(res.status).toBe(200)
|
||||
expect(await res.text()).toContain('Get started by editing')
|
||||
|
||||
const apiRes = await fetchViaHTTP(appPort, '/api/hello')
|
||||
expect(apiRes.status).toBe(200)
|
||||
expect(await apiRes.json()).toEqual({ name: 'John Doe' })
|
||||
} finally {
|
||||
await killApp(app)
|
||||
}
|
||||
}
|
||||
}
|
||||
let testVersion
|
||||
|
||||
describe('create-next-app templates', () => {
|
||||
if (!process.env.NEXT_TEST_CNA) {
|
||||
|
@ -23,6 +56,15 @@ describe('create-next-app templates', () => {
|
|||
return
|
||||
}
|
||||
|
||||
beforeAll(async () => {
|
||||
testVersion = (
|
||||
await getPkgPaths({
|
||||
repoDir: path.join(__dirname, '../../../'),
|
||||
nextSwcVersion: '',
|
||||
})
|
||||
).get('next')
|
||||
})
|
||||
|
||||
it('should prompt user to choose if --ts or --js is not provided', async () => {
|
||||
useTempDir(async (cwd) => {
|
||||
const projectName = 'choose-ts-js'
|
||||
|
@ -36,9 +78,12 @@ describe('create-next-app templates', () => {
|
|||
'--eslint',
|
||||
'--no-src-dir',
|
||||
'--no-experimental-app',
|
||||
`--import-alias="@/*"`,
|
||||
`--import-alias=@/*`,
|
||||
],
|
||||
{ cwd }
|
||||
{
|
||||
cwd,
|
||||
},
|
||||
testVersion
|
||||
)
|
||||
/**
|
||||
* Wait for the prompt to display.
|
||||
|
@ -47,8 +92,8 @@ describe('create-next-app templates', () => {
|
|||
/**
|
||||
* Bind the exit listener.
|
||||
*/
|
||||
await new Promise<void>((resolve) => {
|
||||
childProcess.on('exit', (exitCode) => {
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
childProcess.on('exit', async (exitCode) => {
|
||||
expect(exitCode).toBe(0)
|
||||
/**
|
||||
* Verify it correctly emitted a TS project by looking for tsconfig.
|
||||
|
@ -78,16 +123,19 @@ describe('create-next-app templates', () => {
|
|||
'--eslint',
|
||||
'--no-src-dir',
|
||||
'--no-experimental-app',
|
||||
`--import-alias="@/*"`,
|
||||
`--import-alias=@/*`,
|
||||
],
|
||||
{
|
||||
cwd,
|
||||
}
|
||||
},
|
||||
testVersion
|
||||
)
|
||||
const exitCode = await spawnExitPromise(childProcess)
|
||||
|
||||
expect(exitCode).toBe(0)
|
||||
shouldBeTypescriptProject({ cwd, projectName, template: 'default' })
|
||||
|
||||
await startsWithoutError(path.join(cwd, projectName))
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -101,11 +149,12 @@ describe('create-next-app templates', () => {
|
|||
'--eslint',
|
||||
'--src-dir',
|
||||
'--no-experimental-app',
|
||||
`--import-alias="@/*"`,
|
||||
`--import-alias=@/*`,
|
||||
],
|
||||
{
|
||||
cwd,
|
||||
}
|
||||
},
|
||||
testVersion
|
||||
)
|
||||
const exitCode = await spawnExitPromise(childProcess)
|
||||
|
||||
|
@ -116,24 +165,30 @@ describe('create-next-app templates', () => {
|
|||
template: 'default',
|
||||
srcDir: true,
|
||||
})
|
||||
await startsWithoutError(path.join(cwd, projectName))
|
||||
})
|
||||
})
|
||||
|
||||
it('should create TS projects with --ts, --typescript with CI=1', async () => {
|
||||
await useTempDir(async (cwd) => {
|
||||
const projectName = 'typescript-test'
|
||||
const childProcess = createNextApp([projectName, '--ts', '--eslint'], {
|
||||
cwd,
|
||||
env: {
|
||||
...process.env,
|
||||
CI: '1',
|
||||
GITHUB_ACTIONS: '1',
|
||||
const childProcess = createNextApp(
|
||||
[projectName, '--ts', '--eslint'],
|
||||
{
|
||||
cwd,
|
||||
env: {
|
||||
...process.env,
|
||||
CI: '1',
|
||||
GITHUB_ACTIONS: '1',
|
||||
},
|
||||
},
|
||||
})
|
||||
testVersion
|
||||
)
|
||||
const exitCode = await spawnExitPromise(childProcess)
|
||||
|
||||
expect(exitCode).toBe(0)
|
||||
shouldBeTypescriptProject({ cwd, projectName, template: 'default' })
|
||||
await startsWithoutError(path.join(cwd, projectName))
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -147,16 +202,20 @@ describe('create-next-app templates', () => {
|
|||
'--eslint',
|
||||
'--no-src-dir',
|
||||
'--no-experimental-app',
|
||||
`--import-alias="@/*"`,
|
||||
`--import-alias=@/*`,
|
||||
],
|
||||
{
|
||||
cwd,
|
||||
}
|
||||
},
|
||||
testVersion
|
||||
)
|
||||
const exitCode = await spawnExitPromise(childProcess)
|
||||
|
||||
expect(exitCode).toBe(0)
|
||||
shouldBeJavascriptProject({ cwd, projectName, template: 'default' })
|
||||
// TODO: enable turbo mode as well once jsconfig paths support
|
||||
// is landed
|
||||
await startsWithoutError(path.join(cwd, projectName), ['default'])
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -170,11 +229,12 @@ describe('create-next-app templates', () => {
|
|||
'--eslint',
|
||||
'--src-dir',
|
||||
'--no-experimental-app',
|
||||
`--import-alias="@/*"`,
|
||||
`--import-alias=@/*`,
|
||||
],
|
||||
{
|
||||
cwd,
|
||||
}
|
||||
},
|
||||
testVersion
|
||||
)
|
||||
const exitCode = await spawnExitPromise(childProcess)
|
||||
|
||||
|
@ -185,6 +245,9 @@ describe('create-next-app templates', () => {
|
|||
template: 'default',
|
||||
srcDir: true,
|
||||
})
|
||||
// TODO: enable turbo mode as well once jsconfig paths support
|
||||
// is landed
|
||||
await startsWithoutError(path.join(cwd, projectName), ['default'])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -195,6 +258,16 @@ describe('create-next-app --experimental-app-dir', () => {
|
|||
return
|
||||
}
|
||||
|
||||
beforeAll(async () => {
|
||||
if (testVersion) return
|
||||
testVersion = (
|
||||
await getPkgPaths({
|
||||
repoDir: path.join(__dirname, '../../../'),
|
||||
nextSwcVersion: '',
|
||||
})
|
||||
).get('next')
|
||||
})
|
||||
|
||||
it('should create TS appDir projects with --ts', async () => {
|
||||
await useTempDir(async (cwd) => {
|
||||
const projectName = 'appdir-test'
|
||||
|
@ -205,17 +278,18 @@ describe('create-next-app --experimental-app-dir', () => {
|
|||
'--experimental-app',
|
||||
'--eslint',
|
||||
'--no-src-dir',
|
||||
'--no-experimental-app',
|
||||
`--import-alias="@/*"`,
|
||||
`--import-alias=@/*`,
|
||||
],
|
||||
{
|
||||
cwd,
|
||||
}
|
||||
},
|
||||
testVersion
|
||||
)
|
||||
|
||||
const exitCode = await spawnExitPromise(childProcess)
|
||||
expect(exitCode).toBe(0)
|
||||
shouldBeTemplateProject({ cwd, projectName, template: 'app', mode: 'ts' })
|
||||
await startsWithoutError(path.join(cwd, projectName))
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -229,17 +303,20 @@ describe('create-next-app --experimental-app-dir', () => {
|
|||
'--experimental-app',
|
||||
'--eslint',
|
||||
'--no-src-dir',
|
||||
'--no-experimental-app',
|
||||
`--import-alias="@/*"`,
|
||||
`--import-alias=@/*`,
|
||||
],
|
||||
{
|
||||
cwd,
|
||||
}
|
||||
},
|
||||
testVersion
|
||||
)
|
||||
|
||||
const exitCode = await spawnExitPromise(childProcess)
|
||||
expect(exitCode).toBe(0)
|
||||
shouldBeTemplateProject({ cwd, projectName, template: 'app', mode: 'js' })
|
||||
// TODO: enable turbo mode as well once jsconfig paths support
|
||||
// is landed
|
||||
await startsWithoutError(path.join(cwd, projectName), ['default'])
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -253,12 +330,13 @@ describe('create-next-app --experimental-app-dir', () => {
|
|||
'--experimental-app',
|
||||
'--eslint',
|
||||
'--src-dir',
|
||||
'--import-alias="@/*"',
|
||||
'--import-alias=@/*',
|
||||
],
|
||||
{
|
||||
cwd,
|
||||
stdio: 'inherit',
|
||||
}
|
||||
},
|
||||
testVersion
|
||||
)
|
||||
|
||||
const exitCode = await spawnExitPromise(childProcess)
|
||||
|
@ -270,6 +348,9 @@ describe('create-next-app --experimental-app-dir', () => {
|
|||
mode: 'js',
|
||||
srcDir: true,
|
||||
})
|
||||
// TODO: enable turbo mode as well once jsconfig paths support
|
||||
// is landed
|
||||
await startsWithoutError(path.join(cwd, projectName), ['default'])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -27,7 +27,7 @@ async function createNextInstall({
|
|||
require('console').log('Creating next instance in:')
|
||||
require('console').log(installDir)
|
||||
|
||||
await rootSpan.traceChild(' enruse swc binary').traceAsyncFn(async () => {
|
||||
await rootSpan.traceChild('ensure swc binary').traceAsyncFn(async () => {
|
||||
// ensure swc binary is present in the native folder if
|
||||
// not already built
|
||||
for (const folder of await fs.readdir(
|
||||
|
@ -129,4 +129,5 @@ async function createNextInstall({
|
|||
|
||||
module.exports = {
|
||||
createNextInstall,
|
||||
getPkgPaths: linkPackages,
|
||||
}
|
||||
|
|
|
@ -283,7 +283,7 @@ export function runNextCommand(argv, options = {}) {
|
|||
|
||||
export function runNextCommandDev(argv, stdOut, opts = {}) {
|
||||
const nextDir = path.dirname(require.resolve('next/package'))
|
||||
const nextBin = path.join(nextDir, 'dist/bin/next')
|
||||
const nextBin = opts.nextBin || path.join(nextDir, 'dist/bin/next')
|
||||
const cwd = opts.cwd || nextDir
|
||||
const env = {
|
||||
...process.env,
|
||||
|
|
Loading…
Reference in a new issue