Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: prompt user if no
--js, --ts
flag provided
- Loading branch information
Showing
6 changed files
with
254 additions
and
122 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/** | ||
* Files common to all Next.js templates. | ||
*/ | ||
export const allProjectFiles = [ | ||
'package.json', | ||
'.eslintrc.json', | ||
'node_modules/next', | ||
'.gitignore', | ||
] | ||
|
||
/** | ||
* Files specific to Next.js JS-only templates. | ||
*/ | ||
export const jsProjectFiles = [ | ||
'pages/index.js', | ||
'pages/_app.js', | ||
'pages/api/hello.js', | ||
] | ||
|
||
/** | ||
* Files specific to Next.js TypeScript-only templates. | ||
*/ | ||
export const tsProjectFiles = [ | ||
'pages/index.tsx', | ||
'pages/_app.tsx', | ||
'pages/api/hello.ts', | ||
'tsconfig.json', | ||
'next-env.d.ts', | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
/** | ||
* @fileoverview | ||
* | ||
* This file contains utilities for `create-next-app` testing. | ||
*/ | ||
|
||
import { ChildProcess, spawn, SpawnOptions } from 'child_process' | ||
import { existsSync } from 'fs' | ||
import { resolve } from 'path' | ||
|
||
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) => { | ||
console.log(`[TEST] $ ${cli} ${args.join(' ')}`, { options }) | ||
return spawn('node', [cli].concat(args), options ?? {}) | ||
} | ||
|
||
/** | ||
* Return a Promise that resolves when the process exits with code 0 and rejects | ||
* otherwise. | ||
*/ | ||
export const spawnExitPromise = (childProcess: ChildProcess) => { | ||
return new Promise((resolve, reject) => { | ||
childProcess | ||
.on('exit', (code) => { | ||
if (code === 0) { | ||
resolve(code) | ||
} else { | ||
reject(code) | ||
} | ||
}) | ||
.on('error', reject) | ||
}) | ||
} | ||
|
||
export const projectFilesShouldExist = ( | ||
projectRoot: string, | ||
files: string[] | ||
) => { | ||
for (const file of files) { | ||
expect(existsSync(resolve(projectRoot, file))).toBe(true) | ||
} | ||
} | ||
|
||
export const projectFilesShouldntExist = ( | ||
projectRoot: string, | ||
files: string[] | ||
) => { | ||
for (const file of files) { | ||
expect(existsSync(resolve(projectRoot, file))).toBe(false) | ||
} | ||
} | ||
|
||
export const projectDepsShouldBe = ( | ||
projectRoot: string, | ||
depType: 'dependencies' | 'devDependencies', | ||
value: any | ||
) => { | ||
const pkgJson = require(resolve(projectRoot, 'package.json')) | ||
expect(Object.keys(pkgJson[depType])).toEqual(value) | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
/* eslint-env jest */ | ||
|
||
import { resolve } from 'path' | ||
import { | ||
createNextApp, | ||
projectDepsShouldBe, | ||
projectFilesShouldExist, | ||
projectFilesShouldntExist, | ||
spawnExitPromise, | ||
} from './lib/utils' | ||
import { | ||
allProjectFiles, | ||
jsProjectFiles, | ||
tsProjectFiles, | ||
} from './lib/projectFiles' | ||
|
||
import { useTempDir } from '../../../test/lib/use-temp-dir' | ||
|
||
describe('create-next-app templates', () => { | ||
it('should prompt user to choose if --ts or --js is not provided', async () => { | ||
useTempDir(async (cwd) => { | ||
const projectName = 'choose-ts-js' | ||
const projectRoot = resolve(cwd, projectName) | ||
|
||
/** | ||
* Start the create-next-app call. | ||
*/ | ||
const childProcess = createNextApp([projectName], { cwd }) | ||
/** | ||
* Wait for the prompt to display. | ||
*/ | ||
// await new Promise((resolve) => setTimeout(resolve, 1000)); | ||
/** | ||
* Bind the exit listener. | ||
*/ | ||
childProcess.on('exit', (exitCode) => { | ||
expect(exitCode).toBe(0) | ||
/** | ||
* Verify it correctly emitted a TS project by looking for tsconfig. | ||
*/ | ||
projectFilesShouldntExist(projectRoot, ['tsconfig.json']) | ||
}) | ||
/** | ||
* Simulate "Y" for TypeScript. | ||
*/ | ||
childProcess.stdin.write('N\n') | ||
}) | ||
}) | ||
|
||
it('should create TS projects with --ts, --typescript', async () => { | ||
await useTempDir(async (cwd) => { | ||
const projectName = 'typescript-test' | ||
const projectRoot = resolve(cwd, projectName) | ||
|
||
const childProcess = createNextApp([projectName, '--ts'], { cwd }) | ||
const exitCode = await spawnExitPromise(childProcess) | ||
expect(exitCode).toBe(0) | ||
|
||
projectFilesShouldntExist(projectRoot, jsProjectFiles) | ||
projectFilesShouldExist(projectRoot, [ | ||
...allProjectFiles, | ||
...tsProjectFiles, | ||
]) | ||
|
||
projectDepsShouldBe(projectRoot, 'dependencies', [ | ||
'next', | ||
'react', | ||
'react-dom', | ||
]) | ||
|
||
projectDepsShouldBe(projectRoot, 'devDependencies', [ | ||
'@types/node', | ||
'@types/react', | ||
'@types/react-dom', | ||
'eslint', | ||
'eslint-config-next', | ||
'typescript', | ||
]) | ||
}) | ||
}) | ||
|
||
it('should create JS projects with --js, --javascript', async () => { | ||
await useTempDir(async (cwd) => { | ||
const projectName = 'javascript-test' | ||
const projectRoot = resolve(cwd, projectName) | ||
|
||
const childProcess = createNextApp([projectName, '--js'], { cwd }) | ||
const exitCode = await spawnExitPromise(childProcess) | ||
expect(exitCode).toBe(0) | ||
|
||
projectFilesShouldntExist(projectRoot, tsProjectFiles) | ||
projectFilesShouldExist(projectRoot, [ | ||
...allProjectFiles, | ||
...jsProjectFiles, | ||
]) | ||
|
||
projectDepsShouldBe(projectRoot, 'dependencies', [ | ||
'next', | ||
'react', | ||
'react-dom', | ||
]) | ||
|
||
projectDepsShouldBe(projectRoot, 'devDependencies', [ | ||
'eslint', | ||
'eslint-config-next', | ||
]) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import fs from 'fs-extra' | ||
import os from 'os' | ||
import path from 'path' | ||
|
||
/** | ||
* Create a temporary directory and run a callback function inside it, deleting | ||
* it when finished. | ||
*/ | ||
export async function useTempDir(fn: (folder: string) => void | Promise<void>) { | ||
const folder = path.join(os.tmpdir(), Math.random().toString(36).slice(2)) | ||
fs.mkdirp(folder) | ||
try { | ||
await fn(folder) | ||
} finally { | ||
await fs.remove(folder) | ||
} | ||
} |