From 68e6143c009569a129350d0f9b1b1530105da452 Mon Sep 17 00:00:00 2001 From: Stseb Date: Mon, 23 Jan 2017 20:24:42 +0100 Subject: [PATCH 1/5] feat: web-ext new automatic manifest --- src/cmd/index.js | 3 ++- src/cmd/new.js | 49 ++++++++++++++++++++++++++++++++++++++++++++++++ src/program.js | 6 +++++- 3 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 src/cmd/new.js diff --git a/src/cmd/index.js b/src/cmd/index.js index 46a6b506d0..fd785ac416 100644 --- a/src/cmd/index.js +++ b/src/cmd/index.js @@ -3,5 +3,6 @@ import build from './build'; import lint from './lint'; import run from './run'; import sign from './sign'; +import newCommand from './new'; -export default {build, lint, run, sign}; +export default {build, lint, run, sign, newCommand}; diff --git a/src/cmd/new.js b/src/cmd/new.js new file mode 100644 index 0000000000..9c95a3f015 --- /dev/null +++ b/src/cmd/new.js @@ -0,0 +1,49 @@ +/* @flow */ +import {fs} from 'mz'; + +const manifest = { + background: { + scripts: [], + page: '', + }, + browser_action: { + default_icon: { + '19': 'button/geo-19.png', + '38': 'button/geo-38.png', + }, + default_title: '', + }, + default_locale: 'en', + description: '', + icons: { + '48': 'icon.png', + '96': 'icon@2x.png', + }, + manifest_version: 2, + name: '', + page_action: { + default_icon: { + '19': 'button/geo-19.png', + '38': 'button/geo-38.png', + }, + default_title: '', + }, + permissions: [], + version: 0.1, +}; + +export default async function newCommand(): Promise { + const path = process.cwd(); + const title = path.match(/[A-z0-9_-]+$/); + if (Array.isArray(title)) { + manifest.name = title[0]; + manifest.page_action.default_title = title[0]; + manifest.browser_action.default_title = title[0]; + var json = JSON.stringify(manifest, null, 2); + try { + await fs.writeFile('manifest.json', json, 'utf8'); + } catch (error) { + throw error; + } + } +} diff --git a/src/program.js b/src/program.js index 9f1437649a..ce85f17cf5 100644 --- a/src/program.js +++ b/src/program.js @@ -370,7 +370,11 @@ Example: $0 --help run. type: 'boolean', default: false, }, - }); + }) + .command( + 'new', + 'Ease the creation of new extension', commands.newCommand + ); return program.execute(absolutePackageDir, runOptions); } From 5229109cfc6767fd2e23e84dc060459638762168 Mon Sep 17 00:00:00 2001 From: Stseb Date: Tue, 24 Jan 2017 14:09:51 +0100 Subject: [PATCH 2/5] test: web-ext new basic test --- tests/unit/test-cmd/test.new.js | 35 +++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 tests/unit/test-cmd/test.new.js diff --git a/tests/unit/test-cmd/test.new.js b/tests/unit/test-cmd/test.new.js new file mode 100644 index 0000000000..aa54728521 --- /dev/null +++ b/tests/unit/test-cmd/test.new.js @@ -0,0 +1,35 @@ +/* @flow */ +import path from 'path'; + +import {fs} from 'mz'; +import {describe, it, after} from 'mocha'; +import {assert} from 'chai'; + +import newCommand from '../../../src/cmd/new'; +import {withTempDir} from '../../../src/util/temp-dir'; + +const homeDir = process.cwd(); + +describe('new', () => { + + after(() => { + process.chdir(homeDir); + }); + + it('creates manifest json file with approriate ', () => withTempDir( + (tmpDir) => { + const targetDir = path.join(tmpDir.path(), 'target'); + return fs.mkdir(targetDir) + .then(() => { + process.chdir(targetDir); + return newCommand() + .then(() => { + return fs.readFile('manifest.json', 'utf-8') + .then((data) => { + const manifest = JSON.parse(data); + assert.equal(manifest.name, 'target'); + }); + }); + }); + })); +}); From 647c0a1fb0a856aad68957fde6cf3cd70b41e99b Mon Sep 17 00:00:00 2001 From: Stseb Date: Mon, 13 Feb 2017 21:00:42 +0100 Subject: [PATCH 3/5] feat: cli interface and correct exit --- package.json | 1 + src/cmd/create.js | 130 +++++++++++++++++++++++++++++ src/cmd/index.js | 4 +- src/cmd/new.js | 49 ----------- src/program.js | 17 +++- tests/unit/test-cmd/test.create.js | 83 ++++++++++++++++++ tests/unit/test-cmd/test.new.js | 35 -------- 7 files changed, 230 insertions(+), 89 deletions(-) create mode 100644 src/cmd/create.js delete mode 100644 src/cmd/new.js create mode 100644 tests/unit/test-cmd/test.create.js delete mode 100644 tests/unit/test-cmd/test.new.js diff --git a/package.json b/package.json index aff818ef4e..db3cb27ba1 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ "fx-runner": "1.0.6", "git-rev-sync": "1.8.0", "minimatch": "3.0.3", + "mkdirp": "0.5.1", "mz": "2.6.0", "node-firefox-connect": "1.2.0", "node-notifier": "4.6.1", diff --git a/src/cmd/create.js b/src/cmd/create.js new file mode 100644 index 0000000000..ae4a706247 --- /dev/null +++ b/src/cmd/create.js @@ -0,0 +1,130 @@ +/* @flow */ +import path from 'path'; +import readline from 'readline'; +import tty from 'tty'; + +import {fs} from 'mz'; +import mkdirp from 'mkdirp'; +import promisify from 'es6-promisify'; + +import {createLogger} from '../util/logger'; +import {UsageError, isErrorWithCode} from '../errors'; + +const log = createLogger(__filename); +const defaultAsyncMkdirp = promisify(mkdirp); + +export type CreateParams = {| + name: string, + pause?: typeof process.stdin.pause, +|}; + +export default async function create( + { + name, + pause = process.stdin.pause, + }: CreateParams +): Promise { + const targetPath = path.join(process.cwd(), name); + log.info(targetPath); + + let userAbort = true; + + try { + const stats = await fs.stat(targetPath); + if (stats.isDirectory()) { + if (process.stdin.isTTY && + (process.stdin instanceof tty.ReadStream)) { + process.stdin.setRawMode(true); + readline.emitKeypressEvents(process.stdin); + + while (true) { + log.info(`The ${targetPath} already exists. Are you sure you want ` + + 'to use this directory and overwrite existing files? Y/N'); + + const pressed = await new Promise((resolve) => { + process.stdin.once('keypress', (str, key) => resolve(key)); + }); + + if (pressed.name === 'n' || (pressed.ctrl && pressed.name === 'c')) { + break; + } else if (pressed.name === 'y') { + userAbort = false; + break; + } + } + } else { + throw new UsageError('Target dir already exist, overwrite is not ' + + 'allowed without user confirmation.'); + } + } + + if (userAbort) { + log.info('User aborted the command.'); + pause(); + return; + } + + return await createFiles(name, targetPath).then(() => { + pause(); + }); + } catch (statErr) { + if (!isErrorWithCode('ENOENT', statErr)) { + throw statErr; + } else { + try { + await defaultAsyncMkdirp(targetPath); + await createFiles(name, targetPath); + } catch (mkdirErr) { + throw mkdirErr; + } + } + } +} + +async function createFiles(name, targetPath): Promise { + log.info('Creating manifest file'); + const generatedManifest = await generateManifest(name); + const json = JSON.stringify(generatedManifest, null, 2); + try { + log.info('Writing files'); + await fs.writeFile(path.join(targetPath, 'manifest.json'), json, 'utf8'); + await fs.open(path.join(targetPath, 'background.js'), 'w'); + await fs.open(path.join(targetPath, 'content.js'), 'w'); + } catch (error) { + throw error; + } + return; +} + +async function generateManifest(title) { + return { + manifest_version: 2, + name: `${title} (name)`, + description: `${title} (description)`, + version: 0.1, + default_locale: 'en', + icons: { + '48': 'icon.png', + '96': 'icon@2x.png', + }, + browser_action: { + default_title: `${title} (browserAction)`, + default_icon: { + '19': 'button/button-19.png', + '38': 'button/button-38.png', + }, + }, + background: { + scripts: ['background.js'], + page: '', + }, + content_scripts: [ + { + exclude_matches: [], + matches: [], + js: ['content.js'], + }, + ], + permissions: [], + }; +} diff --git a/src/cmd/index.js b/src/cmd/index.js index fd785ac416..e71b5a2fc1 100644 --- a/src/cmd/index.js +++ b/src/cmd/index.js @@ -3,6 +3,6 @@ import build from './build'; import lint from './lint'; import run from './run'; import sign from './sign'; -import newCommand from './new'; +import create from './create'; -export default {build, lint, run, sign, newCommand}; +export default {build, lint, run, sign, create}; diff --git a/src/cmd/new.js b/src/cmd/new.js deleted file mode 100644 index 9c95a3f015..0000000000 --- a/src/cmd/new.js +++ /dev/null @@ -1,49 +0,0 @@ -/* @flow */ -import {fs} from 'mz'; - -const manifest = { - background: { - scripts: [], - page: '', - }, - browser_action: { - default_icon: { - '19': 'button/geo-19.png', - '38': 'button/geo-38.png', - }, - default_title: '', - }, - default_locale: 'en', - description: '', - icons: { - '48': 'icon.png', - '96': 'icon@2x.png', - }, - manifest_version: 2, - name: '', - page_action: { - default_icon: { - '19': 'button/geo-19.png', - '38': 'button/geo-38.png', - }, - default_title: '', - }, - permissions: [], - version: 0.1, -}; - -export default async function newCommand(): Promise { - const path = process.cwd(); - const title = path.match(/[A-z0-9_-]+$/); - if (Array.isArray(title)) { - manifest.name = title[0]; - manifest.page_action.default_title = title[0]; - manifest.browser_action.default_title = title[0]; - var json = JSON.stringify(manifest, null, 2); - try { - await fs.writeFile('manifest.json', json, 'utf8'); - } catch (error) { - throw error; - } - } -} diff --git a/src/program.js b/src/program.js index ce85f17cf5..2fade06e75 100644 --- a/src/program.js +++ b/src/program.js @@ -372,9 +372,20 @@ Example: $0 --help run. }, }) .command( - 'new', - 'Ease the creation of new extension', commands.newCommand - ); + 'create', + 'Create basic structure of a new addon', commands.create, { + 'name': { + desc: 'Name of the project and its directory', + type: 'string', + demand: true, + requiresArg: true, + }, + 'path': { + desc: 'Optional path to a directory', + type: 'string', + requiresArg: true, + }, + }); return program.execute(absolutePackageDir, runOptions); } diff --git a/tests/unit/test-cmd/test.create.js b/tests/unit/test-cmd/test.create.js new file mode 100644 index 0000000000..df794b4274 --- /dev/null +++ b/tests/unit/test-cmd/test.create.js @@ -0,0 +1,83 @@ +/* @flow */ +import path from 'path'; + +import {fs} from 'mz'; +import {describe, it, afterEach} from 'mocha'; +import {assert} from 'chai'; +import sinon from 'sinon'; + +import create from '../../../src/cmd/create'; +import {withTempDir} from '../../../src/util/temp-dir'; +import {makeSureItFails} from '../helpers'; + +const homeDir = process.cwd(); + +describe('create', () => { + + afterEach(() => { + process.chdir(homeDir); + }); + + it('creates files including manifest with correct name ', () => withTempDir( + (tmpDir) => { + process.chdir(tmpDir.path()); + const targetDir = path.join(tmpDir.path(), 'target'); + const manifest = path.join(targetDir, 'manifest.json'); + return create({name: 'target'}) + .then(() => { + return fs.stat(path.join(targetDir, 'content.js')) + .then((contentstat) => { + assert.equal(contentstat.isDirectory(), false); + return fs.stat(path.join(targetDir, 'background.js')) + .then((bgstat) => { + assert.equal(bgstat.isDirectory(), false); + return fs.readFile(manifest, 'utf-8') + .then((data) => { + const parsed = JSON.parse(data); + assert.equal(parsed.name, 'target (name)'); + }); + }); + }); + }); + })); + + it('does not overwrit existing directory if user aborts', () => withTempDir( + (tmpDir) => { + process.chdir(tmpDir.path()); + const targetDir = path.join(tmpDir.path(), 'target'); + const fakePause = sinon.spy(() => Promise.resolve()); + fs.mkdir('target'); + setTimeout(() => { + process.stdin.emit('keypress', 'n', {name: 'n', ctrl: false}); + }, 2000); + return create({name: 'target', pause: fakePause}) + .then(() => { + return fs.readFile(path.join(targetDir, 'manifest.json'), 'utf-8') + .then(makeSureItFails()) + .catch((error) => { + assert.equal(error.code, 'ENOENT'); + }); + }); + })); + + it('overwrites existing directory if user allows', () => withTempDir( + (tmpDir) => { + process.chdir(tmpDir.path()); + const targetDir = path.join(tmpDir.path(), 'target'); + const fakePause = sinon.spy(() => Promise.resolve()); + fs.mkdir('target'); + setTimeout(() => { + process.stdin.emit('keypress', 'y', {name: 'y', ctrl: false}); + }, 2000); + return create({name: 'target', pause: fakePause}) + .then(() => { + return fs.readFile(path.join(targetDir, 'manifest.json'), 'utf-8') + .then((data) => { + const manifest = JSON.parse(data); + assert.equal(manifest.name, 'target (name)'); + assert.ok(fakePause.called); + }); + }); + })); + +}); diff --git a/tests/unit/test-cmd/test.new.js b/tests/unit/test-cmd/test.new.js deleted file mode 100644 index aa54728521..0000000000 --- a/tests/unit/test-cmd/test.new.js +++ /dev/null @@ -1,35 +0,0 @@ -/* @flow */ -import path from 'path'; - -import {fs} from 'mz'; -import {describe, it, after} from 'mocha'; -import {assert} from 'chai'; - -import newCommand from '../../../src/cmd/new'; -import {withTempDir} from '../../../src/util/temp-dir'; - -const homeDir = process.cwd(); - -describe('new', () => { - - after(() => { - process.chdir(homeDir); - }); - - it('creates manifest json file with approriate ', () => withTempDir( - (tmpDir) => { - const targetDir = path.join(tmpDir.path(), 'target'); - return fs.mkdir(targetDir) - .then(() => { - process.chdir(targetDir); - return newCommand() - .then(() => { - return fs.readFile('manifest.json', 'utf-8') - .then((data) => { - const manifest = JSON.parse(data); - assert.equal(manifest.name, 'target'); - }); - }); - }); - })); -}); From 4cdc8d71bc034461fdebd68a5d09c6ca09197263 Mon Sep 17 00:00:00 2001 From: Stseb Date: Fri, 10 Mar 2017 16:25:46 +0100 Subject: [PATCH 4/5] fix: better while loop and testing --- package.json | 1 + src/cmd/create.js | 31 +++++++++------- src/program.js | 9 +---- tests/unit/test-cmd/test.create.js | 59 ++++++++++++++++++++++++------ 4 files changed, 67 insertions(+), 33 deletions(-) diff --git a/package.json b/package.json index db3cb27ba1..7320adaa12 100644 --- a/package.json +++ b/package.json @@ -108,6 +108,7 @@ "load-grunt-tasks": "3.5.2", "mocha": "3.2.0", "mocha-multi": "0.10.0", + "mock-stdin": "0.3.1", "nsp": "2.6.2", "object.entries": "1.0.4", "object.values": "1.0.4", diff --git a/src/cmd/create.js b/src/cmd/create.js index ae4a706247..34539c7f7f 100644 --- a/src/cmd/create.js +++ b/src/cmd/create.js @@ -14,40 +14,43 @@ const log = createLogger(__filename); const defaultAsyncMkdirp = promisify(mkdirp); export type CreateParams = {| - name: string, - pause?: typeof process.stdin.pause, + dirPath: string, + stdin?: stream$Readable, |}; export default async function create( { - name, - pause = process.stdin.pause, + dirPath, + stdin = process.stdin, }: CreateParams ): Promise { - const targetPath = path.join(process.cwd(), name); - log.info(targetPath); + const targetPath = path.join(process.cwd(), dirPath); + const name = path.basename(dirPath); + log.info(name, targetPath); let userAbort = true; try { const stats = await fs.stat(targetPath); if (stats.isDirectory()) { - if (process.stdin.isTTY && - (process.stdin instanceof tty.ReadStream)) { - process.stdin.setRawMode(true); - readline.emitKeypressEvents(process.stdin); + if (stdin.isTTY && (stdin instanceof tty.ReadStream)) { + stdin.setRawMode(true); + readline.emitKeypressEvents(stdin); + let userConfirmation = false; - while (true) { + while (!userConfirmation) { log.info(`The ${targetPath} already exists. Are you sure you want ` + 'to use this directory and overwrite existing files? Y/N'); const pressed = await new Promise((resolve) => { - process.stdin.once('keypress', (str, key) => resolve(key)); + stdin.once('keypress', (str, key) => resolve(key)); }); if (pressed.name === 'n' || (pressed.ctrl && pressed.name === 'c')) { + userConfirmation = true; break; } else if (pressed.name === 'y') { + userConfirmation = true; userAbort = false; break; } @@ -60,12 +63,12 @@ export default async function create( if (userAbort) { log.info('User aborted the command.'); - pause(); + stdin.pause(); return; } return await createFiles(name, targetPath).then(() => { - pause(); + stdin.pause(); }); } catch (statErr) { if (!isErrorWithCode('ENOENT', statErr)) { diff --git a/src/program.js b/src/program.js index 2fade06e75..79eecaf214 100644 --- a/src/program.js +++ b/src/program.js @@ -374,15 +374,10 @@ Example: $0 --help run. .command( 'create', 'Create basic structure of a new addon', commands.create, { - 'name': { - desc: 'Name of the project and its directory', - type: 'string', - demand: true, - requiresArg: true, - }, - 'path': { + 'dir-path': { desc: 'Optional path to a directory', type: 'string', + demand: true, requiresArg: true, }, }); diff --git a/tests/unit/test-cmd/test.create.js b/tests/unit/test-cmd/test.create.js index df794b4274..c3f3c4c6cf 100644 --- a/tests/unit/test-cmd/test.create.js +++ b/tests/unit/test-cmd/test.create.js @@ -1,14 +1,17 @@ /* @flow */ import path from 'path'; +import tty from 'tty'; import {fs} from 'mz'; import {describe, it, afterEach} from 'mocha'; import {assert} from 'chai'; import sinon from 'sinon'; +import mockStdin from 'mock-stdin'; import create from '../../../src/cmd/create'; import {withTempDir} from '../../../src/util/temp-dir'; import {makeSureItFails} from '../helpers'; +import {onlyInstancesOf, UsageError} from '../../../src/errors'; const homeDir = process.cwd(); @@ -18,12 +21,12 @@ describe('create', () => { process.chdir(homeDir); }); - it('creates files including manifest with correct name ', () => withTempDir( + it('creates files including manifest with correct name', () => withTempDir( (tmpDir) => { process.chdir(tmpDir.path()); const targetDir = path.join(tmpDir.path(), 'target'); const manifest = path.join(targetDir, 'manifest.json'); - return create({name: 'target'}) + return create({dirPath: 'target'}) .then(() => { return fs.stat(path.join(targetDir, 'content.js')) .then((contentstat) => { @@ -41,16 +44,35 @@ describe('create', () => { }); })); - it('does not overwrit existing directory if user aborts', () => withTempDir( + it('creates directory recursively when needed', () => withTempDir( + (tmpDir) => { + process.chdir(tmpDir.path()); + const targetDir = path.join(tmpDir.path(), 'sub/target'); + const manifest = path.join(targetDir, 'manifest.json'); + return create({dirPath: 'sub/target'}) + .then(() => { + return fs.stat(path.join(targetDir)) + .then((contentstat) => { + assert.equal(contentstat.isDirectory(), true); + return fs.readFile(manifest, 'utf-8') + .then((data) => { + const parsed = JSON.parse(data); + assert.equal(parsed.name, 'target (name)'); + }); + }); + }); + })); + + it('does not overwrite existing directory if user aborts', () => withTempDir( (tmpDir) => { process.chdir(tmpDir.path()); const targetDir = path.join(tmpDir.path(), 'target'); - const fakePause = sinon.spy(() => Promise.resolve()); + const fakeStdin = new tty.ReadStream(); fs.mkdir('target'); setTimeout(() => { - process.stdin.emit('keypress', 'n', {name: 'n', ctrl: false}); - }, 2000); - return create({name: 'target', pause: fakePause}) + fakeStdin.emit('keypress', 'n', {name: 'n', ctrl: false}); + }, 100); + return create({dirPath: 'target', stdin: fakeStdin}) .then(() => { return fs.readFile(path.join(targetDir, 'manifest.json'), 'utf-8') .then(makeSureItFails()) @@ -64,20 +86,33 @@ describe('create', () => { (tmpDir) => { process.chdir(tmpDir.path()); const targetDir = path.join(tmpDir.path(), 'target'); - const fakePause = sinon.spy(() => Promise.resolve()); + const fakeStdin = new tty.ReadStream(); + sinon.spy(fakeStdin, 'pause'); fs.mkdir('target'); setTimeout(() => { - process.stdin.emit('keypress', 'y', {name: 'y', ctrl: false}); - }, 2000); - return create({name: 'target', pause: fakePause}) + fakeStdin.emit('keypress', 'y', {name: 'y', ctrl: false}); + }, 100); + return create({dirPath: 'target', stdin: fakeStdin}) .then(() => { return fs.readFile(path.join(targetDir, 'manifest.json'), 'utf-8') .then((data) => { const manifest = JSON.parse(data); assert.equal(manifest.name, 'target (name)'); - assert.ok(fakePause.called); + assert.ok(fakeStdin.pause.called); }); }); })); + it('throws error when user cannot confirm overwriting', () => withTempDir( + (tmpDir) => { + process.chdir(tmpDir.path()); + mockStdin.isTTY = false; + fs.mkdir('target'); + return create({dirPath: 'target', stdin: mockStdin}) + .then(makeSureItFails()) + .catch(onlyInstancesOf(UsageError, (error) => { + assert.match(error.message, /without user confirmation/); + })); + })); + }); From 4e8e438ba4a80fa6a9b83c8eff4194a481a1e78e Mon Sep 17 00:00:00 2001 From: Stseb Date: Tue, 27 Jun 2017 15:33:21 -0700 Subject: [PATCH 5/5] test: adapted for windows fs --- package.json | 5 ++-- tests/unit/test-cmd/test.create.js | 43 +++++++++++++++++++++++++----- 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 5ff09d9d33..ca6cea9537 100644 --- a/package.json +++ b/package.json @@ -63,17 +63,18 @@ "mkdirp": "0.5.1", "mz": "2.6.0", "node-firefox-connect": "1.2.0", - "open": "0.0.5", "node-notifier": "5.1.2", + "open": "0.0.5", "parse-json": "2.2.0", "regenerator-runtime": "0.10.5", "require-uncached": "1.0.3", + "rimraf": "2.6.1", "sign-addon": "0.2.1", "source-map-support": "0.4.15", "stream-to-promise": "2.2.0", "tmp": "0.0.30", - "watchpack": "1.3.0", "update-notifier": "2.1.0", + "watchpack": "1.3.0", "yargs": "6.6.0", "zip-dir": "1.0.2" }, diff --git a/tests/unit/test-cmd/test.create.js b/tests/unit/test-cmd/test.create.js index c3f3c4c6cf..654d9439a6 100644 --- a/tests/unit/test-cmd/test.create.js +++ b/tests/unit/test-cmd/test.create.js @@ -7,6 +7,7 @@ import {describe, it, afterEach} from 'mocha'; import {assert} from 'chai'; import sinon from 'sinon'; import mockStdin from 'mock-stdin'; +import rimraf from 'rimraf'; import create from '../../../src/cmd/create'; import {withTempDir} from '../../../src/util/temp-dir'; @@ -21,6 +22,14 @@ describe('create', () => { process.chdir(homeDir); }); + async function cleanTmpDir(dir) { + rimraf(dir, (error) => { + if (error) { + throw error; + } + }); + } + it('creates files including manifest with correct name', () => withTempDir( (tmpDir) => { process.chdir(tmpDir.path()); @@ -38,7 +47,11 @@ describe('create', () => { .then((data) => { const parsed = JSON.parse(data); assert.equal(parsed.name, 'target (name)'); - }); + }) + .then( + () => cleanTmpDir(targetDir), + () => cleanTmpDir(targetDir) + ); }); }); }); @@ -58,7 +71,11 @@ describe('create', () => { .then((data) => { const parsed = JSON.parse(data); assert.equal(parsed.name, 'target (name)'); - }); + }) + .then( + () => cleanTmpDir(targetDir), + () => cleanTmpDir(targetDir) + ); }); }); })); @@ -71,14 +88,18 @@ describe('create', () => { fs.mkdir('target'); setTimeout(() => { fakeStdin.emit('keypress', 'n', {name: 'n', ctrl: false}); - }, 100); + }, 50); return create({dirPath: 'target', stdin: fakeStdin}) .then(() => { return fs.readFile(path.join(targetDir, 'manifest.json'), 'utf-8') .then(makeSureItFails()) .catch((error) => { assert.equal(error.code, 'ENOENT'); - }); + }) + .then( + () => cleanTmpDir(targetDir), + () => cleanTmpDir(targetDir) + ); }); })); @@ -91,7 +112,7 @@ describe('create', () => { fs.mkdir('target'); setTimeout(() => { fakeStdin.emit('keypress', 'y', {name: 'y', ctrl: false}); - }, 100); + }, 50); return create({dirPath: 'target', stdin: fakeStdin}) .then(() => { return fs.readFile(path.join(targetDir, 'manifest.json'), 'utf-8') @@ -99,7 +120,11 @@ describe('create', () => { const manifest = JSON.parse(data); assert.equal(manifest.name, 'target (name)'); assert.ok(fakeStdin.pause.called); - }); + }) + .then( + () => cleanTmpDir(targetDir), + () => cleanTmpDir(targetDir) + ); }); })); @@ -112,7 +137,11 @@ describe('create', () => { .then(makeSureItFails()) .catch(onlyInstancesOf(UsageError, (error) => { assert.match(error.message, /without user confirmation/); - })); + })) + .then( + () => cleanTmpDir(path.join(tmpDir.path(), 'target')), + () => cleanTmpDir(path.join(tmpDir.path(), 'target')) + ); })); });