diff --git a/test/integration/create-next-app/index.test.ts b/test/integration/create-next-app/index.test.ts index ba7fd5df86c7..0a42f35001e1 100644 --- a/test/integration/create-next-app/index.test.ts +++ b/test/integration/create-next-app/index.test.ts @@ -3,6 +3,7 @@ import execa from 'execa' import fs from 'fs-extra' import os from 'os' import path from 'path' +import { useTempDir } from '../../lib/use-temp-dir' const cli = require.resolve('create-next-app/dist/index.js') @@ -12,25 +13,15 @@ const examplePath = 'examples/basic-css' const run = (args: string[], options: execa.Options) => execa('node', [cli].concat(args), options) -async function usingTempDir(fn: (...args: any[]) => any, options?: any) { - const folder = path.join(os.tmpdir(), Math.random().toString(36).substring(2)) - await fs.mkdirp(folder, options) - try { - await fn(folder) - } finally { - await fs.remove(folder) - } -} - describe('create next app', () => { it('non-empty directory', async () => { - await usingTempDir(async (cwd) => { + await useTempDir(async (cwd) => { const projectName = 'non-empty-directory' await fs.mkdirp(path.join(cwd, projectName)) const pkg = path.join(cwd, projectName, 'package.json') fs.writeFileSync(pkg, '{ "foo": "bar" }') - const res = await run([projectName], { cwd, reject: false }) + const res = await run([projectName, '--js'], { cwd, reject: false }) expect(res.exitCode).toBe(1) expect(res.stdout).toMatch(/contains files that could conflict/) }) @@ -40,9 +31,9 @@ describe('create next app', () => { // stdin is piped instead of inherited on windows if (process.platform !== 'win32') { it('empty directory', async () => { - await usingTempDir(async (cwd) => { + await useTempDir(async (cwd) => { const projectName = 'empty-directory' - const res = await run([projectName], { cwd }) + const res = await run([projectName, '--js'], { cwd }) expect(res.exitCode).toBe(0) expect( @@ -62,12 +53,15 @@ describe('create next app', () => { } it('invalid example name', async () => { - await usingTempDir(async (cwd) => { + await useTempDir(async (cwd) => { const projectName = 'invalid-example-name' - const res = await run([projectName, '--example', 'not a real example'], { - cwd, - reject: false, - }) + const res = await run( + [projectName, '--js', '--example', 'not a real example'], + { + cwd, + reject: false, + } + ) expect(res.exitCode).toBe(1) expect(res.stderr).toMatch(/Could not locate an example named/i) @@ -78,9 +72,11 @@ describe('create next app', () => { }) it('valid example', async () => { - await usingTempDir(async (cwd) => { + await useTempDir(async (cwd) => { const projectName = 'valid-example' - const res = await run([projectName, '--example', 'basic-css'], { cwd }) + const res = await run([projectName, '--js', '--example', 'basic-css'], { + cwd, + }) expect(res.exitCode).toBe(0) expect( @@ -100,11 +96,14 @@ describe('create next app', () => { }) it('valid example without package.json', async () => { - await usingTempDir(async (cwd) => { + await useTempDir(async (cwd) => { const projectName = 'valid-example-without-package-json' - const res = await run([projectName, '--example', 'with-docker-compose'], { - cwd, - }) + const res = await run( + [projectName, '--js', '--example', 'with-docker-compose'], + { + cwd, + } + ) expect(res.exitCode).toBe(0) expect( @@ -118,7 +117,7 @@ describe('create next app', () => { }) it('should support typescript flag', async () => { - await usingTempDir(async (cwd) => { + await useTempDir(async (cwd) => { const projectName = 'typescript' const res = await run([projectName, '--typescript'], { cwd }) expect(res.exitCode).toBe(0) @@ -161,10 +160,10 @@ describe('create next app', () => { }) it('should allow example with GitHub URL', async () => { - await usingTempDir(async (cwd) => { + await useTempDir(async (cwd) => { const projectName = 'github-app' const res = await run( - [projectName, '--example', `${exampleRepo}/${examplePath}`], + [projectName, '--js', '--example', `${exampleRepo}/${examplePath}`], { cwd, } @@ -187,11 +186,12 @@ describe('create next app', () => { }) it('should allow example with GitHub URL with trailing slash', async () => { - await usingTempDir(async (cwd) => { + await useTempDir(async (cwd) => { const projectName = 'github-app' const res = await run( [ projectName, + '--js', '--example', 'https://github.com/vercel/nextjs-portfolio-starter/', ], @@ -217,10 +217,17 @@ describe('create next app', () => { }) it('should allow example with GitHub URL and example-path', async () => { - await usingTempDir(async (cwd) => { + await useTempDir(async (cwd) => { const projectName = 'github-example-path' const res = await run( - [projectName, '--example', exampleRepo, '--example-path', examplePath], + [ + projectName, + '--js', + '--example', + exampleRepo, + '--example-path', + examplePath, + ], { cwd, } @@ -243,11 +250,12 @@ describe('create next app', () => { }) it('should use --example-path over the file path in the GitHub URL', async () => { - await usingTempDir(async (cwd) => { + await useTempDir(async (cwd) => { const projectName = 'github-example-path-2' const res = await run( [ projectName, + '--js', '--example', `${exampleRepo}/${examplePath}`, '--example-path', @@ -278,10 +286,10 @@ describe('create next app', () => { // stdin is piped instead of inherited on windows if (process.platform !== 'win32') { it('should fall back to default template', async () => { - await usingTempDir(async (cwd) => { + await useTempDir(async (cwd) => { const projectName = 'fail-example' const res = await run( - [projectName, '--example', '__internal-testing-retry'], + [projectName, '--js', '--example', '__internal-testing-retry'], { cwd, input: '\n', @@ -303,9 +311,11 @@ describe('create next app', () => { } it('should allow an example named default', async () => { - await usingTempDir(async (cwd) => { + await useTempDir(async (cwd) => { const projectName = 'default-example' - const res = await run([projectName, '--example', 'default'], { cwd }) + const res = await run([projectName, '--js', '--example', 'default'], { + cwd, + }) expect(res.exitCode).toBe(0) expect( @@ -325,17 +335,20 @@ describe('create next app', () => { }) it('should exit if example flag is empty', async () => { - await usingTempDir(async (cwd) => { + await useTempDir(async (cwd) => { const projectName = 'no-example-provided' - const res = await run([projectName, '--example'], { cwd, reject: false }) + const res = await run([projectName, '--js', '--example'], { + cwd, + reject: false, + }) expect(res.exitCode).toBe(1) }) }) - it('should exit if the folder is not writable', async () => { - await usingTempDir(async (cwd) => { + it.only('should exit if the folder is not writable', async () => { + await useTempDir(async (cwd) => { const projectName = 'not-writable' - const res = await run([projectName], { cwd, reject: false }) + const res = await run([projectName, '--js'], { cwd, reject: false }) if (process.platform === 'win32') { expect(res.exitCode).toBe(0) @@ -352,7 +365,7 @@ describe('create next app', () => { }) it('should create a project in the current directory', async () => { - await usingTempDir(async (cwd) => { + await useTempDir(async (cwd) => { const env = { ...process.env } const tmpBin = path.join(__dirname, 'bin') const tmpYarn = path.join(tmpBin, 'yarn') @@ -369,7 +382,7 @@ describe('create next app', () => { delete env.npm_config_user_agent } - const res = await run(['.'], { + const res = await run(['.', '--js'], { cwd, env, extendEnv: false, @@ -393,9 +406,9 @@ describe('create next app', () => { }) it('should ask the user for a name for the project if none supplied', async () => { - await usingTempDir(async (cwd) => { + await useTempDir(async (cwd) => { const projectName = 'test-project' - const res = await run([], { cwd, input: `${projectName}\n` }) + const res = await run(['--js'], { cwd, input: `${projectName}\n` }) expect(res.exitCode).toBe(0) const files = [ @@ -412,9 +425,9 @@ describe('create next app', () => { }) it('should use npm as the package manager on supplying --use-npm', async () => { - await usingTempDir(async (cwd) => { + await useTempDir(async (cwd) => { const projectName = 'use-npm' - const res = await run([projectName, '--use-npm'], { cwd }) + const res = await run([projectName, '--js', '--use-npm'], { cwd }) expect(res.exitCode).toBe(0) const files = [ @@ -432,11 +445,12 @@ describe('create next app', () => { }) it('should use npm as the package manager on supplying --use-npm with example', async () => { - await usingTempDir(async (cwd) => { + await useTempDir(async (cwd) => { const projectName = 'use-npm' const res = await run( [ projectName, + '--js', '--use-npm', '--example', `${exampleRepo}/${examplePath}`, @@ -459,9 +473,9 @@ describe('create next app', () => { }) it('should use pnpm as the package manager on supplying --use-pnpm', async () => { - await usingTempDir(async (cwd) => { + await useTempDir(async (cwd) => { const projectName = 'use-pnpm' - const res = await run([projectName, '--use-pnpm'], { cwd }) + const res = await run([projectName, '--js', '--use-pnpm'], { cwd }) expect(res.exitCode).toBe(0) const files = [ @@ -486,11 +500,12 @@ describe('create next app', () => { await execa('npm', ['i', '-g', 'pnpm']) } - await usingTempDir(async (cwd) => { + await useTempDir(async (cwd) => { const projectName = 'use-pnpm' const res = await run( [ projectName, + '--js', '--use-pnpm', '--example', `${exampleRepo}/${examplePath}`, diff --git a/test/lib/use-temp-dir.ts b/test/lib/use-temp-dir.ts index 989e577891f2..ac5ee243c8e7 100644 --- a/test/lib/use-temp-dir.ts +++ b/test/lib/use-temp-dir.ts @@ -6,9 +6,17 @@ import path from 'path' * Create a randomly-named directory in `os.tmpdir()`, await a function call, * and delete the directory when finished. */ -export async function useTempDir(fn: (folder: string) => void | Promise) { +export async function useTempDir( + fn: (folder: string) => void | Promise, + mode?: string | number +) { const folder = path.join(os.tmpdir(), Math.random().toString(36).slice(2)) - fs.mkdirp(folder) + await fs.mkdirp(folder) + + if (mode) { + fs.chmod(folder, mode) + } + try { await fn(folder) } finally {