Skip to content

Commit

Permalink
Run dev tests against default CNA templates (#45211)
Browse files Browse the repository at this point in the history
  • Loading branch information
ijjk committed Jan 24, 2023
1 parent 45a9373 commit f9c1046
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 34 deletions.
4 changes: 3 additions & 1 deletion .github/actions/next-stats-action/src/prepare/repo-setup.js
Expand Up @@ -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(
Expand Down
2 changes: 1 addition & 1 deletion lint-staged.config.js
Expand Up @@ -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(' ')
Expand Down
11 changes: 10 additions & 1 deletion packages/create-next-app/templates/index.ts
Expand Up @@ -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.
*/
Expand Down
5 changes: 4 additions & 1 deletion scripts/test-pack-package.mts
Expand Up @@ -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}'`)
}
Expand Down
11 changes: 10 additions & 1 deletion test/integration/create-next-app/lib/utils.ts
Expand Up @@ -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()

Expand All @@ -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,
},
})
Expand Down
135 changes: 108 additions & 27 deletions test/integration/create-next-app/templates.test.ts
Expand Up @@ -6,6 +6,8 @@
* JavaScript (default), TypeScript, and appDir.
*/

import path from 'path'
import fs from 'fs-extra'
import {
createNextApp,
projectFilesShouldExist,
Expand All @@ -16,13 +18,53 @@ 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) {
it('should skip when env is not set', () => {})
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'
Expand All @@ -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.
Expand All @@ -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.
Expand Down Expand Up @@ -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))
})
})

Expand All @@ -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)

Expand All @@ -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))
})
})

Expand All @@ -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'])
})
})

Expand All @@ -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)

Expand All @@ -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'])
})
})
})
Expand All @@ -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'
Expand All @@ -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))
})
})

Expand All @@ -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'])
})
})

Expand All @@ -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)
Expand All @@ -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'])
})
})
})
3 changes: 2 additions & 1 deletion test/lib/create-next-install.js
Expand Up @@ -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(
Expand Down Expand Up @@ -129,4 +129,5 @@ async function createNextInstall({

module.exports = {
createNextInstall,
getPkgPaths: linkPackages,
}
2 changes: 1 addition & 1 deletion test/lib/next-test-utils.js
Expand Up @@ -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,
Expand Down

0 comments on commit f9c1046

Please sign in to comment.