From 090605e286b01b6c0d6fb130af7f43a3b08ce61d Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Tue, 15 Aug 2017 09:03:36 -0700 Subject: [PATCH 01/42] Update variable names in tests --- test/tests/callbacks/apply.spec.js | 12 ++++++------ test/tests/commands/ls.spec.js | 4 ++-- test/tests/commands/pointer.spec.js | 6 +++--- test/tests/commands/prune.spec.js | 4 ++-- test/tests/commands/push.spec.js | 10 +++++----- test/tests/commands/track.spec.js | 4 ++-- test/tests/commands/untrack.spec.js | 4 ++-- test/tests/commands/version.spec.js | 4 ++-- test/tests/initialize.spec.js | 12 ++++++------ 9 files changed, 30 insertions(+), 30 deletions(-) diff --git a/test/tests/callbacks/apply.spec.js b/test/tests/callbacks/apply.spec.js index 70b533e..5464c94 100644 --- a/test/tests/callbacks/apply.spec.js +++ b/test/tests/callbacks/apply.spec.js @@ -38,33 +38,33 @@ const commitFile = (repo, fileName, commitMessage) => { describe('Apply', () => { it('Clean', () => { - const workdirPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); + const lfsTestRepoPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); const NodeGitLFS = LFS(NodeGit); let repository; - return NodeGitLFS.Repository.open(workdirPath) + return NodeGitLFS.Repository.open(lfsTestRepoPath) .then((repo) => { repository = repo; return track(repo, ['*.md']); }) .then(() => NodeGitLFS.LFS.register()) - .then(() => exec('base64 /dev/urandom | head -c 20 > big_file_test.md', { cwd: workdirPath })) + .then(() => exec('base64 /dev/urandom | head -c 20 > big_file_test.md', { cwd: lfsTestRepoPath })) .then(() => commitFile(repository, 'big_file_test.md', 'LFS Clean Test')) .then(() => todo()); }); it('Smudge', () => { - const workdirPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); + const lfsTestRepoPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); const NodeGitLFS = LFS(NodeGit); let repository; - return NodeGitLFS.Repository.open(workdirPath) + return NodeGitLFS.Repository.open(lfsTestRepoPath) .then((repo) => { repository = repo; return repo; }) .then(() => NodeGitLFS.LFS.register()) - .then(() => exec('base64 /dev/urandom | head -c 20 > big_file_test.txt', { cwd: workdirPath })) + .then(() => exec('base64 /dev/urandom | head -c 20 > big_file_test.txt', { cwd: lfsTestRepoPath })) .then(() => { const opts = { checkoutStrategy: NodeGit.Checkout.STRATEGY.FORCE, diff --git a/test/tests/commands/ls.spec.js b/test/tests/commands/ls.spec.js index 00bfd27..7a709c6 100644 --- a/test/tests/commands/ls.spec.js +++ b/test/tests/commands/ls.spec.js @@ -6,10 +6,10 @@ import ls from '../../../build/src/commands/ls'; describe('ls-files', () => { it('does generate ls response', () => { - const workdirPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); + const lfsTestRepoPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); const NodeGitLFS = LFS(NodeGit); - return NodeGitLFS.Repository.open(workdirPath) + return NodeGitLFS.Repository.open(lfsTestRepoPath) .then(repo => ls(repo, { long: true })) .then(() => todo()); }); diff --git a/test/tests/commands/pointer.spec.js b/test/tests/commands/pointer.spec.js index 9601691..188385c 100644 --- a/test/tests/commands/pointer.spec.js +++ b/test/tests/commands/pointer.spec.js @@ -6,12 +6,12 @@ import pointer from '../../../build/src/commands/pointer'; describe('Pointer', () => { it('does generate pointer response', () => { - const workdirPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); + const lfsTestRepoPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); const NodeGitLFS = LFS(NodeGit); - const packageJson = path.join(workdirPath, 'package.json'); + const packageJson = path.join(lfsTestRepoPath, 'package.json'); - return NodeGitLFS.Repository.open(workdirPath) + return NodeGitLFS.Repository.open(lfsTestRepoPath) .then(repo => pointer(repo, packageJson)) .then(() => todo()); }); diff --git a/test/tests/commands/prune.spec.js b/test/tests/commands/prune.spec.js index 6e60141..acf896c 100644 --- a/test/tests/commands/prune.spec.js +++ b/test/tests/commands/prune.spec.js @@ -6,10 +6,10 @@ import prune from '../../../build/src/commands/prune'; describe('Prune', () => { it('does generate prune response', () => { - const workdirPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); + const lfsTestRepoPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); const NodeGitLFS = LFS(NodeGit); - return NodeGitLFS.Repository.open(workdirPath) + return NodeGitLFS.Repository.open(lfsTestRepoPath) .then(repo => prune(repo)) .then(() => todo()); }); diff --git a/test/tests/commands/push.spec.js b/test/tests/commands/push.spec.js index a26d918..f0099d4 100644 --- a/test/tests/commands/push.spec.js +++ b/test/tests/commands/push.spec.js @@ -6,13 +6,13 @@ import exec from '../../../build/src/utils/execHelper'; describe('Push', () => { it('should generate push response', () => { - const workdirPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); + const lfsTestRepoPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); const NodeGitLFS = LFS(NodeGit); - return exec('base64 /dev/urandom | head -c 20 > test_file.txt', { cwd: workdirPath }) - .then(() => exec('git add test_file.txt', { cwd: workdirPath })) - .then(() => exec('git commit -m "LFS: push unit test"', { cwd: workdirPath })) - .then(() => NodeGitLFS.Repository.open(workdirPath)) + return exec('base64 /dev/urandom | head -c 20 > test_file.txt', { cwd: lfsTestRepoPath }) + .then(() => exec('git add test_file.txt', { cwd: lfsTestRepoPath })) + .then(() => exec('git commit -m "LFS: push unit test"', { cwd: lfsTestRepoPath })) + .then(() => NodeGitLFS.Repository.open(lfsTestRepoPath)) .then(repo => NodeGitLFS.LFS.push(repo, 'origin', 'test')) .then(() => todo()); }); diff --git a/test/tests/commands/track.spec.js b/test/tests/commands/track.spec.js index 6c2f7d7..c88e016 100644 --- a/test/tests/commands/track.spec.js +++ b/test/tests/commands/track.spec.js @@ -6,10 +6,10 @@ import track from '../../../build/src/commands/track'; describe('Track', () => { it('does generate track response', () => { - const workdirPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); + const lfsTestRepoPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); const NodeGitLFS = LFS(NodeGit); - return NodeGitLFS.Repository.open(workdirPath) + return NodeGitLFS.Repository.open(lfsTestRepoPath) .then(repo => track(repo, ['*.png', '*.dmg'])) .then(() => todo()); }); diff --git a/test/tests/commands/untrack.spec.js b/test/tests/commands/untrack.spec.js index 63b6f9f..3a74f93 100644 --- a/test/tests/commands/untrack.spec.js +++ b/test/tests/commands/untrack.spec.js @@ -7,10 +7,10 @@ import untrack from '../../../build/src/commands/untrack'; describe('Untrack', () => { it('does generate untrack response', () => { - const workdirPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); + const lfsTestRepoPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); const NodeGitLFS = LFS(NodeGit); let repository; - return NodeGitLFS.Repository.open(workdirPath) + return NodeGitLFS.Repository.open(lfsTestRepoPath) .then((repo) => { repository = repo; return track(repo, ['*.png', '*.dmg', '*.txt', '*.a']); diff --git a/test/tests/commands/version.spec.js b/test/tests/commands/version.spec.js index 3dc34c6..f39fca8 100644 --- a/test/tests/commands/version.spec.js +++ b/test/tests/commands/version.spec.js @@ -6,10 +6,10 @@ import version from '../../../build/src/commands/version'; describe('Version', () => { it('does provide version number', () => { - const workdirPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); + const lfsTestRepoPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); const NodeGitLFS = LFS(NodeGit); - return NodeGitLFS.Repository.open(workdirPath) + return NodeGitLFS.Repository.open(lfsTestRepoPath) .then(repo => version(repo)) .then(() => todo()); }); diff --git a/test/tests/initialize.spec.js b/test/tests/initialize.spec.js index cf06443..bd4c75c 100644 --- a/test/tests/initialize.spec.js +++ b/test/tests/initialize.spec.js @@ -7,9 +7,9 @@ import LFS from '../../build/src'; describe('Initialize', () => { it('initialize is a promise', () => { const NodeGitLFS = LFS(NodeGit); - const workdirPath = path.resolve(__dirname, '..', 'repos', 'lfs-test-repository'); + const lfsTestRepoPath = path.resolve(__dirname, '..', 'repos', 'lfs-test-repository'); - return NodeGitLFS.Repository.open(workdirPath) + return NodeGitLFS.Repository.open(lfsTestRepoPath) .then((repo) => { const init = NodeGitLFS.LFS.initialize(repo); expect(init).to.be.a('promise'); @@ -18,13 +18,13 @@ describe('Initialize', () => { it('creates .gitattributes for empty repo', () => { const NodeGitLFS = LFS(NodeGit); - const emptydirPath = path.resolve(__dirname, '..', 'repos', 'empty'); - expect(fs.existsSync(path.join(emptydirPath, '.gitattributes'))).to.be.false; + const emptyRepoPath = path.resolve(__dirname, '..', 'repos', 'empty'); + expect(fs.existsSync(path.join(emptyRepoPath, '.gitattributes'))).to.be.false; - return NodeGitLFS.Repository.open(emptydirPath) + return NodeGitLFS.Repository.open(emptyRepoPath) .then(repo => NodeGitLFS.LFS.initialize(repo)) .then(() => { - expect(fs.existsSync(path.join(emptydirPath, '.gitattributes'))).to.be.true; + expect(fs.existsSync(path.join(emptyRepoPath, '.gitattributes'))).to.be.true; }); }); }); From dfa73148616f00d5ea5b199898a276427d31a07d Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Tue, 15 Aug 2017 09:03:58 -0700 Subject: [PATCH 02/42] Remove unnecessary variable assignments --- src/commands/checkout.js | 1 - src/commands/fetch.js | 1 - src/commands/ls.js | 3 +-- src/commands/pointer.js | 3 +-- src/commands/prune.js | 3 +-- src/commands/pull.js | 1 - src/commands/push.js | 1 - src/commands/track.js | 3 +-- src/commands/untrack.js | 3 +-- src/initialize.js | 2 +- 10 files changed, 6 insertions(+), 15 deletions(-) diff --git a/src/commands/checkout.js b/src/commands/checkout.js index ee11f26..f24e56d 100644 --- a/src/commands/checkout.js +++ b/src/commands/checkout.js @@ -63,7 +63,6 @@ const generateCheckoutStats = (raw) => { function checkout(repo, callback) { const response = generateResponse(); - const repoPath = repo.workdir(); return core.checkout('', { cwd: repoPath }, callback) .then(({ stdout }) => { diff --git a/src/commands/fetch.js b/src/commands/fetch.js index fe3a5d9..5c01748 100644 --- a/src/commands/fetch.js +++ b/src/commands/fetch.js @@ -61,7 +61,6 @@ const generateFetchStats = (raw) => { function fetch(repo, options) { const response = generateResponse(); - const repoPath = repo.workdir(); const args = []; const { diff --git a/src/commands/ls.js b/src/commands/ls.js index f2445c6..3ae1107 100644 --- a/src/commands/ls.js +++ b/src/commands/ls.js @@ -48,10 +48,9 @@ const buildArgs = (options) => { const ls = (repo, options) => { const response = generateResponse(); - const repoPath = repo.workdir(); const args = buildArgs(options); - return core.ls(args, { cwd: repoPath }) + return core.ls(args, { cwd: repo.workdir() }) .then(({ stdout, stderr }) => { response.raw = stdout; diff --git a/src/commands/pointer.js b/src/commands/pointer.js index fdc6d8d..58b57ac 100644 --- a/src/commands/pointer.js +++ b/src/commands/pointer.js @@ -14,9 +14,8 @@ const pointer = (repo, filePath, pointerPath) => { } const response = generateResponse(); - const repoPath = repo.workdir(); - return core.pointer(args, { cwd: repoPath }) + return core.pointer(args, { cwd: repo.workdir() }) .then(({ stdout, stderr }) => { response.raw = stdout; diff --git a/src/commands/prune.js b/src/commands/prune.js index 5cfb4b3..ad28e02 100644 --- a/src/commands/prune.js +++ b/src/commands/prune.js @@ -4,9 +4,8 @@ import { BAD_CORE_RESPONSE } from '../constants'; const prune = (repo, args) => { const response = generateResponse(); - const repoPath = repo.workdir(); - return core.prune(args, { cwd: repoPath }) + return core.prune(args, { cwd: repo.workdir() }) .then(({ stdout, stderr }) => { response.raw = stdout; diff --git a/src/commands/pull.js b/src/commands/pull.js index 433ed4d..a6b2771 100644 --- a/src/commands/pull.js +++ b/src/commands/pull.js @@ -61,7 +61,6 @@ const generatePullStats = (raw) => { function pull(repo, options) { const response = generateResponse(); - const repoPath = repo.workdir(); const args = []; const { diff --git a/src/commands/push.js b/src/commands/push.js index a870dab..11125b7 100644 --- a/src/commands/push.js +++ b/src/commands/push.js @@ -70,7 +70,6 @@ const generatePushStats = (raw) => { function push(repo, options) { const response = generateResponse(); - const repoPath = repo.workdir(); const { remoteName, diff --git a/src/commands/track.js b/src/commands/track.js index 6733854..bc771ba 100644 --- a/src/commands/track.js +++ b/src/commands/track.js @@ -23,9 +23,8 @@ const track = (repo, globs) => { R.map(g => `${ticks}${g}${ticks}`) )(globs); const response = generateResponse(); - const repoPath = repo.workdir(); - return core.track(R.join(' ', filteredGlobs), { cwd: repoPath }) + return core.track(R.join(' ', filteredGlobs), { cwd: repo.workdir() }) .then(({ stdout, stderr }) => { response.raw = stdout; diff --git a/src/commands/untrack.js b/src/commands/untrack.js index a070e58..9db503c 100644 --- a/src/commands/untrack.js +++ b/src/commands/untrack.js @@ -23,9 +23,8 @@ const untrack = (repo, globs) => { R.map(g => `${ticks}${g}${ticks}`) )(globs); const response = generateResponse(); - const repoPath = repo.workdir(); - return core.untrack(R.join(' ', filteredGlobs), { cwd: repoPath }) + return core.untrack(R.join(' ', filteredGlobs), { cwd: repo.workdir() }) .then(({ stdout, stderr }) => { response.raw = stdout; diff --git a/src/initialize.js b/src/initialize.js index 09de2cf..bf926a8 100644 --- a/src/initialize.js +++ b/src/initialize.js @@ -19,7 +19,7 @@ const builldArgs = (options) => { const initialize = (repo, options) => { const workdir = repo.workdir(); - const lfsDir = path.join(workdir, '.git', 'lfs'); + const lfsDir = path.join(repo.path(), 'lfs'); return fse.pathExists(lfsDir) .then((exists) => { From 52890057d24245ca5d35e13b6ed5bdaa9a307b46 Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Tue, 15 Aug 2017 09:13:11 -0700 Subject: [PATCH 03/42] Replace Windows-incompatible random string generation method --- test/tests/callbacks/apply.spec.js | 10 ++++++---- test/tests/commands/push.spec.js | 7 +++++-- test/utils.js | 8 ++++++++ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/test/tests/callbacks/apply.spec.js b/test/tests/callbacks/apply.spec.js index 5464c94..dffbb16 100644 --- a/test/tests/callbacks/apply.spec.js +++ b/test/tests/callbacks/apply.spec.js @@ -1,8 +1,10 @@ import path from 'path'; import NodeGit from 'nodegit'; -import { todo } from '../../utils'; +import { + createDummyFile, + todo +} from '../../utils'; import LFS from '../../../build/src'; -import exec from '../../../build/src/utils/execHelper'; import track from '../../../build/src/commands/track'; const commitFile = (repo, fileName, commitMessage) => { @@ -48,7 +50,7 @@ describe('Apply', () => { return track(repo, ['*.md']); }) .then(() => NodeGitLFS.LFS.register()) - .then(() => exec('base64 /dev/urandom | head -c 20 > big_file_test.md', { cwd: lfsTestRepoPath })) + .then(() => createDummyFile(path.join(lfsTestRepoPath, 'big_file_test.md'), 20)) .then(() => commitFile(repository, 'big_file_test.md', 'LFS Clean Test')) .then(() => todo()); }); @@ -64,7 +66,7 @@ describe('Apply', () => { return repo; }) .then(() => NodeGitLFS.LFS.register()) - .then(() => exec('base64 /dev/urandom | head -c 20 > big_file_test.txt', { cwd: lfsTestRepoPath })) + .then(() => createDummyFile(path.join(lfsTestRepoPath, 'big_file_test.txt'), 20)) .then(() => { const opts = { checkoutStrategy: NodeGit.Checkout.STRATEGY.FORCE, diff --git a/test/tests/commands/push.spec.js b/test/tests/commands/push.spec.js index f0099d4..f0327c9 100644 --- a/test/tests/commands/push.spec.js +++ b/test/tests/commands/push.spec.js @@ -1,6 +1,9 @@ import path from 'path'; import NodeGit from 'nodegit'; -import { todo } from '../../utils'; +import { + createDummyFile, + todo +} from '../../utils'; import LFS from '../../../build/src'; import exec from '../../../build/src/utils/execHelper'; @@ -9,7 +12,7 @@ describe('Push', () => { const lfsTestRepoPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); const NodeGitLFS = LFS(NodeGit); - return exec('base64 /dev/urandom | head -c 20 > test_file.txt', { cwd: lfsTestRepoPath }) + return createDummyFile(path.join(lfsTestRepoPath, 'test_file.txt'), 20) .then(() => exec('git add test_file.txt', { cwd: lfsTestRepoPath })) .then(() => exec('git commit -m "LFS: push unit test"', { cwd: lfsTestRepoPath })) .then(() => NodeGitLFS.Repository.open(lfsTestRepoPath)) diff --git a/test/utils.js b/test/utils.js index 76215f4..cac8094 100644 --- a/test/utils.js +++ b/test/utils.js @@ -1,4 +1,12 @@ import { expect } from 'chai'; +import crypto from 'crypto'; +import fse from 'fs-extra'; + +export const createDummyFile = (fileName, length) => { + // https://github.com/sindresorhus/crypto-random-string/blob/master/index.js#L9 + const contents = crypto.randomBytes(Math.ceil(length / 2)).toString('hex').slice(0, length); + return fse.writeFile(fileName, contents); +}; export const fail = (msg) => { expect.fail(true, true, msg); From a5e228c1661404ec5094242189b3b3681eb0646a Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Tue, 15 Aug 2017 09:18:45 -0700 Subject: [PATCH 04/42] Bypass SSL validation in clone tests --- src/commands/clone.js | 1 + test/tests/commands/clone.spec.js | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/commands/clone.js b/src/commands/clone.js index 389f0bd..ebb91a3 100644 --- a/src/commands/clone.js +++ b/src/commands/clone.js @@ -66,6 +66,7 @@ function clone(url, cwd, options) { const { branch, callback, + env = {} } = (options || {}); const args = branch ? `-b ${branch}` : ''; diff --git a/test/tests/commands/clone.spec.js b/test/tests/commands/clone.spec.js index 3666265..237015d 100644 --- a/test/tests/commands/clone.spec.js +++ b/test/tests/commands/clone.spec.js @@ -7,9 +7,9 @@ describe('Clone', () => { it('should generate clone repsonse', () => { const emptyRepoPath = path.resolve(__dirname, '..', '..', 'repos', 'empty'); const NodeGitLFS = LFS(NodeGit); - const url = 'https://github.com/mohseenrm/nodegit-lfs-test-repo'; + const url = 'https://github.com/jgrosso/nodegit-lfs-test-repo'; - return NodeGitLFS.LFS.clone(url, emptyRepoPath, { branch: 'test' }) + return NodeGitLFS.LFS.clone(url, emptyRepoPath, { branch: 'test', env: { GIT_SSL_NO_VERIFY: 1 } }) .then(() => todo()); }); }); From cca19d12d22aa3498f00983dec51fa91318f6d09 Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Tue, 15 Aug 2017 10:56:57 -0700 Subject: [PATCH 05/42] Finish 'Apply clean' spec --- test/tests/callbacks/apply.spec.js | 40 ++++++++++++++++++++++++++---- test/utils.js | 9 ++++++- 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/test/tests/callbacks/apply.spec.js b/test/tests/callbacks/apply.spec.js index dffbb16..2eb1a69 100644 --- a/test/tests/callbacks/apply.spec.js +++ b/test/tests/callbacks/apply.spec.js @@ -1,11 +1,18 @@ -import path from 'path'; +import { + expect +} from 'chai'; +import fse from 'fs-extra'; import NodeGit from 'nodegit'; +import path from 'path'; + import { createDummyFile, + getFilePointer, todo } from '../../utils'; + import LFS from '../../../build/src'; -import track from '../../../build/src/commands/track'; +import trackCommand from '../../../build/src/commands/track'; const commitFile = (repo, fileName, commitMessage) => { let index; @@ -38,21 +45,44 @@ const commitFile = (repo, fileName, commitMessage) => { [parent])); }; +const track = (repo, globs) => { + let index; + + return trackCommand(repo, globs) + .then(() => repo.index()) + .then((_index) => { + index = _index; + return index.addByPath('.gitattributes'); + }) + .then(() => index.write()); +}; + describe('Apply', () => { - it('Clean', () => { + it.only('Clean', () => { const lfsTestRepoPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); const NodeGitLFS = LFS(NodeGit); let repository; + let dummyContents; return NodeGitLFS.Repository.open(lfsTestRepoPath) .then((repo) => { repository = repo; - return track(repo, ['*.md']); + return track(repo, ['big_file_test.md']); }) .then(() => NodeGitLFS.LFS.register()) .then(() => createDummyFile(path.join(lfsTestRepoPath, 'big_file_test.md'), 20)) + .then((contents) => { + dummyContents = contents; + }) .then(() => commitFile(repository, 'big_file_test.md', 'LFS Clean Test')) - .then(() => todo()); + .then(() => fse.readFile(path.join(lfsTestRepoPath, 'big_file_test.md'), 'utf8')) + .then((contents) => { + expect(contents).to.equal(dummyContents); + }) + .then(() => getFilePointer(lfsTestRepoPath, 'big_file_test.md')) + .then((pointer) => { + expect(pointer).to.have.string('size 20'); + }); }); it('Smudge', () => { diff --git a/test/utils.js b/test/utils.js index cac8094..54f99d0 100644 --- a/test/utils.js +++ b/test/utils.js @@ -2,10 +2,13 @@ import { expect } from 'chai'; import crypto from 'crypto'; import fse from 'fs-extra'; +import spawn from '../build/src/utils/spawnHelper'; + export const createDummyFile = (fileName, length) => { // https://github.com/sindresorhus/crypto-random-string/blob/master/index.js#L9 const contents = crypto.randomBytes(Math.ceil(length / 2)).toString('hex').slice(0, length); - return fse.writeFile(fileName, contents); + return fse.writeFile(fileName, contents) + .then(() => contents); }; export const fail = (msg) => { @@ -15,3 +18,7 @@ export const fail = (msg) => { export const todo = () => { fail('TODO'); }; + +export const getFilePointer = (workdir, fileName) => + spawn(`git show HEAD:${fileName}`, { cwd: workdir, env: { GIT_PAGER: 'cat' } }) + .then(({ stdout }) => stdout.toString()); From 52285321c51eb420105c16e66a76b25f3153a4c2 Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Tue, 15 Aug 2017 12:37:34 -0700 Subject: [PATCH 06/42] Finish 'Apply smudge' spec --- .eslintrc | 8 +-- test/tests/callbacks/apply.spec.js | 88 +++++++++++++++--------------- 2 files changed, 46 insertions(+), 50 deletions(-) diff --git a/.eslintrc b/.eslintrc index 1cfebea..fbbe2cd 100644 --- a/.eslintrc +++ b/.eslintrc @@ -12,15 +12,11 @@ "chai-friendly/no-unused-expressions": 2, "comma-dangle": 0, "consistent-return": 0, + "func-names": 0, "import/prefer-default-export": 0, "linebreak-style": 0, "no-bitwise": 0, "no-param-reassign": 0, - "no-unnamed-functions": 0, - "no-unused-expressions": 0, - - // this is for the tests, don't worrry about it for now - "import/no-unresolved": 1, - "import/extensions": 1 + "no-unused-expressions": 0 } } diff --git a/test/tests/callbacks/apply.spec.js b/test/tests/callbacks/apply.spec.js index 2eb1a69..52fce41 100644 --- a/test/tests/callbacks/apply.spec.js +++ b/test/tests/callbacks/apply.spec.js @@ -7,13 +7,14 @@ import path from 'path'; import { createDummyFile, - getFilePointer, - todo + getFilePointer } from '../../utils'; import LFS from '../../../build/src'; import trackCommand from '../../../build/src/commands/track'; +const NodeGitLFS = LFS(NodeGit); + const commitFile = (repo, fileName, commitMessage) => { let index; let treeOid; @@ -58,51 +59,50 @@ const track = (repo, globs) => { }; describe('Apply', () => { - it.only('Clean', () => { - const lfsTestRepoPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); - const NodeGitLFS = LFS(NodeGit); - let repository; - let dummyContents; + beforeEach(function () { + const testFileSize = 20; + + this.lfsTestRepoPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); + this.testFileName = 'bigFileTest.md'; - return NodeGitLFS.Repository.open(lfsTestRepoPath) - .then((repo) => { - repository = repo; - return track(repo, ['big_file_test.md']); - }) - .then(() => NodeGitLFS.LFS.register()) - .then(() => createDummyFile(path.join(lfsTestRepoPath, 'big_file_test.md'), 20)) - .then((contents) => { - dummyContents = contents; - }) - .then(() => commitFile(repository, 'big_file_test.md', 'LFS Clean Test')) - .then(() => fse.readFile(path.join(lfsTestRepoPath, 'big_file_test.md'), 'utf8')) - .then((contents) => { - expect(contents).to.equal(dummyContents); - }) - .then(() => getFilePointer(lfsTestRepoPath, 'big_file_test.md')) - .then((pointer) => { - expect(pointer).to.have.string('size 20'); - }); + this.verifyTestFileTracked = () => + fse.readFile(path.join(this.lfsTestRepoPath, this.testFileName), 'utf8') + .then((contents) => { + expect(contents).to.equal(this.dummyContents); + }) + .then(() => getFilePointer(this.lfsTestRepoPath, this.testFileName)) + .then((pointer) => { + expect(pointer).to.have.string(`size ${testFileSize}`); + }); + + this.trackTestFile = () => + NodeGitLFS.Repository.open(this.lfsTestRepoPath) + .then((repo) => { + this.repository = repo; + return track(repo, [this.testFileName]); + }) + .then(() => NodeGitLFS.LFS.register()) + .then(() => createDummyFile( + path.join(this.lfsTestRepoPath, this.testFileName), + testFileSize + )) + .then((contents) => { + this.dummyContents = contents; + }) + .then(() => commitFile(this.repository, this.testFileName, 'LFS filter tests')); }); - it('Smudge', () => { - const lfsTestRepoPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); - const NodeGitLFS = LFS(NodeGit); - let repository; + it('Clean', function () { + return this.trackTestFile() + .then(() => this.verifyTestFileTracked()); + }); - return NodeGitLFS.Repository.open(lfsTestRepoPath) - .then((repo) => { - repository = repo; - return repo; - }) - .then(() => NodeGitLFS.LFS.register()) - .then(() => createDummyFile(path.join(lfsTestRepoPath, 'big_file_test.txt'), 20)) - .then(() => { - const opts = { - checkoutStrategy: NodeGit.Checkout.STRATEGY.FORCE, - }; - return NodeGit.Checkout.head(repository, opts); - }) - .then(() => todo()); + it('Smudge', function () { + return this.trackTestFile() + .then(() => createDummyFile(path.join(this.lfsTestRepoPath, this.testFileName), 5)) + .then(() => NodeGit.Checkout.head(this.repository, { + checkoutStrategy: NodeGit.Checkout.STRATEGY.FORCE + })) + .then(() => this.verifyTestFileTracked()); }); }); From b60820961cad4a48d16c7f203b86c5e1073b3b49 Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Tue, 15 Aug 2017 14:45:52 -0700 Subject: [PATCH 07/42] Refactor 'Amend Check/Smudge' tests --- test/runner.js | 37 ++++---- test/tests/callbacks/apply.spec.js | 137 ++++++++++++++++------------- 2 files changed, 97 insertions(+), 77 deletions(-) diff --git a/test/runner.js b/test/runner.js index bd52a3a..5885624 100644 --- a/test/runner.js +++ b/test/runner.js @@ -9,46 +9,51 @@ const git = require('../build/src/commands/lfsCommands').core.git; const testLFSServer = require('./server/server'); const testReposPath = path.join(__dirname, 'repos'); -const lfsRepoPath = path.join(testReposPath, 'lfs-test-repository'); -const emptyRepoPath = path.join(testReposPath, 'empty'); - before(function () { // eslint-disable-line prefer-arrow-callback this.timeout(30000); + this.NodeGitLFS = LFS(NodeGit); + + this.emptyRepoPath = path.join(testReposPath, 'empty'); + this.lfsTestRepoPath = path.join(testReposPath, 'lfs-test-repository'); + const testRepoUrl = 'https://github.com/jgrosso/nodegit-lfs-test-repo'; return testLFSServer.start() .then(() => fse.remove(testReposPath)) .then(() => fse.mkdir(testReposPath)) - .then(() => fse.mkdir(lfsRepoPath)) - .then(() => fse.mkdir(emptyRepoPath)) - .then(() => git(`init ${emptyRepoPath}`)) - .then(() => git(`clone ${testRepoUrl} ${lfsRepoPath}`, { + .then(() => fse.mkdir(this.lfsTestRepoPath)) + .then(() => fse.mkdir(this.emptyRepoPath)) + .then(() => git(`init ${this.emptyRepoPath}`)) + .then(() => git(`clone ${testRepoUrl} ${this.lfsTestRepoPath}`, { env: { GIT_SSL_NO_VERIFY: 1 } })) .then(() => fse.appendFile( - path.join(lfsRepoPath, '.git', 'config'), + path.join(this.lfsTestRepoPath, '.git', 'config'), `[http] sslverify = false` )) - .catch((err) => { throw new Error(err); }); + .catch((err) => { + throw new Error(err); + }); }); -beforeEach(() => { - return exec('git clean -xdf && git reset --hard', { cwd: lfsRepoPath }) - .then(() => exec('git clean -xdff', { cwd: emptyRepoPath })); +beforeEach(function () { + return exec('git clean -xdf && git reset --hard', { cwd: this.lfsTestRepoPath }) + .then(() => exec('git clean -xdff', { cwd: this.emptyRepoPath })); }); after(() => { testLFSServer.stop(); }); -afterEach(() => { - const NodeGitLFS = LFS(NodeGit); - return NodeGitLFS.LFS.unregister() +afterEach(function () { + return this.NodeGitLFS.LFS.unregister() .catch((error) => { // -3 implies LFS filter was not registered - if (error.errno !== -3) { throw error; } + if (error.errno !== -3) { + throw error; + } }); }); diff --git a/test/tests/callbacks/apply.spec.js b/test/tests/callbacks/apply.spec.js index 52fce41..fb35d07 100644 --- a/test/tests/callbacks/apply.spec.js +++ b/test/tests/callbacks/apply.spec.js @@ -2,7 +2,6 @@ import { expect } from 'chai'; import fse from 'fs-extra'; -import NodeGit from 'nodegit'; import path from 'path'; import { @@ -10,42 +9,8 @@ import { getFilePointer } from '../../utils'; -import LFS from '../../../build/src'; import trackCommand from '../../../build/src/commands/track'; -const NodeGitLFS = LFS(NodeGit); - -const commitFile = (repo, fileName, commitMessage) => { - let index; - let treeOid; - let parent; - - return repo.refreshIndex() - .then((indexResult) => { - index = indexResult; - }) - .then(() => index.addByPath(fileName)) - .then(() => index.write()) - .then(() => index.writeTree()) - .then((oidResult) => { - treeOid = oidResult; - return NodeGit.Reference.nameToId(repo, 'HEAD'); - }) - .then(head => repo.getCommit(head)) - .then((parentResult) => { - parent = parentResult; - return NodeGit.Signature.default(repo); - }) - .then(signatures => - repo.createCommit( - 'HEAD', - signatures, - signatures, - commitMessage, - treeOid, - [parent])); -}; - const track = (repo, globs) => { let index; @@ -60,49 +25,99 @@ const track = (repo, globs) => { describe('Apply', () => { beforeEach(function () { - const testFileSize = 20; + const { + lfsTestRepoPath, + NodeGitLFS + } = this; - this.lfsTestRepoPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); + const testFileSize = 20; this.testFileName = 'bigFileTest.md'; - this.verifyTestFileTracked = () => - fse.readFile(path.join(this.lfsTestRepoPath, this.testFileName), 'utf8') - .then((contents) => { - expect(contents).to.equal(this.dummyContents); + this.commitFile = (repo, fileName, commitMessage) => { + let index; + let treeOid; + let parent; + + return repo.refreshIndex() + .then((indexResult) => { + index = indexResult; + }) + .then(() => index.addByPath(fileName)) + .then(() => index.write()) + .then(() => index.writeTree()) + .then((oidResult) => { + treeOid = oidResult; + return NodeGitLFS.Reference.nameToId(repo, 'HEAD'); }) - .then(() => getFilePointer(this.lfsTestRepoPath, this.testFileName)) - .then((pointer) => { - expect(pointer).to.have.string(`size ${testFileSize}`); - }); + .then(head => repo.getCommit(head)) + .then((parentResult) => { + parent = parentResult; + return NodeGitLFS.Signature.default(repo); + }) + .then(signatures => + repo.createCommit( + 'HEAD', + signatures, + signatures, + commitMessage, + treeOid, + [parent] + )); + }; this.trackTestFile = () => - NodeGitLFS.Repository.open(this.lfsTestRepoPath) - .then((repo) => { - this.repository = repo; - return track(repo, [this.testFileName]); - }) - .then(() => NodeGitLFS.LFS.register()) + track(this.repo, [this.testFileName]) .then(() => createDummyFile( - path.join(this.lfsTestRepoPath, this.testFileName), + path.join(lfsTestRepoPath, this.testFileName), testFileSize )) .then((contents) => { - this.dummyContents = contents; + this.contents = contents; }) - .then(() => commitFile(this.repository, this.testFileName, 'LFS filter tests')); + .then(() => this.commitFile(this.repo, this.testFileName, 'LFS filter tests')); + + this.verifyTestFileTracked = () => + fse.readFile(path.join(lfsTestRepoPath, this.testFileName), 'utf8') + .then((contents) => { + expect(contents).to.equal(this.contents); + }) + .then(() => getFilePointer(lfsTestRepoPath, this.testFileName)) + .then((pointer) => { + expect(pointer).to.have.string(`size ${testFileSize}`); + }); + + return NodeGitLFS.LFS.register() + .then(() => NodeGitLFS.Repository.open(lfsTestRepoPath)) + .then((repo) => { + this.repo = repo; + }); }); it('Clean', function () { - return this.trackTestFile() - .then(() => this.verifyTestFileTracked()); + const { + trackTestFile, + verifyTestFileTracked + } = this; + + return trackTestFile() + .then(() => verifyTestFileTracked()); }); it('Smudge', function () { - return this.trackTestFile() - .then(() => createDummyFile(path.join(this.lfsTestRepoPath, this.testFileName), 5)) - .then(() => NodeGit.Checkout.head(this.repository, { - checkoutStrategy: NodeGit.Checkout.STRATEGY.FORCE + const { + lfsTestRepoPath, + NodeGitLFS, + repo, + testFileName, + trackTestFile, + verifyTestFileTracked + } = this; + + return trackTestFile() + .then(() => createDummyFile(path.join(lfsTestRepoPath, testFileName), 5)) + .then(() => NodeGitLFS.Checkout.head(repo, { + checkoutStrategy: NodeGitLFS.Checkout.STRATEGY.FORCE })) - .then(() => this.verifyTestFileTracked()); + .then(() => verifyTestFileTracked()); }); }); From 5aa57ad071c0b711b82a640e020bc03ce82d7a14 Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Wed, 16 Aug 2017 14:48:58 -0700 Subject: [PATCH 08/42] Refactor out test constants --- test/constants.js | 7 +++++ test/runner.js | 47 +++++++++++++++++------------- test/tests/callbacks/apply.spec.js | 7 +++-- test/utils.js | 7 +++-- 4 files changed, 41 insertions(+), 27 deletions(-) create mode 100644 test/constants.js diff --git a/test/constants.js b/test/constants.js new file mode 100644 index 0000000..5cad4ef --- /dev/null +++ b/test/constants.js @@ -0,0 +1,7 @@ +import path from 'path'; + +export const testReposPath = path.join(__dirname, 'repos'); +export const emptyRepoPath = path.join(testReposPath, 'empty'); +export const lfsTestRepoPath = path.join(testReposPath, 'lfs-test-repository'); + +export const lfsTestRepoUrl = 'https://github.com/jgrosso/nodegit-lfs-test-repo'; diff --git a/test/runner.js b/test/runner.js index 5885624..a514192 100644 --- a/test/runner.js +++ b/test/runner.js @@ -1,36 +1,42 @@ -const fse = require('fs-extra'); -const path = require('path'); -const NodeGit = require('nodegit'); -const LFS = require('../build/src'); +import chai from 'chai'; +import fse from 'fs-extra'; +import path from 'path'; +import NodeGit from 'nodegit'; +import sinonChai from 'sinon-chai'; -const exec = require('../build/src/utils/execHelper').default; -const git = require('../build/src/commands/lfsCommands').core.git; +import { + core +} from '../build/src/commands/lfsCommands'; +import { + emptyRepoPath, + lfsTestRepoPath, + lfsTestRepoUrl, + testReposPath +} from './constants'; -const testLFSServer = require('./server/server'); +import LFS from '../build/src'; +import exec from '../build/src/utils/execHelper'; + +import * as testLFSServer from './server/server'; -const testReposPath = path.join(__dirname, 'repos'); before(function () { // eslint-disable-line prefer-arrow-callback this.timeout(30000); this.NodeGitLFS = LFS(NodeGit); - this.emptyRepoPath = path.join(testReposPath, 'empty'); - this.lfsTestRepoPath = path.join(testReposPath, 'lfs-test-repository'); - - const testRepoUrl = 'https://github.com/jgrosso/nodegit-lfs-test-repo'; return testLFSServer.start() .then(() => fse.remove(testReposPath)) .then(() => fse.mkdir(testReposPath)) - .then(() => fse.mkdir(this.lfsTestRepoPath)) - .then(() => fse.mkdir(this.emptyRepoPath)) - .then(() => git(`init ${this.emptyRepoPath}`)) - .then(() => git(`clone ${testRepoUrl} ${this.lfsTestRepoPath}`, { + .then(() => fse.mkdir(lfsTestRepoPath)) + .then(() => fse.mkdir(emptyRepoPath)) + .then(() => core.git(`init ${emptyRepoPath}`)) + .then(() => core.git(`clone ${lfsTestRepoUrl} ${lfsTestRepoPath}`, { env: { GIT_SSL_NO_VERIFY: 1 } })) .then(() => fse.appendFile( - path.join(this.lfsTestRepoPath, '.git', 'config'), + path.join(lfsTestRepoPath, '.git', 'config'), `[http] sslverify = false` )) @@ -39,10 +45,9 @@ before(function () { // eslint-disable-line prefer-arrow-callback }); }); -beforeEach(function () { - return exec('git clean -xdf && git reset --hard', { cwd: this.lfsTestRepoPath }) - .then(() => exec('git clean -xdff', { cwd: this.emptyRepoPath })); -}); +beforeEach(() => + exec('git clean -xdf && git reset --hard', { cwd: lfsTestRepoPath }) + .then(() => exec('git clean -xdff', { cwd: emptyRepoPath }))); after(() => { testLFSServer.stop(); diff --git a/test/tests/callbacks/apply.spec.js b/test/tests/callbacks/apply.spec.js index fb35d07..6f2324b 100644 --- a/test/tests/callbacks/apply.spec.js +++ b/test/tests/callbacks/apply.spec.js @@ -4,6 +4,9 @@ import { import fse from 'fs-extra'; import path from 'path'; +import { + lfsTestRepoPath +} from '../../constants'; import { createDummyFile, getFilePointer @@ -23,10 +26,9 @@ const track = (repo, globs) => { .then(() => index.write()); }; -describe('Apply', () => { +describe('apply', () => { beforeEach(function () { const { - lfsTestRepoPath, NodeGitLFS } = this; @@ -105,7 +107,6 @@ describe('Apply', () => { it('Smudge', function () { const { - lfsTestRepoPath, NodeGitLFS, repo, testFileName, diff --git a/test/utils.js b/test/utils.js index 54f99d0..dd7a044 100644 --- a/test/utils.js +++ b/test/utils.js @@ -15,10 +15,11 @@ export const fail = (msg) => { expect.fail(true, true, msg); }; +export const getFilePointer = (workdir, fileName) => + spawn(`git show HEAD:${fileName}`, { cwd: workdir, env: { GIT_PAGER: 'cat' } }) + .then(({ stdout }) => stdout.toString()); + export const todo = () => { fail('TODO'); }; -export const getFilePointer = (workdir, fileName) => - spawn(`git show HEAD:${fileName}`, { cwd: workdir, env: { GIT_PAGER: 'cat' } }) - .then(({ stdout }) => stdout.toString()); From 82c4cacfa0ac8d982dcc656d46c67ddb786430ce Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Wed, 16 Aug 2017 14:43:23 -0700 Subject: [PATCH 09/42] Finish `check` callback tests --- src/callbacks/check.js | 10 ++-- test/tests/callbacks/check.spec.js | 82 ++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 6 deletions(-) create mode 100644 test/tests/callbacks/check.spec.js diff --git a/src/callbacks/check.js b/src/callbacks/check.js index cea1dfb..573cf2e 100644 --- a/src/callbacks/check.js +++ b/src/callbacks/check.js @@ -8,11 +8,9 @@ export default src => loadGitattributeFiltersFromRepo(src.repo()) const file = src.path(); const filterIgnore = ignore().add(filters); - // these ignore rules are the closest to the .gitignore rules I have found - if (filterIgnore.ignores(file)) { - return Error.CODE.OK; - } - - return Error.CODE.PASSTHROUGH; + // The rules for `.gitignore` are close enough to those for `.gitattributes` + return filterIgnore.ignores(file) + ? Error.CODE.OK + : Error.CODE.PASSTHROUGH; }) .catch(() => Error.CODE.PASSTHROUGH); diff --git a/test/tests/callbacks/check.spec.js b/test/tests/callbacks/check.spec.js new file mode 100644 index 0000000..49b5a58 --- /dev/null +++ b/test/tests/callbacks/check.spec.js @@ -0,0 +1,82 @@ +import { + expect +} from 'chai'; +import { + Error +} from 'nodegit'; + +import { + lfsTestRepoPath +} from '../../constants'; + +import track from '../../../build/src/commands/track'; +import { check as checkCallback } from '../../../build/src/callbacks/check'; + +describe('check', () => { + beforeEach(function () { + const { + NodeGitLFS + } = this; + + this.check = fileName => checkCallback({ + path: () => fileName, + repo: () => this.repo + }); + + return NodeGitLFS.LFS.register() + .then(() => NodeGitLFS.Repository.open(lfsTestRepoPath)) + .then((repo) => { + this.repo = repo; + }); + }); + + it('returns `OK` for a file directly specified in .gitattributes', function () { + const { + check, + repo + } = this; + + return track(repo, ['test.txt']) + .then(() => check('test.txt')) + .then((result) => { + expect(result).to.equal(Error.CODE.OK); + }); + }); + + it('returns `OK` for a file included in a glob in .gitattributes', function () { + const { + check, + repo + } = this; + + return track(repo, ['*.txt']) + .then(() => check('test.txt')) + .then((result) => { + expect(result).to.equal(Error.CODE.OK); + }); + }); + + it('returns `PASSTHROUGH` for a file not included in .gitattributes', function () { + const { + check, + repo + } = this; + + return track(repo, ['other.txt']) + .then(() => check('test.txt')) + .then((result) => { + expect(result).to.equal(Error.CODE.PASSTHROUGH); + }); + }); + + it('returns `PASSTHROUGH` on error', function () { + const { + check + } = this; + + return check('test.txt') + .then((result) => { + expect(result).to.equal(Error.CODE.PASSTHROUGH); + }); + }); +}); From bb7482a0be2120ed8ec9ae6c5477981823f8bf83 Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Wed, 16 Aug 2017 14:47:51 -0700 Subject: [PATCH 10/42] Finish `initialize` callback tests --- test/tests/callbacks/initialize.check.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 test/tests/callbacks/initialize.check.js diff --git a/test/tests/callbacks/initialize.check.js b/test/tests/callbacks/initialize.check.js new file mode 100644 index 0000000..32569cc --- /dev/null +++ b/test/tests/callbacks/initialize.check.js @@ -0,0 +1,14 @@ +import { + expect +} from 'chai'; +import { + Error +} from 'nodegit'; + +import initialize from '../../../build/src/callbacks/initialize'; + +describe('Initialize', () => { + it('returns `OK`', () => { + expect(initialize()).to.equal(Error.CODE.OK); + }); +}); From 582544f6df951a1b8c87f3eb8775d3cd780bf1b7 Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Thu, 17 Aug 2017 08:54:36 -0700 Subject: [PATCH 11/42] Finish `execHelper` tests --- package.json | 4 +- test/runner.js | 2 + test/server/server.js | 80 +- test/tests/utils/execHelper.spec.js | 49 +- test/utils.js | 20 +- yarn.lock | 7149 ++++++++++++++------------- 6 files changed, 3714 insertions(+), 3590 deletions(-) diff --git a/package.json b/package.json index 886a620..f236246 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,9 @@ "jsdoc-to-markdown": "^3.0.0", "mocha": "^3.4.2", "nyc": "^11.0.3", - "prompt": "^1.0.0" + "prompt": "^1.0.0", + "sinon": "^3.2.0", + "sinon-chai": "^2.13.0" }, "dependencies": { "default-shell": "^1.0.1", diff --git a/test/runner.js b/test/runner.js index a514192..d1cb728 100644 --- a/test/runner.js +++ b/test/runner.js @@ -19,6 +19,8 @@ import exec from '../build/src/utils/execHelper'; import * as testLFSServer from './server/server'; +chai.use(sinonChai); + before(function () { // eslint-disable-line prefer-arrow-callback this.timeout(30000); diff --git a/test/server/server.js b/test/server/server.js index 73b290b..895923e 100644 --- a/test/server/server.js +++ b/test/server/server.js @@ -1,5 +1,7 @@ -const fse = require('fs-extra'); -const { spawn } = require('child_process'); +import fse from 'fs-extra'; +import { + spawn +} from 'child_process'; let serverPid = null; @@ -17,45 +19,43 @@ const getWin32BashCommand = () => { return `"${shPath}" `; }; -module.exports = { - start() { - if (serverPid) { - throw new Error('LFS test server has already been started!'); - } - - return new Promise((resolve, reject) => { - const cmdRunner = process.platform === 'win32' - ? getWin32BashCommand() - : './'; - const server = spawn(`${cmdRunner}start.sh`, { - cwd: __dirname, - shell: true - }); - server.stdout.on('data', (data) => { - // Store outputted server PID - const pid = data.toString().match(/pid=(\d+)/); - if (pid) { - serverPid = parseInt(pid[1], 10); - return resolve(); - } - - // Handle Go errors - const err = data.toString().match(/ err=(.*)/); - if (err) { - throw new Error(err[1]); - } - }); - server.stderr.on('data', (err) => { - throw new Error(err.toString()); - }); - }); - }, +export const start = () => { + if (serverPid) { + throw new Error('LFS test server has already been started!'); + } - stop() { - if (!serverPid) { - throw new Error("LFS test server hasn't been started!"); - } + return new Promise((resolve, reject) => { + const cmdRunner = process.platform === 'win32' + ? getWin32BashCommand() + : './'; + const server = spawn(`${cmdRunner}start.sh`, { + cwd: __dirname, + shell: true + }); + server.stdout.on('data', (data) => { + // Store outputted server PID + const pid = data.toString().match(/pid=(\d+)/); + if (pid) { + serverPid = parseInt(pid[1], 10); + return resolve(); + } + + // Handle Go errors + const err = data.toString().match(/ err=(.*)/); + if (err) { + throw new Error(err[1]); + } + }); + server.stderr.on('data', (err) => { + throw new Error(err.toString()); + }); + }); +}; - process.kill(serverPid, 'SIGKILL'); +export const stop = () => { + if (!serverPid) { + throw new Error("LFS test server hasn't been started!"); } + + process.kill(serverPid, 'SIGKILL'); }; diff --git a/test/tests/utils/execHelper.spec.js b/test/tests/utils/execHelper.spec.js index e7e3fe9..65c912f 100644 --- a/test/tests/utils/execHelper.spec.js +++ b/test/tests/utils/execHelper.spec.js @@ -1,9 +1,48 @@ -import { expect } from 'chai'; +import { + expect +} from 'chai'; +import childProcess from 'child_process'; + +import { + fail, + spyDescribe +} from '../../utils'; + import exec from '../../../src/utils/execHelper'; -describe('exec', () => { - it('returns a promise', () => { - const result = exec('woo', null, {}).catch(() => {}); - expect(result).to.be.a('Promise'); +spyDescribe('exec', (sandbox) => { + beforeEach(function () { + this.execSpy = sandbox.stub(childProcess, 'exec').returns('proc object'); + }); + + it('resolves with the spawned process and its stdout and stderr on success', function () { + const { + execSpy + } = this; + + const promise = exec('test', { foo: 'bar' }); + execSpy.firstCall.args[2](null, 'some stdout', 'some stderr'); + return promise + .then((result) => { + expect(result).to.eql({ + proc: 'proc object', + stderr: 'some stderr', + stdout: 'some stdout' + }); + }); + }); + + it('rejects with the error on failure', function () { + const { + execSpy + } = this; + + const promise = exec('test', { foo: 'bar' }); + execSpy.firstCall.args[2]('some error'); + return promise + .then(() => fail('Expected this promise to fail!')) + .catch((result) => { + expect(result).to.equal('some error'); + }); }); }); diff --git a/test/utils.js b/test/utils.js index dd7a044..f76d10a 100644 --- a/test/utils.js +++ b/test/utils.js @@ -1,6 +1,9 @@ -import { expect } from 'chai'; +import { + expect +} from 'chai'; import crypto from 'crypto'; import fse from 'fs-extra'; +import sinon from 'sinon'; import spawn from '../build/src/utils/spawnHelper'; @@ -17,9 +20,20 @@ export const fail = (msg) => { export const getFilePointer = (workdir, fileName) => spawn(`git show HEAD:${fileName}`, { cwd: workdir, env: { GIT_PAGER: 'cat' } }) - .then(({ stdout }) => stdout.toString()); + .then(({ stdout }) => stdout.toString()); + +export const spyDescribe = (message, fn) => { + const sandbox = sinon.createSandbox(); + + describe(message, () => { + fn(sandbox); + + afterEach(() => { + sandbox.restore(); + }); + }); +}; export const todo = () => { fail('TODO'); }; - diff --git a/yarn.lock b/yarn.lock index e0a228c..b31bb8f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1,3541 +1,3608 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -abbrev@1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.0.tgz#d0554c2256636e2f56e7c2e5ad183f859428d81f" - -acorn-jsx@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" - dependencies: - acorn "^3.0.4" - -acorn@^3.0.4, acorn@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" - -acorn@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.1.1.tgz#53fe161111f912ab999ee887a90a0bc52822fd75" - -ajv-keywords@^1.0.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" - -ajv@^4.7.0, ajv@^4.9.1: - version "4.11.8" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" - dependencies: - co "^4.6.0" - json-stable-stringify "^1.0.1" - -align-text@^0.1.1, align-text@^0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" - dependencies: - kind-of "^3.0.2" - longest "^1.0.1" - repeat-string "^1.5.2" - -amdefine@>=0.0.4: - version "1.0.1" - resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" - -ansi-escape-sequences@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-escape-sequences/-/ansi-escape-sequences-3.0.0.tgz#1c18394b6af9b76ff9a63509fa497669fd2ce53e" - dependencies: - array-back "^1.0.3" - -ansi-escape-sequences@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/ansi-escape-sequences/-/ansi-escape-sequences-4.0.0.tgz#e0ecb042958b71e42942d35c1fcf1d9b00a0f67e" - dependencies: - array-back "^2.0.0" - -ansi-escapes@^1.1.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - -ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - -anymatch@^1.3.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" - dependencies: - micromatch "^2.1.5" - normalize-path "^2.0.0" - -app-usage-stats@^0.5.0: - version "0.5.1" - resolved "https://registry.yarnpkg.com/app-usage-stats/-/app-usage-stats-0.5.1.tgz#6547c5db9bab0aa5f5b2c560eacc8af20d0ab13b" - dependencies: - array-back "^1.0.4" - home-path "^1.0.3" - test-value "^2.1.0" - usage-stats "^0.9.0" - -append-transform@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-0.4.0.tgz#d76ebf8ca94d276e247a36bad44a4b74ab611991" - dependencies: - default-require-extensions "^1.0.0" - -aproba@^1.0.3: - version "1.1.2" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.1.2.tgz#45c6629094de4e96f693ef7eab74ae079c240fc1" - -archy@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" - -are-we-there-yet@~1.1.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz#bb5dca382bb94f05e15194373d16fd3ba1ca110d" - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" - -argparse@^1.0.7: - version "1.0.9" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" - dependencies: - sprintf-js "~1.0.2" - -arr-diff@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" - dependencies: - arr-flatten "^1.0.1" - -arr-flatten@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - -array-back@^1.0.2, array-back@^1.0.3, array-back@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/array-back/-/array-back-1.0.4.tgz#644ba7f095f7ffcf7c43b5f0dc39d3c1f03c063b" - dependencies: - typical "^2.6.0" - -array-back@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/array-back/-/array-back-2.0.0.tgz#6877471d51ecc9c9bfa6136fb6c7d5fe69748022" - dependencies: - typical "^2.6.1" - -array-union@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" - dependencies: - array-uniq "^1.0.1" - -array-uniq@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" - -array-unique@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" - -arrify@^1.0.0, arrify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" - -asap@~2.0.3: - version "2.0.6" - resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" - -asn1@~0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - -assert-plus@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" - -assertion-error@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.0.2.tgz#13ca515d86206da0bac66e834dd397d87581094c" - -async-each@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" - -async@^1.4.0: - version "1.5.2" - resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" - -async@~0.2.6: - version "0.2.10" - resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" - -async@~0.9.0: - version "0.9.2" - resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" - -async@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/async/-/async-1.0.0.tgz#f8fc04ca3a13784ade9e1641af98578cfbd647a9" - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - -aws-sign2@~0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" - -aws4@^1.2.1: - version "1.6.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" - -babel-cli@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-cli/-/babel-cli-6.26.0.tgz#502ab54874d7db88ad00b887a06383ce03d002f1" - dependencies: - babel-core "^6.26.0" - babel-polyfill "^6.26.0" - babel-register "^6.26.0" - babel-runtime "^6.26.0" - commander "^2.11.0" - convert-source-map "^1.5.0" - fs-readdir-recursive "^1.0.0" - glob "^7.1.2" - lodash "^4.17.4" - output-file-sync "^1.1.2" - path-is-absolute "^1.0.1" - slash "^1.0.0" - source-map "^0.5.6" - v8flags "^2.1.1" - optionalDependencies: - chokidar "^1.6.1" - -babel-code-frame@^6.16.0, babel-code-frame@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" - dependencies: - chalk "^1.1.3" - esutils "^2.0.2" - js-tokens "^3.0.2" - -babel-core@^6.25.0, babel-core@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.0.tgz#af32f78b31a6fcef119c87b0fd8d9753f03a0bb8" - dependencies: - babel-code-frame "^6.26.0" - babel-generator "^6.26.0" - babel-helpers "^6.24.1" - babel-messages "^6.23.0" - babel-register "^6.26.0" - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - convert-source-map "^1.5.0" - debug "^2.6.8" - json5 "^0.5.1" - lodash "^4.17.4" - minimatch "^3.0.4" - path-is-absolute "^1.0.1" - private "^0.1.7" - slash "^1.0.0" - source-map "^0.5.6" - -babel-generator@^6.18.0, babel-generator@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.0.tgz#ac1ae20070b79f6e3ca1d3269613053774f20dc5" - dependencies: - babel-messages "^6.23.0" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - detect-indent "^4.0.0" - jsesc "^1.3.0" - lodash "^4.17.4" - source-map "^0.5.6" - trim-right "^1.0.1" - -babel-helper-call-delegate@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" - dependencies: - babel-helper-hoist-variables "^6.24.1" - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-define-map@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - -babel-helper-function-name@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" - dependencies: - babel-helper-get-function-arity "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-get-function-arity@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-hoist-variables@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-optimise-call-expression@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-regex@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" - dependencies: - babel-runtime "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - -babel-helper-replace-supers@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" - dependencies: - babel-helper-optimise-call-expression "^6.24.1" - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helpers@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" - dependencies: - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-messages@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-check-es2015-constants@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-arrow-functions@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-block-scoping@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" - dependencies: - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - -babel-plugin-transform-es2015-classes@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" - dependencies: - babel-helper-define-map "^6.24.1" - babel-helper-function-name "^6.24.1" - babel-helper-optimise-call-expression "^6.24.1" - babel-helper-replace-supers "^6.24.1" - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-computed-properties@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" - dependencies: - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-destructuring@^6.22.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-duplicate-keys@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-for-of@^6.22.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-function-name@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-literals@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-modules-amd@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" - dependencies: - babel-plugin-transform-es2015-modules-commonjs "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-modules-commonjs@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz#0d8394029b7dc6abe1a97ef181e00758dd2e5d8a" - dependencies: - babel-plugin-transform-strict-mode "^6.24.1" - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-types "^6.26.0" - -babel-plugin-transform-es2015-modules-systemjs@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" - dependencies: - babel-helper-hoist-variables "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-modules-umd@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" - dependencies: - babel-plugin-transform-es2015-modules-amd "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-object-super@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" - dependencies: - babel-helper-replace-supers "^6.24.1" - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-parameters@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" - dependencies: - babel-helper-call-delegate "^6.24.1" - babel-helper-get-function-arity "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-shorthand-properties@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-spread@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-sticky-regex@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" - dependencies: - babel-helper-regex "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-template-literals@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-typeof-symbol@^6.22.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-unicode-regex@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" - dependencies: - babel-helper-regex "^6.24.1" - babel-runtime "^6.22.0" - regexpu-core "^2.0.0" - -babel-plugin-transform-regenerator@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" - dependencies: - regenerator-transform "^0.10.0" - -babel-plugin-transform-strict-mode@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-polyfill@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153" - dependencies: - babel-runtime "^6.26.0" - core-js "^2.5.0" - regenerator-runtime "^0.10.5" - -babel-preset-es2015@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz#d44050d6bc2c9feea702aaf38d727a0210538939" - dependencies: - babel-plugin-check-es2015-constants "^6.22.0" - babel-plugin-transform-es2015-arrow-functions "^6.22.0" - babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" - babel-plugin-transform-es2015-block-scoping "^6.24.1" - babel-plugin-transform-es2015-classes "^6.24.1" - babel-plugin-transform-es2015-computed-properties "^6.24.1" - babel-plugin-transform-es2015-destructuring "^6.22.0" - babel-plugin-transform-es2015-duplicate-keys "^6.24.1" - babel-plugin-transform-es2015-for-of "^6.22.0" - babel-plugin-transform-es2015-function-name "^6.24.1" - babel-plugin-transform-es2015-literals "^6.22.0" - babel-plugin-transform-es2015-modules-amd "^6.24.1" - babel-plugin-transform-es2015-modules-commonjs "^6.24.1" - babel-plugin-transform-es2015-modules-systemjs "^6.24.1" - babel-plugin-transform-es2015-modules-umd "^6.24.1" - babel-plugin-transform-es2015-object-super "^6.24.1" - babel-plugin-transform-es2015-parameters "^6.24.1" - babel-plugin-transform-es2015-shorthand-properties "^6.24.1" - babel-plugin-transform-es2015-spread "^6.22.0" - babel-plugin-transform-es2015-sticky-regex "^6.24.1" - babel-plugin-transform-es2015-template-literals "^6.22.0" - babel-plugin-transform-es2015-typeof-symbol "^6.22.0" - babel-plugin-transform-es2015-unicode-regex "^6.24.1" - babel-plugin-transform-regenerator "^6.24.1" - -babel-register@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" - dependencies: - babel-core "^6.26.0" - babel-runtime "^6.26.0" - core-js "^2.5.0" - home-or-tmp "^2.0.0" - lodash "^4.17.4" - mkdirp "^0.5.1" - source-map-support "^0.4.15" - -babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" - dependencies: - core-js "^2.4.0" - regenerator-runtime "^0.11.0" - -babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" - dependencies: - babel-runtime "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - lodash "^4.17.4" - -babel-traverse@^6.18.0, babel-traverse@^6.24.1, babel-traverse@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" - dependencies: - babel-code-frame "^6.26.0" - babel-messages "^6.23.0" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - debug "^2.6.8" - globals "^9.18.0" - invariant "^2.2.2" - lodash "^4.17.4" - -babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" - dependencies: - babel-runtime "^6.26.0" - esutils "^2.0.2" - lodash "^4.17.4" - to-fast-properties "^1.0.3" - -babylon@^6.17.4, babylon@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - -bcrypt-pbkdf@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" - dependencies: - tweetnacl "^0.14.3" - -binary-extensions@^1.0.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.10.0.tgz#9aeb9a6c5e88638aad171e167f5900abe24835d0" - -block-stream@*: - version "0.0.9" - resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" - dependencies: - inherits "~2.0.0" - -bluebird@~3.4.6: - version "3.4.7" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.7.tgz#f72d760be09b7f76d08ed8fae98b289a8d05fab3" - -boom@2.x.x: - version "2.10.1" - resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" - dependencies: - hoek "2.x.x" - -brace-expansion@^1.1.7: - version "1.1.8" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^1.8.2: - version "1.8.5" - resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" - dependencies: - expand-range "^1.8.1" - preserve "^0.2.0" - repeat-element "^1.1.2" - -browser-stdout@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" - -builtin-modules@^1.0.0, builtin-modules@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" - -cache-point@^0.4.0, cache-point@~0.4.0: - version "0.4.1" - resolved "https://registry.yarnpkg.com/cache-point/-/cache-point-0.4.1.tgz#cc8c9cbd99d90d7b0c66910cd33d77a1aab8840e" - dependencies: - array-back "^2.0.0" - fs-then-native "^2.0.0" - mkdirp2 "^1.0.3" - -caching-transform@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/caching-transform/-/caching-transform-1.0.1.tgz#6dbdb2f20f8d8fbce79f3e94e9d1742dcdf5c0a1" - dependencies: - md5-hex "^1.2.0" - mkdirp "^0.5.1" - write-file-atomic "^1.1.4" - -caller-path@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" - dependencies: - callsites "^0.2.0" - -callsites@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" - -camelcase@^1.0.2: - version "1.2.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" - -camelcase@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" - -camelcase@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - -catharsis@~0.8.8: - version "0.8.9" - resolved "https://registry.yarnpkg.com/catharsis/-/catharsis-0.8.9.tgz#98cc890ca652dd2ef0e70b37925310ff9e90fc8b" - dependencies: - underscore-contrib "~0.3.0" - -center-align@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" - dependencies: - align-text "^0.1.3" - lazy-cache "^1.0.3" - -chai@^4.0.2: - version "4.1.1" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.1.1.tgz#66e21279e6f3c6415ff8231878227900e2171b39" - dependencies: - assertion-error "^1.0.1" - check-error "^1.0.1" - deep-eql "^2.0.1" - get-func-name "^2.0.0" - pathval "^1.0.0" - type-detect "^4.0.0" - -chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - dependencies: - ansi-styles "^2.2.1" - escape-string-regexp "^1.0.2" - has-ansi "^2.0.0" - strip-ansi "^3.0.0" - supports-color "^2.0.0" - -check-error@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" - -chokidar@^1.6.1: - version "1.7.0" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" - dependencies: - anymatch "^1.3.0" - async-each "^1.0.0" - glob-parent "^2.0.0" - inherits "^2.0.1" - is-binary-path "^1.0.0" - is-glob "^2.0.0" - path-is-absolute "^1.0.0" - readdirp "^2.0.0" - optionalDependencies: - fsevents "^1.0.0" - -circular-json@^0.3.1: - version "0.3.3" - resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" - -cli-cursor@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" - dependencies: - restore-cursor "^1.0.1" - -cli-width@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.1.0.tgz#b234ca209b29ef66fc518d9b98d5847b00edf00a" - -cliui@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" - dependencies: - center-align "^0.1.1" - right-align "^0.1.1" - wordwrap "0.0.2" - -cliui@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - wrap-ansi "^2.0.0" - -co@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - -collect-all@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/collect-all/-/collect-all-1.0.3.tgz#1abcc20448b58a1447487fcf34130e9512b0acf8" - dependencies: - stream-connect "^1.0.2" - stream-via "^1.0.4" - -colors@1.0.x: - version "1.0.3" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" - -colors@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" - -combined-stream@^1.0.5, combined-stream@~1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" - dependencies: - delayed-stream "~1.0.0" - -command-line-args@^4.0.1: - version "4.0.7" - resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-4.0.7.tgz#f8d1916ecb90e9e121eda6428e41300bfb64cc46" - dependencies: - array-back "^2.0.0" - find-replace "^1.0.3" - typical "^2.6.1" - -command-line-tool@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/command-line-tool/-/command-line-tool-0.7.0.tgz#ca80792ae2069cf7caa562c0cbc2cd11811122a0" - dependencies: - ansi-escape-sequences "^3.0.0" - array-back "^1.0.4" - command-line-args "^4.0.1" - command-line-usage "^4.0.0" - typical "^2.6.0" - -command-line-usage@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/command-line-usage/-/command-line-usage-4.0.1.tgz#d89cf16c8ae71e8e8a6e6aabae1652af76ff644e" - dependencies: - ansi-escape-sequences "^4.0.0" - array-back "^2.0.0" - table-layout "^0.4.1" - typical "^2.6.1" - -commander@2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" - dependencies: - graceful-readlink ">= 1.0.0" - -commander@^2.11.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" - -common-sequence@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/common-sequence/-/common-sequence-1.0.2.tgz#30e07f3f8f6f7f9b3dee854f20b2d39eee086de8" - -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - -concat-stream@^1.5.2: - version "1.6.0" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" - dependencies: - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - -config-master@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/config-master/-/config-master-3.1.0.tgz#667663590505a283bf26a484d68489d74c5485da" - dependencies: - walk-back "^2.0.1" - -console-control-strings@^1.0.0, console-control-strings@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - -contains-path@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" - -convert-source-map@^1.3.0, convert-source-map@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5" - -core-js@^2.4.0, core-js@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.0.tgz#569c050918be6486b3837552028ae0466b717086" - -core-util-is@1.0.2, core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - -cross-spawn@^4: - version "4.0.2" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" - dependencies: - lru-cache "^4.0.1" - which "^1.2.9" - -cross-spawn@^5.0.1: - version "5.1.0" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" - dependencies: - lru-cache "^4.0.1" - shebang-command "^1.2.0" - which "^1.2.9" - -cryptiles@2.x.x: - version "2.0.5" - resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" - dependencies: - boom "2.x.x" - -cycle@1.0.x: - version "1.0.3" - resolved "https://registry.yarnpkg.com/cycle/-/cycle-1.0.3.tgz#21e80b2be8580f98b468f379430662b046c34ad2" - -d@1: - version "1.0.0" - resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" - dependencies: - es5-ext "^0.10.9" - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - dependencies: - assert-plus "^1.0.0" - -debug-log@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/debug-log/-/debug-log-1.0.1.tgz#2307632d4c04382b8df8a32f70b895046d52745f" - -debug@2.6.8, debug@^2.1.1, debug@^2.2.0, debug@^2.6.3, debug@^2.6.8: - version "2.6.8" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" - dependencies: - ms "2.0.0" - -decamelize@^1.0.0, decamelize@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - -deep-eql@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-2.0.2.tgz#b1bac06e56f0a76777686d50c9feb75c2ed7679a" - dependencies: - type-detect "^3.0.0" - -deep-equal@~0.2.1: - version "0.2.2" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-0.2.2.tgz#84b745896f34c684e98f2ce0e42abaf43bba017d" - -deep-extend@~0.4.0: - version "0.4.2" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" - -deep-extend@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.5.0.tgz#6ef4a09b05f98b0e358d6d93d4ca3caec6672803" - -deep-is@~0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" - -default-require-extensions@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-1.0.0.tgz#f37ea15d3e13ffd9b437d33e1a75b5fb97874cb8" - dependencies: - strip-bom "^2.0.0" - -default-shell@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/default-shell/-/default-shell-1.0.1.tgz#752304bddc6174f49eb29cb988feea0b8813c8bc" - -defer-promise@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/defer-promise/-/defer-promise-1.0.1.tgz#1ca6ffeddbcef1715dd7aae25c7616f9ae22932f" - -del@^2.0.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" - dependencies: - globby "^5.0.0" - is-path-cwd "^1.0.0" - is-path-in-cwd "^1.0.0" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.0" - rimraf "^2.2.8" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - -detect-indent@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" - dependencies: - repeating "^2.0.0" - -diff@3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9" - -dmd@^3.0.0: - version "3.0.6" - resolved "https://registry.yarnpkg.com/dmd/-/dmd-3.0.6.tgz#94c0e0fb88d1cb6b82837595053de7919c753c25" - dependencies: - array-back "^1.0.4" - cache-point "^0.4.0" - common-sequence "^1.0.2" - file-set "^1.1.1" - handlebars "3.0.3" - marked "^0.3.6" - object-get "^2.1.0" - reduce-flatten "^1.0.1" - reduce-unique "^1.0.0" - reduce-without "^1.0.1" - test-value "^2.1.0" - walk-back "^3.0.0" - -doctrine@1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" - dependencies: - esutils "^2.0.2" - isarray "^1.0.0" - -doctrine@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.0.tgz#c73d8d2909d22291e1a007a395804da8b665fe63" - dependencies: - esutils "^2.0.2" - isarray "^1.0.0" - -ecc-jsbn@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" - dependencies: - jsbn "~0.1.0" - -error-ex@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" - dependencies: - is-arrayish "^0.2.1" - -es5-ext@^0.10.14, es5-ext@^0.10.9, es5-ext@~0.10.14: - version "0.10.27" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.27.tgz#bf926b058c62b1cb5de1a887930673b6aa6d9a66" - dependencies: - es6-iterator "2" - es6-symbol "~3.1" - -es6-iterator@2, es6-iterator@^2.0.1, es6-iterator@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.1.tgz#8e319c9f0453bf575d374940a655920e59ca5512" - dependencies: - d "1" - es5-ext "^0.10.14" - es6-symbol "^3.1" - -es6-map@^0.1.3: - version "0.1.5" - resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0" - dependencies: - d "1" - es5-ext "~0.10.14" - es6-iterator "~2.0.1" - es6-set "~0.1.5" - es6-symbol "~3.1.1" - event-emitter "~0.3.5" - -es6-set@~0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" - dependencies: - d "1" - es5-ext "~0.10.14" - es6-iterator "~2.0.1" - es6-symbol "3.1.1" - event-emitter "~0.3.5" - -es6-symbol@3.1.1, es6-symbol@^3.1, es6-symbol@^3.1.1, es6-symbol@~3.1, es6-symbol@~3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" - dependencies: - d "1" - es5-ext "~0.10.14" - -es6-weak-map@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f" - dependencies: - d "1" - es5-ext "^0.10.14" - es6-iterator "^2.0.1" - es6-symbol "^3.1.1" - -escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5, escape-string-regexp@~1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - -escope@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" - dependencies: - es6-map "^0.1.3" - es6-weak-map "^2.0.1" - esrecurse "^4.1.0" - estraverse "^4.1.1" - -eslint-config-airbnb-base@^11.2.0: - version "11.3.1" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-11.3.1.tgz#c0ab108c9beed503cb999e4c60f4ef98eda0ed30" - dependencies: - eslint-restricted-globals "^0.1.1" - -eslint-import-resolver-node@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.1.tgz#4422574cde66a9a7b099938ee4d508a199e0e3cc" - dependencies: - debug "^2.6.8" - resolve "^1.2.0" - -eslint-module-utils@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz#abaec824177613b8a95b299639e1b6facf473449" - dependencies: - debug "^2.6.8" - pkg-dir "^1.0.0" - -eslint-plugin-chai-friendly@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-chai-friendly/-/eslint-plugin-chai-friendly-0.4.0.tgz#aad72b4f0ea3cd2655dd92528f66bc7da7a8c9fe" - -eslint-plugin-import@^2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.7.0.tgz#21de33380b9efb55f5ef6d2e210ec0e07e7fa69f" - dependencies: - builtin-modules "^1.1.1" - contains-path "^0.1.0" - debug "^2.6.8" - doctrine "1.5.0" - eslint-import-resolver-node "^0.3.1" - eslint-module-utils "^2.1.1" - has "^1.0.1" - lodash.cond "^4.3.0" - minimatch "^3.0.3" - read-pkg-up "^2.0.0" - -eslint-plugin-mocha@^4.11.0: - version "4.11.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-mocha/-/eslint-plugin-mocha-4.11.0.tgz#91193a2f55e20a5e35974054a0089d30198ee578" - dependencies: - ramda "^0.24.1" - -eslint-restricted-globals@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz#35f0d5cbc64c2e3ed62e93b4b1a7af05ba7ed4d7" - -eslint@^3.19.0: - version "3.19.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.19.0.tgz#c8fc6201c7f40dd08941b87c085767386a679acc" - dependencies: - babel-code-frame "^6.16.0" - chalk "^1.1.3" - concat-stream "^1.5.2" - debug "^2.1.1" - doctrine "^2.0.0" - escope "^3.6.0" - espree "^3.4.0" - esquery "^1.0.0" - estraverse "^4.2.0" - esutils "^2.0.2" - file-entry-cache "^2.0.0" - glob "^7.0.3" - globals "^9.14.0" - ignore "^3.2.0" - imurmurhash "^0.1.4" - inquirer "^0.12.0" - is-my-json-valid "^2.10.0" - is-resolvable "^1.0.0" - js-yaml "^3.5.1" - json-stable-stringify "^1.0.0" - levn "^0.3.0" - lodash "^4.0.0" - mkdirp "^0.5.0" - natural-compare "^1.4.0" - optionator "^0.8.2" - path-is-inside "^1.0.1" - pluralize "^1.2.1" - progress "^1.1.8" - require-uncached "^1.0.2" - shelljs "^0.7.5" - strip-bom "^3.0.0" - strip-json-comments "~2.0.1" - table "^3.7.8" - text-table "~0.2.0" - user-home "^2.0.0" - -espree@^3.4.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.0.tgz#98358625bdd055861ea27e2867ea729faf463d8d" - dependencies: - acorn "^5.1.1" - acorn-jsx "^3.0.0" - -espree@~3.1.7: - version "3.1.7" - resolved "https://registry.yarnpkg.com/espree/-/espree-3.1.7.tgz#fd5deec76a97a5120a9cd3a7cb1177a0923b11d2" - dependencies: - acorn "^3.3.0" - acorn-jsx "^3.0.0" - -esprima@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" - -esquery@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.0.tgz#cfba8b57d7fba93f17298a8a006a04cda13d80fa" - dependencies: - estraverse "^4.0.0" - -esrecurse@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.0.tgz#fa9568d98d3823f9a41d91e902dcab9ea6e5b163" - dependencies: - estraverse "^4.1.0" - object-assign "^4.0.1" - -estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" - -esutils@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" - -event-emitter@~0.3.5: - version "0.3.5" - resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" - dependencies: - d "1" - es5-ext "~0.10.14" - -execa@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" - dependencies: - cross-spawn "^5.0.1" - get-stream "^3.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -exit-hook@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" - -expand-brackets@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" - dependencies: - is-posix-bracket "^0.1.0" - -expand-range@^1.8.1: - version "1.8.2" - resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" - dependencies: - fill-range "^2.1.0" - -extend@~3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" - -extglob@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" - dependencies: - is-extglob "^1.0.0" - -extsprintf@1.3.0, extsprintf@^1.2.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - -eyes@0.1.x: - version "0.1.8" - resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" - -fast-levenshtein@~2.0.4: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - -figures@^1.3.5: - version "1.7.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" - dependencies: - escape-string-regexp "^1.0.5" - object-assign "^4.1.0" - -file-entry-cache@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" - dependencies: - flat-cache "^1.2.1" - object-assign "^4.0.1" - -file-set@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/file-set/-/file-set-1.1.1.tgz#d3ec70c080ec8f18f204ba1de106780c9056926b" - dependencies: - array-back "^1.0.3" - glob "^7.1.0" - -filename-regex@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" - -fill-range@^2.1.0: - version "2.2.3" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" - dependencies: - is-number "^2.1.0" - isobject "^2.0.0" - randomatic "^1.1.3" - repeat-element "^1.1.2" - repeat-string "^1.5.2" - -find-cache-dir@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9" - dependencies: - commondir "^1.0.1" - mkdirp "^0.5.1" - pkg-dir "^1.0.0" - -find-replace@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-1.0.3.tgz#b88e7364d2d9c959559f388c66670d6130441fa0" - dependencies: - array-back "^1.0.4" - test-value "^2.1.0" - -find-up@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - dependencies: - path-exists "^2.0.0" - pinkie-promise "^2.0.0" - -find-up@^2.0.0, find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - dependencies: - locate-path "^2.0.0" - -flat-cache@^1.2.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.2.2.tgz#fa86714e72c21db88601761ecf2f555d1abc6b96" - dependencies: - circular-json "^0.3.1" - del "^2.0.2" - graceful-fs "^4.1.2" - write "^0.2.1" - -for-in@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - -for-own@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" - dependencies: - for-in "^1.0.1" - -foreground-child@^1.5.3, foreground-child@^1.5.6: - version "1.5.6" - resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-1.5.6.tgz#4fd71ad2dfde96789b980a5c0a295937cb2f5ce9" - dependencies: - cross-spawn "^4" - signal-exit "^3.0.0" - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - -form-data@~2.1.1: - version "2.1.4" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1" - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.5" - mime-types "^2.1.12" - -fs-extra@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-3.0.1.tgz#3794f378c58b342ea7dbbb23095109c4b3b62291" - dependencies: - graceful-fs "^4.1.2" - jsonfile "^3.0.0" - universalify "^0.1.0" - -fs-readdir-recursive@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.0.0.tgz#8cd1745c8b4f8a29c8caec392476921ba195f560" - -fs-then-native@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/fs-then-native/-/fs-then-native-2.0.0.tgz#19a124d94d90c22c8e045f2e8dd6ebea36d48c67" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - -fsevents@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.2.tgz#3282b713fb3ad80ede0e9fcf4611b5aa6fc033f4" - dependencies: - nan "^2.3.0" - node-pre-gyp "^0.6.36" - -fstream-ignore@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" - dependencies: - fstream "^1.0.0" - inherits "2" - minimatch "^3.0.0" - -fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.2: - version "1.0.11" - resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" - dependencies: - graceful-fs "^4.1.2" - inherits "~2.0.0" - mkdirp ">=0.5 0" - rimraf "2" - -function-bind@^1.0.2: - version "1.1.0" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.0.tgz#16176714c801798e4e8f2cf7f7529467bb4a5771" - -gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" - -generate-function@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" - -generate-object-property@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" - dependencies: - is-property "^1.0.0" - -get-caller-file@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" - -get-func-name@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" - -get-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - dependencies: - assert-plus "^1.0.0" - -glob-base@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" - dependencies: - glob-parent "^2.0.0" - is-glob "^2.0.0" - -glob-parent@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" - dependencies: - is-glob "^2.0.0" - -glob@7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.2" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.0, glob@^7.1.2: - version "7.1.2" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -globals@^9.14.0, globals@^9.18.0: - version "9.18.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" - -globby@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" - dependencies: - array-union "^1.0.1" - arrify "^1.0.0" - glob "^7.0.3" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.4, graceful-fs@^4.1.6, graceful-fs@^4.1.9: - version "4.1.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" - -"graceful-readlink@>= 1.0.0": - version "1.0.1" - resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" - -growl@1.9.2: - version "1.9.2" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f" - -handlebars@3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-3.0.3.tgz#0e09651a2f0fb3c949160583710d551f92e6d2ad" - dependencies: - optimist "^0.6.1" - source-map "^0.1.40" - optionalDependencies: - uglify-js "~2.3" - -handlebars@^4.0.3: - version "4.0.10" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.10.tgz#3d30c718b09a3d96f23ea4cc1f403c4d3ba9ff4f" - dependencies: - async "^1.4.0" - optimist "^0.6.1" - source-map "^0.4.4" - optionalDependencies: - uglify-js "^2.6" - -har-schema@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" - -har-validator@~4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a" - dependencies: - ajv "^4.9.1" - har-schema "^1.0.5" - -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - dependencies: - ansi-regex "^2.0.0" - -has-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" - -has-unicode@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - -has@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28" - dependencies: - function-bind "^1.0.2" - -hawk@~3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" - dependencies: - boom "2.x.x" - cryptiles "2.x.x" - hoek "2.x.x" - sntp "1.x.x" - -hoek@2.x.x: - version "2.16.3" - resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" - -home-or-tmp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.1" - -home-path@^1.0.3, home-path@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/home-path/-/home-path-1.0.5.tgz#788b29815b12d53bacf575648476e6f9041d133f" - -hosted-git-info@^2.1.4: - version "2.5.0" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c" - -http-signature@~1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" - dependencies: - assert-plus "^0.2.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -i@0.3.x: - version "0.3.5" - resolved "https://registry.yarnpkg.com/i/-/i-0.3.5.tgz#1d2b854158ec8169113c6cb7f6b6801e99e211d5" - -ignore@^3.2.0, ignore@^3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.3.tgz#432352e57accd87ab3110e82d3fea0e47812156d" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - -ini@~1.3.0: - version "1.3.4" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" - -inquirer@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e" - dependencies: - ansi-escapes "^1.1.0" - ansi-regex "^2.0.0" - chalk "^1.0.0" - cli-cursor "^1.0.1" - cli-width "^2.0.0" - figures "^1.3.5" - lodash "^4.3.0" - readline2 "^1.0.1" - run-async "^0.1.0" - rx-lite "^3.1.2" - string-width "^1.0.1" - strip-ansi "^3.0.0" - through "^2.3.6" - -interpret@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.3.tgz#cbc35c62eeee73f19ab7b10a801511401afc0f90" - -invariant@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" - dependencies: - loose-envify "^1.0.0" - -invert-kv@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - -is-binary-path@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" - dependencies: - binary-extensions "^1.0.0" - -is-buffer@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.5.tgz#1f3b26ef613b214b88cbca23cc6c01d87961eecc" - -is-builtin-module@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" - dependencies: - builtin-modules "^1.0.0" - -is-dotfile@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" - -is-equal-shallow@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" - dependencies: - is-primitive "^2.0.0" - -is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - -is-extglob@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" - -is-finite@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - -is-glob@^2.0.0, is-glob@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" - dependencies: - is-extglob "^1.0.0" - -is-my-json-valid@^2.10.0: - version "2.16.0" - resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz#f079dd9bfdae65ee2038aae8acbc86ab109e3693" - dependencies: - generate-function "^2.0.0" - generate-object-property "^1.1.0" - jsonpointer "^4.0.0" - xtend "^4.0.0" - -is-number@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" - dependencies: - kind-of "^3.0.2" - -is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - dependencies: - kind-of "^3.0.2" - -is-path-cwd@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" - -is-path-in-cwd@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz#6477582b8214d602346094567003be8a9eac04dc" - dependencies: - is-path-inside "^1.0.0" - -is-path-inside@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.0.tgz#fc06e5a1683fbda13de667aff717bbc10a48f37f" - dependencies: - path-is-inside "^1.0.1" - -is-posix-bracket@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" - -is-primitive@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" - -is-property@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" - -is-resolvable@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.0.tgz#8df57c61ea2e3c501408d100fb013cf8d6e0cc62" - dependencies: - tryit "^1.0.1" - -is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - -is-utf8@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" - -isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - dependencies: - isarray "1.0.0" - -isstream@0.1.x, isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - -istanbul-lib-coverage@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz#73bfb998885299415c93d38a3e9adf784a77a9da" - -istanbul-lib-hook@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.0.7.tgz#dd6607f03076578fe7d6f2a630cf143b49bacddc" - dependencies: - append-transform "^0.4.0" - -istanbul-lib-instrument@^1.7.4: - version "1.7.4" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.7.4.tgz#e9fd920e4767f3d19edc765e2d6b3f5ccbd0eea8" - dependencies: - babel-generator "^6.18.0" - babel-template "^6.16.0" - babel-traverse "^6.18.0" - babel-types "^6.18.0" - babylon "^6.17.4" - istanbul-lib-coverage "^1.1.1" - semver "^5.3.0" - -istanbul-lib-report@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz#f0e55f56655ffa34222080b7a0cd4760e1405fc9" - dependencies: - istanbul-lib-coverage "^1.1.1" - mkdirp "^0.5.1" - path-parse "^1.0.5" - supports-color "^3.1.2" - -istanbul-lib-source-maps@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.1.tgz#a6fe1acba8ce08eebc638e572e294d267008aa0c" - dependencies: - debug "^2.6.3" - istanbul-lib-coverage "^1.1.1" - mkdirp "^0.5.1" - rimraf "^2.6.1" - source-map "^0.5.3" - -istanbul-reports@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.1.1.tgz#042be5c89e175bc3f86523caab29c014e77fee4e" - dependencies: - handlebars "^4.0.3" - -js-tokens@^3.0.0, js-tokens@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" - -js-yaml@^3.5.1: - version "3.9.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.9.1.tgz#08775cebdfdd359209f0d2acd383c8f86a6904a0" - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -js2xmlparser@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/js2xmlparser/-/js2xmlparser-1.0.0.tgz#5a170f2e8d6476ce45405e04823242513782fe30" - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - -jsdoc-75lb@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/jsdoc-75lb/-/jsdoc-75lb-3.6.0.tgz#a807119528b4009ccbcab49b7522f63fec6cd0bd" - dependencies: - bluebird "~3.4.6" - catharsis "~0.8.8" - escape-string-regexp "~1.0.5" - espree "~3.1.7" - js2xmlparser "~1.0.0" - klaw "~1.3.0" - marked "~0.3.6" - mkdirp "~0.5.1" - requizzle "~0.2.1" - strip-json-comments "~2.0.1" - taffydb "2.6.2" - underscore "~1.8.3" - -jsdoc-api@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/jsdoc-api/-/jsdoc-api-3.0.0.tgz#0d52700235f865bd4a8bad5ebc1efb562fc8ad2a" - dependencies: - array-back "^1.0.4" - cache-point "~0.4.0" - collect-all "^1.0.2" - file-set "^1.1.1" - fs-then-native "^2.0.0" - jsdoc-75lb "^3.6.0" - object-to-spawn-args "^1.1.0" - temp-path "^1.0.0" - walk-back "^2.0.1" - -jsdoc-parse@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/jsdoc-parse/-/jsdoc-parse-3.0.0.tgz#271531d88f19df2520b1632a7f6c989441a87fde" - dependencies: - array-back "^1.0.4" - lodash.omit "^4.5.0" - lodash.pick "^4.4.0" - reduce-extract "^1.0.0" - sort-array "^1.1.1" - test-value "^2.1.0" - -jsdoc-to-markdown@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/jsdoc-to-markdown/-/jsdoc-to-markdown-3.0.0.tgz#cc8a94f1f412ac1da4bac1657475b0975ee8161a" - dependencies: - array-back "^1.0.4" - command-line-tool "^0.7.0" - config-master "^3.0.0" - dmd "^3.0.0" - jsdoc-api "^3.0.0" - jsdoc-parse "^3.0.0" - jsdoc2md-stats "^2.0.0" - walk-back "^2.0.1" - -jsdoc2md-stats@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/jsdoc2md-stats/-/jsdoc2md-stats-2.0.1.tgz#bd8343734cfe69ea8050a17931251293f0d9047b" - dependencies: - app-usage-stats "^0.5.0" - -jsesc@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" - -jsesc@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - -json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" - dependencies: - jsonify "~0.0.0" - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - -json3@3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" - -json5@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" - -jsonfile@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-3.0.1.tgz#a5ecc6f65f53f662c4415c7675a0331d0992ec66" - optionalDependencies: - graceful-fs "^4.1.6" - -jsonify@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" - -jsonpointer@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" - -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - -kind-of@^3.0.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - dependencies: - is-buffer "^1.1.5" - -kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - dependencies: - is-buffer "^1.1.5" - -klaw@~1.3.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" - optionalDependencies: - graceful-fs "^4.1.9" - -lazy-cache@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" - -lcid@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" - dependencies: - invert-kv "^1.0.0" - -levn@^0.3.0, levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - -load-json-file@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - pinkie-promise "^2.0.0" - strip-bom "^2.0.0" - -load-json-file@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - strip-bom "^3.0.0" - -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - -lodash._baseassign@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" - dependencies: - lodash._basecopy "^3.0.0" - lodash.keys "^3.0.0" - -lodash._basecopy@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" - -lodash._basecreate@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz#1bc661614daa7fc311b7d03bf16806a0213cf821" - -lodash._getnative@^3.0.0: - version "3.9.1" - resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" - -lodash._isiterateecall@^3.0.0: - version "3.0.9" - resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" - -lodash.cond@^4.3.0: - version "4.5.2" - resolved "https://registry.yarnpkg.com/lodash.cond/-/lodash.cond-4.5.2.tgz#f471a1da486be60f6ab955d17115523dd1d255d5" - -lodash.create@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/lodash.create/-/lodash.create-3.1.1.tgz#d7f2849f0dbda7e04682bb8cd72ab022461debe7" - dependencies: - lodash._baseassign "^3.0.0" - lodash._basecreate "^3.0.0" - lodash._isiterateecall "^3.0.0" - -lodash.isarguments@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" - -lodash.isarray@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" - -lodash.keys@^3.0.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" - dependencies: - lodash._getnative "^3.0.0" - lodash.isarguments "^3.0.0" - lodash.isarray "^3.0.0" - -lodash.omit@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.omit/-/lodash.omit-4.5.0.tgz#6eb19ae5a1ee1dd9df0b969e66ce0b7fa30b5e60" - -lodash.padend@^4.6.1: - version "4.6.1" - resolved "https://registry.yarnpkg.com/lodash.padend/-/lodash.padend-4.6.1.tgz#53ccba047d06e158d311f45da625f4e49e6f166e" - -lodash.pick@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" - -lodash@^4.0.0, lodash@^4.17.4, lodash@^4.3.0: - version "4.17.4" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" - -longest@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" - -loose-envify@^1.0.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" - dependencies: - js-tokens "^3.0.0" - -lru-cache@^4.0.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55" - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - -marked@^0.3.6, marked@~0.3.6: - version "0.3.6" - resolved "https://registry.yarnpkg.com/marked/-/marked-0.3.6.tgz#b2c6c618fccece4ef86c4fc6cb8a7cbf5aeda8d7" - -md5-hex@^1.2.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-1.3.0.tgz#d2c4afe983c4370662179b8cad145219135046c4" - dependencies: - md5-o-matic "^0.1.1" - -md5-o-matic@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/md5-o-matic/-/md5-o-matic-0.1.1.tgz#822bccd65e117c514fab176b25945d54100a03c3" - -mem@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" - dependencies: - mimic-fn "^1.0.0" - -merge-source-map@^1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.0.4.tgz#a5de46538dae84d4114cc5ea02b4772a6346701f" - dependencies: - source-map "^0.5.6" - -micromatch@^2.1.5, micromatch@^2.3.11: - version "2.3.11" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" - dependencies: - arr-diff "^2.0.0" - array-unique "^0.2.1" - braces "^1.8.2" - expand-brackets "^0.1.4" - extglob "^0.3.1" - filename-regex "^2.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.1" - kind-of "^3.0.2" - normalize-path "^2.0.1" - object.omit "^2.0.0" - parse-glob "^3.0.4" - regex-cache "^0.4.2" - -mime-db@~1.29.0: - version "1.29.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.29.0.tgz#48d26d235589651704ac5916ca06001914266878" - -mime-types@^2.1.12, mime-types@~2.1.7: - version "2.1.16" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.16.tgz#2b858a52e5ecd516db897ac2be87487830698e23" - dependencies: - mime-db "~1.29.0" - -mimic-fn@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18" - -minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - dependencies: - brace-expansion "^1.1.7" - -minimist@0.0.8, minimist@~0.0.1: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - -minimist@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - -mkdirp2@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/mkdirp2/-/mkdirp2-1.0.3.tgz#cc8dd8265f1f06e2d8f5b10b6e52f4e050bed21b" - -mkdirp@0.5.1, mkdirp@0.x.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - dependencies: - minimist "0.0.8" - -mocha@^3.4.2: - version "3.5.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-3.5.0.tgz#1328567d2717f997030f8006234bce9b8cd72465" - dependencies: - browser-stdout "1.3.0" - commander "2.9.0" - debug "2.6.8" - diff "3.2.0" - escape-string-regexp "1.0.5" - glob "7.1.1" - growl "1.9.2" - json3 "3.3.2" - lodash.create "3.1.1" - mkdirp "0.5.1" - supports-color "3.1.2" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - -mute-stream@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" - -mute-stream@~0.0.4: - version "0.0.7" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" - -nan@^2.3.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.5.0.tgz#aa8f1e34531d807e9e27755b234b4a6ec0c152a8" - -nan@^2.6.2: - version "2.7.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.7.0.tgz#d95bf721ec877e08db276ed3fc6eb78f9083ad46" - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - -ncp@1.0.x: - version "1.0.1" - resolved "https://registry.yarnpkg.com/ncp/-/ncp-1.0.1.tgz#d15367e5cb87432ba117d2bf80fdf45aecfb4246" - -node-pre-gyp@^0.6.36: - version "0.6.36" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.36.tgz#db604112cb74e0d477554e9b505b17abddfab786" - dependencies: - mkdirp "^0.5.1" - nopt "^4.0.1" - npmlog "^4.0.2" - rc "^1.1.7" - request "^2.81.0" - rimraf "^2.6.1" - semver "^5.3.0" - tar "^2.2.1" - tar-pack "^3.4.0" - -"node-pty@github:implausible/node-pty#57f5f4ef6b751ffcd056fb6f2b626a0a0d804301": - version "0.7.0" - resolved "https://codeload.github.com/implausible/node-pty/tar.gz/57f5f4ef6b751ffcd056fb6f2b626a0a0d804301" - dependencies: - nan "^2.6.2" - -nodegit-promise@~4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/nodegit-promise/-/nodegit-promise-4.0.0.tgz#5722b184f2df7327161064a791d2e842c9167b34" - dependencies: - asap "~2.0.3" - -nopt@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" - dependencies: - abbrev "1" - osenv "^0.1.4" - -normalize-package-data@^2.3.2: - version "2.4.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" - dependencies: - hosted-git-info "^2.1.4" - is-builtin-module "^1.0.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -normalize-path@^2.0.0, normalize-path@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - dependencies: - remove-trailing-separator "^1.0.1" - -npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - dependencies: - path-key "^2.0.0" - -npmlog@^4.0.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - -nyc@^11.0.3: - version "11.1.0" - resolved "https://registry.yarnpkg.com/nyc/-/nyc-11.1.0.tgz#d6b3c5e16892a25af63138ba484676aa8a22eda7" - dependencies: - archy "^1.0.0" - arrify "^1.0.1" - caching-transform "^1.0.0" - convert-source-map "^1.3.0" - debug-log "^1.0.1" - default-require-extensions "^1.0.0" - find-cache-dir "^0.1.1" - find-up "^2.1.0" - foreground-child "^1.5.3" - glob "^7.0.6" - istanbul-lib-coverage "^1.1.1" - istanbul-lib-hook "^1.0.7" - istanbul-lib-instrument "^1.7.4" - istanbul-lib-report "^1.1.1" - istanbul-lib-source-maps "^1.2.1" - istanbul-reports "^1.1.1" - md5-hex "^1.2.0" - merge-source-map "^1.0.2" - micromatch "^2.3.11" - mkdirp "^0.5.0" - resolve-from "^2.0.0" - rimraf "^2.5.4" - signal-exit "^3.0.1" - spawn-wrap "^1.3.8" - test-exclude "^4.1.1" - yargs "^8.0.1" - yargs-parser "^5.0.0" - -oauth-sign@~0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" - -object-assign@^4.0.1, object-assign@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - -object-get@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/object-get/-/object-get-2.1.0.tgz#722bbdb60039efa47cad3c6dc2ce51a85c02c5ae" - -object-to-spawn-args@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-to-spawn-args/-/object-to-spawn-args-1.1.1.tgz#77da8827f073d011c9e1b173f895781470246785" - -object.omit@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" - dependencies: - for-own "^0.1.4" - is-extendable "^0.1.1" - -once@^1.3.0, once@^1.3.3: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - dependencies: - wrappy "1" - -onetime@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" - -optimist@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" - dependencies: - minimist "~0.0.1" - wordwrap "~0.0.2" - -optimist@~0.3.5: - version "0.3.7" - resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.3.7.tgz#c90941ad59e4273328923074d2cf2e7cbc6ec0d9" - dependencies: - wordwrap "~0.0.2" - -optionator@^0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.4" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - wordwrap "~1.0.0" - -os-homedir@^1.0.0, os-homedir@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - -os-locale@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" - dependencies: - execa "^0.7.0" - lcid "^1.0.0" - mem "^1.1.0" - -os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - -osenv@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.4.tgz#42fe6d5953df06c8064be6f176c3d05aaaa34644" - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.0" - -output-file-sync@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/output-file-sync/-/output-file-sync-1.1.2.tgz#d0a33eefe61a205facb90092e826598d5245ce76" - dependencies: - graceful-fs "^4.1.4" - mkdirp "^0.5.1" - object-assign "^4.1.0" - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - -p-limit@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.1.0.tgz#b07ff2d9a5d88bec806035895a2bab66a27988bc" - -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - dependencies: - p-limit "^1.1.0" - -parse-glob@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" - dependencies: - glob-base "^0.3.0" - is-dotfile "^1.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.0" - -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - dependencies: - error-ex "^1.2.0" - -path-exists@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - dependencies: - pinkie-promise "^2.0.0" - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - -path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - -path-is-inside@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" - -path-key@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - -path-parse@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" - -path-type@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" - dependencies: - graceful-fs "^4.1.2" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -path-type@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" - dependencies: - pify "^2.0.0" - -pathval@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" - -performance-now@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" - -pify@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - dependencies: - pinkie "^2.0.0" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - -pkg-dir@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" - dependencies: - find-up "^1.0.0" - -pkginfo@0.3.x: - version "0.3.1" - resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.3.1.tgz#5b29f6a81f70717142e09e765bbeab97b4f81e21" - -pkginfo@0.x.x: - version "0.4.0" - resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.4.0.tgz#349dbb7ffd38081fcadc0853df687f0c7744cd65" - -pluralize@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45" - -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - -preserve@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" - -private@^0.1.6, private@^0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/private/-/private-0.1.7.tgz#68ce5e8a1ef0a23bb570cc28537b5332aba63ef1" - -process-nextick-args@~1.0.6: - version "1.0.7" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" - -progress@^1.1.8: - version "1.1.8" - resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" - -promisify-node@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/promisify-node/-/promisify-node-0.4.0.tgz#32803874ec411784e4786c339902a87a179a469c" - dependencies: - nodegit-promise "~4.0.0" - object-assign "^4.0.1" - -prompt@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/prompt/-/prompt-1.0.0.tgz#8e57123c396ab988897fb327fd3aedc3e735e4fe" - dependencies: - colors "^1.1.2" - pkginfo "0.x.x" - read "1.0.x" - revalidator "0.1.x" - utile "0.3.x" - winston "2.1.x" - -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - -punycode@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - -qs@~6.4.0: - version "6.4.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" - -ramda@^0.24.1: - version "0.24.1" - resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.24.1.tgz#c3b7755197f35b8dc3502228262c4c91ddb6b857" - -randomatic@^1.1.3: - version "1.1.7" - resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - -rc@^1.1.7: - version "1.2.1" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.1.tgz#2e03e8e42ee450b8cb3dce65be1bf8974e1dfd95" - dependencies: - deep-extend "~0.4.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - -read-pkg-up@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" - dependencies: - find-up "^1.0.0" - read-pkg "^1.0.0" - -read-pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" - dependencies: - find-up "^2.0.0" - read-pkg "^2.0.0" - -read-pkg@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" - dependencies: - load-json-file "^1.0.0" - normalize-package-data "^2.3.2" - path-type "^1.0.0" - -read-pkg@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" - dependencies: - load-json-file "^2.0.0" - normalize-package-data "^2.3.2" - path-type "^2.0.0" - -read@1.0.x: - version "1.0.7" - resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" - dependencies: - mute-stream "~0.0.4" - -readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.2.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~1.0.6" - safe-buffer "~5.1.1" - string_decoder "~1.0.3" - util-deprecate "~1.0.1" - -readdirp@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" - dependencies: - graceful-fs "^4.1.2" - minimatch "^3.0.2" - readable-stream "^2.0.2" - set-immediate-shim "^1.0.1" - -readline2@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35" - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - mute-stream "0.0.5" - -rechoir@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" - dependencies: - resolve "^1.1.6" - -reduce-extract@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/reduce-extract/-/reduce-extract-1.0.0.tgz#67f2385beda65061b5f5f4312662e8b080ca1525" - dependencies: - test-value "^1.0.1" - -reduce-flatten@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/reduce-flatten/-/reduce-flatten-1.0.1.tgz#258c78efd153ddf93cb561237f61184f3696e327" - -reduce-unique@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/reduce-unique/-/reduce-unique-1.0.0.tgz#7e586bcf87a4e32b6d7abd8277fad6cdec9f4803" - -reduce-without@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/reduce-without/-/reduce-without-1.0.1.tgz#68ad0ead11855c9a37d4e8256c15bbf87972fc8c" - dependencies: - test-value "^2.0.0" - -regenerate@^1.2.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.2.tgz#d1941c67bad437e1be76433add5b385f95b19260" - -regenerator-runtime@^0.10.5: - version "0.10.5" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" - -regenerator-runtime@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz#7e54fe5b5ccd5d6624ea6255c3473be090b802e1" - -regenerator-transform@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.0.tgz#f9ab3eac9cc2de38431d996a6a8abf1c50f2e459" - dependencies: - babel-runtime "^6.18.0" - babel-types "^6.19.0" - private "^0.1.6" - -regex-cache@^0.4.2: - version "0.4.3" - resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.3.tgz#9b1a6c35d4d0dfcef5711ae651e8e9d3d7114145" - dependencies: - is-equal-shallow "^0.1.3" - is-primitive "^2.0.0" - -regexpu-core@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" - dependencies: - regenerate "^1.2.1" - regjsgen "^0.2.0" - regjsparser "^0.1.4" - -regjsgen@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" - -regjsparser@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" - dependencies: - jsesc "~0.5.0" - -remove-trailing-separator@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - -repeat-element@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" - -repeat-string@^1.5.2: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - -repeating@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" - dependencies: - is-finite "^1.0.0" - -req-then@^0.6.4: - version "0.6.4" - resolved "https://registry.yarnpkg.com/req-then/-/req-then-0.6.4.tgz#9f9c04626afd311ae01d727846a0a1075c0e1965" - dependencies: - array-back "^2.0.0" - defer-promise "^1.0.1" - lodash.pick "^4.4.0" - stream-read-all "^0.1.0" - typical "^2.6.1" - -request@^2.81.0: - version "2.81.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" - dependencies: - aws-sign2 "~0.6.0" - aws4 "^1.2.1" - caseless "~0.12.0" - combined-stream "~1.0.5" - extend "~3.0.0" - forever-agent "~0.6.1" - form-data "~2.1.1" - har-validator "~4.2.1" - hawk "~3.1.3" - http-signature "~1.1.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.7" - oauth-sign "~0.8.1" - performance-now "^0.2.0" - qs "~6.4.0" - safe-buffer "^5.0.1" - stringstream "~0.0.4" - tough-cookie "~2.3.0" - tunnel-agent "^0.6.0" - uuid "^3.0.0" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - -require-main-filename@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" - -require-uncached@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" - dependencies: - caller-path "^0.1.0" - resolve-from "^1.0.0" - -requizzle@~0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/requizzle/-/requizzle-0.2.1.tgz#6943c3530c4d9a7e46f1cddd51c158fc670cdbde" - dependencies: - underscore "~1.6.0" - -resolve-from@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" - -resolve-from@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57" - -resolve@^1.1.6, resolve@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.4.0.tgz#a75be01c53da25d934a98ebd0e4c4a7312f92a86" - dependencies: - path-parse "^1.0.5" - -restore-cursor@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" - dependencies: - exit-hook "^1.0.0" - onetime "^1.0.0" - -revalidator@0.1.x: - version "0.1.8" - resolved "https://registry.yarnpkg.com/revalidator/-/revalidator-0.1.8.tgz#fece61bfa0c1b52a206bd6b18198184bdd523a3b" - -right-align@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" - dependencies: - align-text "^0.1.1" - -rimraf@2, rimraf@2.x.x, rimraf@^2.2.8, rimraf@^2.3.3, rimraf@^2.5.1, rimraf@^2.5.4, rimraf@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d" - dependencies: - glob "^7.0.5" - -run-async@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389" - dependencies: - once "^1.3.0" - -rx-lite@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" - -safe-buffer@^5.0.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" - -"semver@2 || 3 || 4 || 5", semver@^5.3.0: - version "5.4.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" - -set-blocking@^2.0.0, set-blocking@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - -set-immediate-shim@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" - -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - dependencies: - shebang-regex "^1.0.0" - -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - -shelljs@^0.7.5: - version "0.7.8" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3" - dependencies: - glob "^7.0.0" - interpret "^1.0.0" - rechoir "^0.6.2" - -signal-exit@^3.0.0, signal-exit@^3.0.1, signal-exit@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - -slash@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" - -slice-ansi@0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" - -slide@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" - -sntp@1.x.x: - version "1.0.9" - resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" - dependencies: - hoek "2.x.x" - -sort-array@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/sort-array/-/sort-array-1.1.2.tgz#b88986053c0170a7f9de63f18a49ec79c24c3e64" - dependencies: - array-back "^1.0.4" - object-get "^2.1.0" - typical "^2.6.0" - -source-map-support@^0.4.15: - version "0.4.15" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.15.tgz#03202df65c06d2bd8c7ec2362a193056fef8d3b1" - dependencies: - source-map "^0.5.6" - -source-map@^0.1.40, source-map@~0.1.7: - version "0.1.43" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" - dependencies: - amdefine ">=0.0.4" - -source-map@^0.4.4: - version "0.4.4" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" - dependencies: - amdefine ">=0.0.4" - -source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1: - version "0.5.6" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" - -spawn-wrap@^1.3.8: - version "1.3.8" - resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-1.3.8.tgz#fa2a79b990cbb0bb0018dca6748d88367b19ec31" - dependencies: - foreground-child "^1.5.6" - mkdirp "^0.5.0" - os-homedir "^1.0.1" - rimraf "^2.3.3" - signal-exit "^3.0.2" - which "^1.2.4" - -spdx-correct@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" - dependencies: - spdx-license-ids "^1.0.2" - -spdx-expression-parse@~1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c" - -spdx-license-ids@^1.0.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - -sshpk@^1.7.0: - version "1.13.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3" - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - dashdash "^1.12.0" - getpass "^0.1.1" - optionalDependencies: - bcrypt-pbkdf "^1.0.0" - ecc-jsbn "~0.1.1" - jsbn "~0.1.0" - tweetnacl "~0.14.0" - -stack-trace@0.0.x: - version "0.0.10" - resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" - -stream-connect@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/stream-connect/-/stream-connect-1.0.2.tgz#18bc81f2edb35b8b5d9a8009200a985314428a97" - dependencies: - array-back "^1.0.2" - -stream-read-all@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/stream-read-all/-/stream-read-all-0.1.2.tgz#748718e89281fff6b0742918233415a6900387e1" - -stream-via@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/stream-via/-/stream-via-1.0.4.tgz#8dccbb0ac909328eb8bc8e2a4bd3934afdaf606c" - -string-width@^1.0.1, string-width@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -string-width@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string_decoder@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" - dependencies: - safe-buffer "~5.1.0" - -stringstream@~0.0.4: - version "0.0.5" - resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - dependencies: - ansi-regex "^3.0.0" - -strip-bom@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" - dependencies: - is-utf8 "^0.2.0" - -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - -strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - -supports-color@3.1.2, supports-color@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" - dependencies: - has-flag "^1.0.0" - -supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - -table-layout@^0.4.1: - version "0.4.2" - resolved "https://registry.yarnpkg.com/table-layout/-/table-layout-0.4.2.tgz#10e9043c142a1e2d155da7257e478f0ef4981786" - dependencies: - array-back "^2.0.0" - deep-extend "~0.5.0" - lodash.padend "^4.6.1" - typical "^2.6.1" - wordwrapjs "^3.0.0" - -table@^3.7.8: - version "3.8.3" - resolved "https://registry.yarnpkg.com/table/-/table-3.8.3.tgz#2bbc542f0fda9861a755d3947fefd8b3f513855f" - dependencies: - ajv "^4.7.0" - ajv-keywords "^1.0.0" - chalk "^1.1.1" - lodash "^4.0.0" - slice-ansi "0.0.4" - string-width "^2.0.0" - -taffydb@2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/taffydb/-/taffydb-2.6.2.tgz#7cbcb64b5a141b6a2efc2c5d2c67b4e150b2a268" - -tar-pack@^3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.0.tgz#23be2d7f671a8339376cbdb0b8fe3fdebf317984" - dependencies: - debug "^2.2.0" - fstream "^1.0.10" - fstream-ignore "^1.0.5" - once "^1.3.3" - readable-stream "^2.1.4" - rimraf "^2.5.1" - tar "^2.2.1" - uid-number "^0.0.6" - -tar@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" - dependencies: - block-stream "*" - fstream "^1.0.2" - inherits "2" - -temp-path@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/temp-path/-/temp-path-1.0.0.tgz#24b1543973ab442896d9ad367dd9cbdbfafe918b" - -test-exclude@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.1.1.tgz#4d84964b0966b0087ecc334a2ce002d3d9341e26" - dependencies: - arrify "^1.0.1" - micromatch "^2.3.11" - object-assign "^4.1.0" - read-pkg-up "^1.0.1" - require-main-filename "^1.0.1" - -test-value@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/test-value/-/test-value-1.1.0.tgz#a09136f72ec043d27c893707c2b159bfad7de93f" - dependencies: - array-back "^1.0.2" - typical "^2.4.2" - -test-value@^2.0.0, test-value@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/test-value/-/test-value-2.1.0.tgz#11da6ff670f3471a73b625ca4f3fdcf7bb748291" - dependencies: - array-back "^1.0.3" - typical "^2.6.0" - -text-table@~0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - -through@^2.3.6: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - -tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - dependencies: - os-tmpdir "~1.0.2" - -to-fast-properties@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" - -tough-cookie@~2.3.0: - version "2.3.2" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a" - dependencies: - punycode "^1.4.1" - -trim-right@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" - -tryit@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb" - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - dependencies: - safe-buffer "^5.0.1" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - dependencies: - prelude-ls "~1.1.2" - -type-detect@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-3.0.0.tgz#46d0cc8553abb7b13a352b0d6dea2fd58f2d9b55" - -type-detect@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.3.tgz#0e3f2670b44099b0b46c284d136a7ef49c74c2ea" - -typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - -typical@^2.4.2, typical@^2.6.0, typical@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/typical/-/typical-2.6.1.tgz#5c080e5d661cbbe38259d2e70a3c7253e873881d" - -uglify-js@^2.6: - version "2.8.29" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" - dependencies: - source-map "~0.5.1" - yargs "~3.10.0" - optionalDependencies: - uglify-to-browserify "~1.0.0" - -uglify-js@~2.3: - version "2.3.6" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.3.6.tgz#fa0984770b428b7a9b2a8058f46355d14fef211a" - dependencies: - async "~0.2.6" - optimist "~0.3.5" - source-map "~0.1.7" - -uglify-to-browserify@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" - -uid-number@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" - -underscore-contrib@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/underscore-contrib/-/underscore-contrib-0.3.0.tgz#665b66c24783f8fa2b18c9f8cbb0e2c7d48c26c7" - dependencies: - underscore "1.6.0" - -underscore@1.6.0, underscore@~1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.6.0.tgz#8b38b10cacdef63337b8b24e4ff86d45aea529a8" - -underscore@~1.8.3: - version "1.8.3" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022" - -universalify@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7" - -usage-stats@^0.9.0: - version "0.9.4" - resolved "https://registry.yarnpkg.com/usage-stats/-/usage-stats-0.9.4.tgz#ff06ba51d824faa1982f48a055dea8495a249077" - dependencies: - array-back "^2.0.0" - home-path "^1.0.5" - mkdirp2 "^1.0.3" - req-then "^0.6.4" - typical "^2.6.1" - uuid "^3.1.0" - -user-home@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" - -user-home@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" - dependencies: - os-homedir "^1.0.0" - -util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - -utile@0.3.x: - version "0.3.0" - resolved "https://registry.yarnpkg.com/utile/-/utile-0.3.0.tgz#1352c340eb820e4d8ddba039a4fbfaa32ed4ef3a" - dependencies: - async "~0.9.0" - deep-equal "~0.2.1" - i "0.3.x" - mkdirp "0.x.x" - ncp "1.0.x" - rimraf "2.x.x" - -uuid@^3.0.0, uuid@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" - -v8flags@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.1.1.tgz#aab1a1fa30d45f88dd321148875ac02c0b55e5b4" - dependencies: - user-home "^1.1.1" - -validate-npm-package-license@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" - dependencies: - spdx-correct "~1.0.0" - spdx-expression-parse "~1.0.0" - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -walk-back@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/walk-back/-/walk-back-2.0.1.tgz#554e2a9d874fac47a8cb006bf44c2f0c4998a0a4" - -walk-back@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/walk-back/-/walk-back-3.0.0.tgz#2358787a35da91032dad5e92f80b12370d8795c5" - -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - -which@^1.2.4, which@^1.2.9: - version "1.3.0" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" - dependencies: - isexe "^2.0.0" - -wide-align@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.2.tgz#571e0f1b0604636ebc0dfc21b0339bbe31341710" - dependencies: - string-width "^1.0.2" - -window-size@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" - -winston@2.1.x: - version "2.1.1" - resolved "https://registry.yarnpkg.com/winston/-/winston-2.1.1.tgz#3c9349d196207fd1bdff9d4bc43ef72510e3a12e" - dependencies: - async "~1.0.0" - colors "1.0.x" - cycle "1.0.x" - eyes "0.1.x" - isstream "0.1.x" - pkginfo "0.3.x" - stack-trace "0.0.x" - -wordwrap@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" - -wordwrap@~0.0.2: - version "0.0.3" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" - -wordwrap@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - -wordwrapjs@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/wordwrapjs/-/wordwrapjs-3.0.0.tgz#c94c372894cadc6feb1a66bff64e1d9af92c5d1e" - dependencies: - reduce-flatten "^1.0.1" - typical "^2.6.1" - -wrap-ansi@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - -write-file-atomic@^1.1.4: - version "1.3.4" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.3.4.tgz#f807a4f0b1d9e913ae7a48112e6cc3af1991b45f" - dependencies: - graceful-fs "^4.1.11" - imurmurhash "^0.1.4" - slide "^1.1.5" - -write@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" - dependencies: - mkdirp "^0.5.1" - -xtend@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" - -y18n@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" - -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - -yargs-parser@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a" - dependencies: - camelcase "^3.0.0" - -yargs-parser@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9" - dependencies: - camelcase "^4.1.0" - -yargs@^8.0.1: - version "8.0.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-8.0.2.tgz#6299a9055b1cefc969ff7e79c1d918dceb22c360" - dependencies: - camelcase "^4.1.0" - cliui "^3.2.0" - decamelize "^1.1.1" - get-caller-file "^1.0.1" - os-locale "^2.0.0" - read-pkg-up "^2.0.0" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^2.0.0" - which-module "^2.0.0" - y18n "^3.2.1" - yargs-parser "^7.0.0" - -yargs@~3.10.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" - dependencies: - camelcase "^1.0.2" - cliui "^2.1.0" - decamelize "^1.0.0" - window-size "0.1.0" +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +abbrev@1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.0.tgz#d0554c2256636e2f56e7c2e5ad183f859428d81f" + +acorn-jsx@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" + dependencies: + acorn "^3.0.4" + +acorn@^3.0.4, acorn@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" + +acorn@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.1.1.tgz#53fe161111f912ab999ee887a90a0bc52822fd75" + +ajv-keywords@^1.0.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" + +ajv@^4.7.0, ajv@^4.9.1: + version "4.11.8" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" + dependencies: + co "^4.6.0" + json-stable-stringify "^1.0.1" + +align-text@^0.1.1, align-text@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" + dependencies: + kind-of "^3.0.2" + longest "^1.0.1" + repeat-string "^1.5.2" + +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + +ansi-escape-sequences@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-escape-sequences/-/ansi-escape-sequences-3.0.0.tgz#1c18394b6af9b76ff9a63509fa497669fd2ce53e" + dependencies: + array-back "^1.0.3" + +ansi-escape-sequences@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/ansi-escape-sequences/-/ansi-escape-sequences-4.0.0.tgz#e0ecb042958b71e42942d35c1fcf1d9b00a0f67e" + dependencies: + array-back "^2.0.0" + +ansi-escapes@^1.1.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + +anymatch@^1.3.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" + dependencies: + micromatch "^2.1.5" + normalize-path "^2.0.0" + +app-usage-stats@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/app-usage-stats/-/app-usage-stats-0.5.1.tgz#6547c5db9bab0aa5f5b2c560eacc8af20d0ab13b" + dependencies: + array-back "^1.0.4" + home-path "^1.0.3" + test-value "^2.1.0" + usage-stats "^0.9.0" + +append-transform@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-0.4.0.tgz#d76ebf8ca94d276e247a36bad44a4b74ab611991" + dependencies: + default-require-extensions "^1.0.0" + +aproba@^1.0.3: + version "1.1.2" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.1.2.tgz#45c6629094de4e96f693ef7eab74ae079c240fc1" + +archy@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" + +are-we-there-yet@~1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz#bb5dca382bb94f05e15194373d16fd3ba1ca110d" + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +argparse@^1.0.7: + version "1.0.9" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" + dependencies: + sprintf-js "~1.0.2" + +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + dependencies: + arr-flatten "^1.0.1" + +arr-flatten@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + +array-back@^1.0.2, array-back@^1.0.3, array-back@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/array-back/-/array-back-1.0.4.tgz#644ba7f095f7ffcf7c43b5f0dc39d3c1f03c063b" + dependencies: + typical "^2.6.0" + +array-back@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/array-back/-/array-back-2.0.0.tgz#6877471d51ecc9c9bfa6136fb6c7d5fe69748022" + dependencies: + typical "^2.6.1" + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + +arrify@^1.0.0, arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + +asap@~2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + +asn1@~0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + +assert-plus@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" + +assertion-error@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.0.2.tgz#13ca515d86206da0bac66e834dd397d87581094c" + +async-each@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" + +async@^1.4.0: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + +async@~0.2.6: + version "0.2.10" + resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" + +async@~0.9.0: + version "0.9.2" + resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" + +async@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/async/-/async-1.0.0.tgz#f8fc04ca3a13784ade9e1641af98578cfbd647a9" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + +aws-sign2@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" + +aws4@^1.2.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" + +babel-cli@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-cli/-/babel-cli-6.26.0.tgz#502ab54874d7db88ad00b887a06383ce03d002f1" + dependencies: + babel-core "^6.26.0" + babel-polyfill "^6.26.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + commander "^2.11.0" + convert-source-map "^1.5.0" + fs-readdir-recursive "^1.0.0" + glob "^7.1.2" + lodash "^4.17.4" + output-file-sync "^1.1.2" + path-is-absolute "^1.0.1" + slash "^1.0.0" + source-map "^0.5.6" + v8flags "^2.1.1" + optionalDependencies: + chokidar "^1.6.1" + +babel-code-frame@^6.16.0, babel-code-frame@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + +babel-core@^6.25.0, babel-core@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.0.tgz#af32f78b31a6fcef119c87b0fd8d9753f03a0bb8" + dependencies: + babel-code-frame "^6.26.0" + babel-generator "^6.26.0" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + convert-source-map "^1.5.0" + debug "^2.6.8" + json5 "^0.5.1" + lodash "^4.17.4" + minimatch "^3.0.4" + path-is-absolute "^1.0.1" + private "^0.1.7" + slash "^1.0.0" + source-map "^0.5.6" + +babel-generator@^6.18.0, babel-generator@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.0.tgz#ac1ae20070b79f6e3ca1d3269613053774f20dc5" + dependencies: + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + detect-indent "^4.0.0" + jsesc "^1.3.0" + lodash "^4.17.4" + source-map "^0.5.6" + trim-right "^1.0.1" + +babel-helper-call-delegate@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-define-map@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-function-name@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" + dependencies: + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-get-function-arity@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-hoist-variables@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-optimise-call-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-regex@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" + dependencies: + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-replace-supers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" + dependencies: + babel-helper-optimise-call-expression "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helpers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-check-es2015-constants@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-arrow-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoping@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" + dependencies: + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-plugin-transform-es2015-classes@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" + dependencies: + babel-helper-define-map "^6.24.1" + babel-helper-function-name "^6.24.1" + babel-helper-optimise-call-expression "^6.24.1" + babel-helper-replace-supers "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-computed-properties@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-destructuring@^6.22.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-duplicate-keys@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-for-of@^6.22.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-function-name@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-modules-amd@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" + dependencies: + babel-plugin-transform-es2015-modules-commonjs "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-commonjs@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz#0d8394029b7dc6abe1a97ef181e00758dd2e5d8a" + dependencies: + babel-plugin-transform-strict-mode "^6.24.1" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-types "^6.26.0" + +babel-plugin-transform-es2015-modules-systemjs@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-umd@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" + dependencies: + babel-plugin-transform-es2015-modules-amd "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-object-super@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" + dependencies: + babel-helper-replace-supers "^6.24.1" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-parameters@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" + dependencies: + babel-helper-call-delegate "^6.24.1" + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-shorthand-properties@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-spread@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-sticky-regex@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-template-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-typeof-symbol@^6.22.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-unicode-regex@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + regexpu-core "^2.0.0" + +babel-plugin-transform-regenerator@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" + dependencies: + regenerator-transform "^0.10.0" + +babel-plugin-transform-strict-mode@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-polyfill@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153" + dependencies: + babel-runtime "^6.26.0" + core-js "^2.5.0" + regenerator-runtime "^0.10.5" + +babel-preset-es2015@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz#d44050d6bc2c9feea702aaf38d727a0210538939" + dependencies: + babel-plugin-check-es2015-constants "^6.22.0" + babel-plugin-transform-es2015-arrow-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoping "^6.24.1" + babel-plugin-transform-es2015-classes "^6.24.1" + babel-plugin-transform-es2015-computed-properties "^6.24.1" + babel-plugin-transform-es2015-destructuring "^6.22.0" + babel-plugin-transform-es2015-duplicate-keys "^6.24.1" + babel-plugin-transform-es2015-for-of "^6.22.0" + babel-plugin-transform-es2015-function-name "^6.24.1" + babel-plugin-transform-es2015-literals "^6.22.0" + babel-plugin-transform-es2015-modules-amd "^6.24.1" + babel-plugin-transform-es2015-modules-commonjs "^6.24.1" + babel-plugin-transform-es2015-modules-systemjs "^6.24.1" + babel-plugin-transform-es2015-modules-umd "^6.24.1" + babel-plugin-transform-es2015-object-super "^6.24.1" + babel-plugin-transform-es2015-parameters "^6.24.1" + babel-plugin-transform-es2015-shorthand-properties "^6.24.1" + babel-plugin-transform-es2015-spread "^6.22.0" + babel-plugin-transform-es2015-sticky-regex "^6.24.1" + babel-plugin-transform-es2015-template-literals "^6.22.0" + babel-plugin-transform-es2015-typeof-symbol "^6.22.0" + babel-plugin-transform-es2015-unicode-regex "^6.24.1" + babel-plugin-transform-regenerator "^6.24.1" + +babel-register@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" + dependencies: + babel-core "^6.26.0" + babel-runtime "^6.26.0" + core-js "^2.5.0" + home-or-tmp "^2.0.0" + lodash "^4.17.4" + mkdirp "^0.5.1" + source-map-support "^0.4.15" + +babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" + dependencies: + babel-runtime "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + lodash "^4.17.4" + +babel-traverse@^6.18.0, babel-traverse@^6.24.1, babel-traverse@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + dependencies: + babel-code-frame "^6.26.0" + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + debug "^2.6.8" + globals "^9.18.0" + invariant "^2.2.2" + lodash "^4.17.4" + +babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + dependencies: + babel-runtime "^6.26.0" + esutils "^2.0.2" + lodash "^4.17.4" + to-fast-properties "^1.0.3" + +babylon@^6.17.4, babylon@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + +bcrypt-pbkdf@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" + dependencies: + tweetnacl "^0.14.3" + +binary-extensions@^1.0.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.10.0.tgz#9aeb9a6c5e88638aad171e167f5900abe24835d0" + +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + dependencies: + inherits "~2.0.0" + +bluebird@~3.4.6: + version "3.4.7" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.7.tgz#f72d760be09b7f76d08ed8fae98b289a8d05fab3" + +boom@2.x.x: + version "2.10.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" + dependencies: + hoek "2.x.x" + +brace-expansion@^1.1.7: + version "1.1.8" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + +browser-stdout@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" + +builtin-modules@^1.0.0, builtin-modules@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + +cache-point@^0.4.0, cache-point@~0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/cache-point/-/cache-point-0.4.1.tgz#cc8c9cbd99d90d7b0c66910cd33d77a1aab8840e" + dependencies: + array-back "^2.0.0" + fs-then-native "^2.0.0" + mkdirp2 "^1.0.3" + +caching-transform@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/caching-transform/-/caching-transform-1.0.1.tgz#6dbdb2f20f8d8fbce79f3e94e9d1742dcdf5c0a1" + dependencies: + md5-hex "^1.2.0" + mkdirp "^0.5.1" + write-file-atomic "^1.1.4" + +caller-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" + dependencies: + callsites "^0.2.0" + +callsites@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" + +camelcase@^1.0.2: + version "1.2.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" + +camelcase@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" + +camelcase@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + +catharsis@~0.8.8: + version "0.8.9" + resolved "https://registry.yarnpkg.com/catharsis/-/catharsis-0.8.9.tgz#98cc890ca652dd2ef0e70b37925310ff9e90fc8b" + dependencies: + underscore-contrib "~0.3.0" + +center-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" + dependencies: + align-text "^0.1.3" + lazy-cache "^1.0.3" + +chai@^4.0.2: + version "4.1.1" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.1.1.tgz#66e21279e6f3c6415ff8231878227900e2171b39" + dependencies: + assertion-error "^1.0.1" + check-error "^1.0.1" + deep-eql "^2.0.1" + get-func-name "^2.0.0" + pathval "^1.0.0" + type-detect "^4.0.0" + +chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +check-error@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" + +chokidar@^1.6.1: + version "1.7.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" + dependencies: + anymatch "^1.3.0" + async-each "^1.0.0" + glob-parent "^2.0.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^2.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + optionalDependencies: + fsevents "^1.0.0" + +circular-json@^0.3.1: + version "0.3.3" + resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" + +cli-cursor@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" + dependencies: + restore-cursor "^1.0.1" + +cli-width@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.1.0.tgz#b234ca209b29ef66fc518d9b98d5847b00edf00a" + +cliui@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" + dependencies: + center-align "^0.1.1" + right-align "^0.1.1" + wordwrap "0.0.2" + +cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + +collect-all@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/collect-all/-/collect-all-1.0.3.tgz#1abcc20448b58a1447487fcf34130e9512b0acf8" + dependencies: + stream-connect "^1.0.2" + stream-via "^1.0.4" + +colors@1.0.x: + version "1.0.3" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" + +colors@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" + +combined-stream@^1.0.5, combined-stream@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" + dependencies: + delayed-stream "~1.0.0" + +command-line-args@^4.0.1: + version "4.0.7" + resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-4.0.7.tgz#f8d1916ecb90e9e121eda6428e41300bfb64cc46" + dependencies: + array-back "^2.0.0" + find-replace "^1.0.3" + typical "^2.6.1" + +command-line-tool@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/command-line-tool/-/command-line-tool-0.7.0.tgz#ca80792ae2069cf7caa562c0cbc2cd11811122a0" + dependencies: + ansi-escape-sequences "^3.0.0" + array-back "^1.0.4" + command-line-args "^4.0.1" + command-line-usage "^4.0.0" + typical "^2.6.0" + +command-line-usage@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/command-line-usage/-/command-line-usage-4.0.1.tgz#d89cf16c8ae71e8e8a6e6aabae1652af76ff644e" + dependencies: + ansi-escape-sequences "^4.0.0" + array-back "^2.0.0" + table-layout "^0.4.1" + typical "^2.6.1" + +commander@2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" + dependencies: + graceful-readlink ">= 1.0.0" + +commander@^2.11.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" + +common-sequence@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/common-sequence/-/common-sequence-1.0.2.tgz#30e07f3f8f6f7f9b3dee854f20b2d39eee086de8" + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + +concat-stream@^1.5.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" + dependencies: + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +config-master@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/config-master/-/config-master-3.1.0.tgz#667663590505a283bf26a484d68489d74c5485da" + dependencies: + walk-back "^2.0.1" + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + +contains-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" + +convert-source-map@^1.3.0, convert-source-map@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5" + +core-js@^2.4.0, core-js@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.0.tgz#569c050918be6486b3837552028ae0466b717086" + +core-util-is@1.0.2, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + +cross-spawn@^4: + version "4.0.2" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" + dependencies: + lru-cache "^4.0.1" + which "^1.2.9" + +cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +cryptiles@2.x.x: + version "2.0.5" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" + dependencies: + boom "2.x.x" + +cycle@1.0.x: + version "1.0.3" + resolved "https://registry.yarnpkg.com/cycle/-/cycle-1.0.3.tgz#21e80b2be8580f98b468f379430662b046c34ad2" + +d@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" + dependencies: + es5-ext "^0.10.9" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + dependencies: + assert-plus "^1.0.0" + +debug-log@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/debug-log/-/debug-log-1.0.1.tgz#2307632d4c04382b8df8a32f70b895046d52745f" + +debug@2.6.8, debug@^2.1.1, debug@^2.2.0, debug@^2.6.3, debug@^2.6.8: + version "2.6.8" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" + dependencies: + ms "2.0.0" + +decamelize@^1.0.0, decamelize@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + +deep-eql@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-2.0.2.tgz#b1bac06e56f0a76777686d50c9feb75c2ed7679a" + dependencies: + type-detect "^3.0.0" + +deep-equal@~0.2.1: + version "0.2.2" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-0.2.2.tgz#84b745896f34c684e98f2ce0e42abaf43bba017d" + +deep-extend@~0.4.0: + version "0.4.2" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" + +deep-extend@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.5.0.tgz#6ef4a09b05f98b0e358d6d93d4ca3caec6672803" + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + +default-require-extensions@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-1.0.0.tgz#f37ea15d3e13ffd9b437d33e1a75b5fb97874cb8" + dependencies: + strip-bom "^2.0.0" + +default-shell@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/default-shell/-/default-shell-1.0.1.tgz#752304bddc6174f49eb29cb988feea0b8813c8bc" + +defer-promise@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/defer-promise/-/defer-promise-1.0.1.tgz#1ca6ffeddbcef1715dd7aae25c7616f9ae22932f" + +del@^2.0.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" + dependencies: + globby "^5.0.0" + is-path-cwd "^1.0.0" + is-path-in-cwd "^1.0.0" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + rimraf "^2.2.8" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + dependencies: + repeating "^2.0.0" + +diff@3.2.0, diff@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9" + +dmd@^3.0.0: + version "3.0.6" + resolved "https://registry.yarnpkg.com/dmd/-/dmd-3.0.6.tgz#94c0e0fb88d1cb6b82837595053de7919c753c25" + dependencies: + array-back "^1.0.4" + cache-point "^0.4.0" + common-sequence "^1.0.2" + file-set "^1.1.1" + handlebars "3.0.3" + marked "^0.3.6" + object-get "^2.1.0" + reduce-flatten "^1.0.1" + reduce-unique "^1.0.0" + reduce-without "^1.0.1" + test-value "^2.1.0" + walk-back "^3.0.0" + +doctrine@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + +doctrine@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.0.tgz#c73d8d2909d22291e1a007a395804da8b665fe63" + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + +ecc-jsbn@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" + dependencies: + jsbn "~0.1.0" + +error-ex@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" + dependencies: + is-arrayish "^0.2.1" + +es5-ext@^0.10.14, es5-ext@^0.10.9, es5-ext@~0.10.14: + version "0.10.27" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.27.tgz#bf926b058c62b1cb5de1a887930673b6aa6d9a66" + dependencies: + es6-iterator "2" + es6-symbol "~3.1" + +es6-iterator@2, es6-iterator@^2.0.1, es6-iterator@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.1.tgz#8e319c9f0453bf575d374940a655920e59ca5512" + dependencies: + d "1" + es5-ext "^0.10.14" + es6-symbol "^3.1" + +es6-map@^0.1.3: + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0" + dependencies: + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-set "~0.1.5" + es6-symbol "~3.1.1" + event-emitter "~0.3.5" + +es6-set@~0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" + dependencies: + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-symbol "3.1.1" + event-emitter "~0.3.5" + +es6-symbol@3.1.1, es6-symbol@^3.1, es6-symbol@^3.1.1, es6-symbol@~3.1, es6-symbol@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" + dependencies: + d "1" + es5-ext "~0.10.14" + +es6-weak-map@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f" + dependencies: + d "1" + es5-ext "^0.10.14" + es6-iterator "^2.0.1" + es6-symbol "^3.1.1" + +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5, escape-string-regexp@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + +escope@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" + dependencies: + es6-map "^0.1.3" + es6-weak-map "^2.0.1" + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-config-airbnb-base@^11.2.0: + version "11.3.1" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-11.3.1.tgz#c0ab108c9beed503cb999e4c60f4ef98eda0ed30" + dependencies: + eslint-restricted-globals "^0.1.1" + +eslint-import-resolver-node@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.1.tgz#4422574cde66a9a7b099938ee4d508a199e0e3cc" + dependencies: + debug "^2.6.8" + resolve "^1.2.0" + +eslint-module-utils@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz#abaec824177613b8a95b299639e1b6facf473449" + dependencies: + debug "^2.6.8" + pkg-dir "^1.0.0" + +eslint-plugin-chai-friendly@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-chai-friendly/-/eslint-plugin-chai-friendly-0.4.0.tgz#aad72b4f0ea3cd2655dd92528f66bc7da7a8c9fe" + +eslint-plugin-import@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.7.0.tgz#21de33380b9efb55f5ef6d2e210ec0e07e7fa69f" + dependencies: + builtin-modules "^1.1.1" + contains-path "^0.1.0" + debug "^2.6.8" + doctrine "1.5.0" + eslint-import-resolver-node "^0.3.1" + eslint-module-utils "^2.1.1" + has "^1.0.1" + lodash.cond "^4.3.0" + minimatch "^3.0.3" + read-pkg-up "^2.0.0" + +eslint-plugin-mocha@^4.11.0: + version "4.11.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-mocha/-/eslint-plugin-mocha-4.11.0.tgz#91193a2f55e20a5e35974054a0089d30198ee578" + dependencies: + ramda "^0.24.1" + +eslint-restricted-globals@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz#35f0d5cbc64c2e3ed62e93b4b1a7af05ba7ed4d7" + +eslint@^3.19.0: + version "3.19.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.19.0.tgz#c8fc6201c7f40dd08941b87c085767386a679acc" + dependencies: + babel-code-frame "^6.16.0" + chalk "^1.1.3" + concat-stream "^1.5.2" + debug "^2.1.1" + doctrine "^2.0.0" + escope "^3.6.0" + espree "^3.4.0" + esquery "^1.0.0" + estraverse "^4.2.0" + esutils "^2.0.2" + file-entry-cache "^2.0.0" + glob "^7.0.3" + globals "^9.14.0" + ignore "^3.2.0" + imurmurhash "^0.1.4" + inquirer "^0.12.0" + is-my-json-valid "^2.10.0" + is-resolvable "^1.0.0" + js-yaml "^3.5.1" + json-stable-stringify "^1.0.0" + levn "^0.3.0" + lodash "^4.0.0" + mkdirp "^0.5.0" + natural-compare "^1.4.0" + optionator "^0.8.2" + path-is-inside "^1.0.1" + pluralize "^1.2.1" + progress "^1.1.8" + require-uncached "^1.0.2" + shelljs "^0.7.5" + strip-bom "^3.0.0" + strip-json-comments "~2.0.1" + table "^3.7.8" + text-table "~0.2.0" + user-home "^2.0.0" + +espree@^3.4.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.0.tgz#98358625bdd055861ea27e2867ea729faf463d8d" + dependencies: + acorn "^5.1.1" + acorn-jsx "^3.0.0" + +espree@~3.1.7: + version "3.1.7" + resolved "https://registry.yarnpkg.com/espree/-/espree-3.1.7.tgz#fd5deec76a97a5120a9cd3a7cb1177a0923b11d2" + dependencies: + acorn "^3.3.0" + acorn-jsx "^3.0.0" + +esprima@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" + +esquery@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.0.tgz#cfba8b57d7fba93f17298a8a006a04cda13d80fa" + dependencies: + estraverse "^4.0.0" + +esrecurse@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.0.tgz#fa9568d98d3823f9a41d91e902dcab9ea6e5b163" + dependencies: + estraverse "^4.1.0" + object-assign "^4.0.1" + +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + +esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + +event-emitter@~0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + dependencies: + d "1" + es5-ext "~0.10.14" + +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +exit-hook@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" + +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + dependencies: + is-posix-bracket "^0.1.0" + +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + dependencies: + fill-range "^2.1.0" + +extend@~3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" + +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + dependencies: + is-extglob "^1.0.0" + +extsprintf@1.3.0, extsprintf@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + +eyes@0.1.x: + version "0.1.8" + resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" + +fast-levenshtein@~2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + +figures@^1.3.5: + version "1.7.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" + dependencies: + escape-string-regexp "^1.0.5" + object-assign "^4.1.0" + +file-entry-cache@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" + dependencies: + flat-cache "^1.2.1" + object-assign "^4.0.1" + +file-set@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/file-set/-/file-set-1.1.1.tgz#d3ec70c080ec8f18f204ba1de106780c9056926b" + dependencies: + array-back "^1.0.3" + glob "^7.1.0" + +filename-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" + +fill-range@^2.1.0: + version "2.2.3" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^1.1.3" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + +find-cache-dir@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9" + dependencies: + commondir "^1.0.1" + mkdirp "^0.5.1" + pkg-dir "^1.0.0" + +find-replace@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-1.0.3.tgz#b88e7364d2d9c959559f388c66670d6130441fa0" + dependencies: + array-back "^1.0.4" + test-value "^2.1.0" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-up@^2.0.0, find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + dependencies: + locate-path "^2.0.0" + +flat-cache@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.2.2.tgz#fa86714e72c21db88601761ecf2f555d1abc6b96" + dependencies: + circular-json "^0.3.1" + del "^2.0.2" + graceful-fs "^4.1.2" + write "^0.2.1" + +for-in@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + +for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + dependencies: + for-in "^1.0.1" + +foreground-child@^1.5.3, foreground-child@^1.5.6: + version "1.5.6" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-1.5.6.tgz#4fd71ad2dfde96789b980a5c0a295937cb2f5ce9" + dependencies: + cross-spawn "^4" + signal-exit "^3.0.0" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + +form-data@~2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1" + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.12" + +formatio@1.2.0, formatio@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/formatio/-/formatio-1.2.0.tgz#f3b2167d9068c4698a8d51f4f760a39a54d818eb" + dependencies: + samsam "1.x" + +fs-extra@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-3.0.1.tgz#3794f378c58b342ea7dbbb23095109c4b3b62291" + dependencies: + graceful-fs "^4.1.2" + jsonfile "^3.0.0" + universalify "^0.1.0" + +fs-readdir-recursive@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.0.0.tgz#8cd1745c8b4f8a29c8caec392476921ba195f560" + +fs-then-native@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fs-then-native/-/fs-then-native-2.0.0.tgz#19a124d94d90c22c8e045f2e8dd6ebea36d48c67" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + +fsevents@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.2.tgz#3282b713fb3ad80ede0e9fcf4611b5aa6fc033f4" + dependencies: + nan "^2.3.0" + node-pre-gyp "^0.6.36" + +fstream-ignore@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" + dependencies: + fstream "^1.0.0" + inherits "2" + minimatch "^3.0.0" + +fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.2: + version "1.0.11" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + +function-bind@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.0.tgz#16176714c801798e4e8f2cf7f7529467bb4a5771" + +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +generate-function@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" + +generate-object-property@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" + dependencies: + is-property "^1.0.0" + +get-caller-file@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" + +get-func-name@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" + +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + dependencies: + assert-plus "^1.0.0" + +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + dependencies: + is-glob "^2.0.0" + +glob@7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.2" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.0, glob@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^9.14.0, globals@^9.18.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + +globby@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" + dependencies: + array-union "^1.0.1" + arrify "^1.0.0" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.4, graceful-fs@^4.1.6, graceful-fs@^4.1.9: + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + +"graceful-readlink@>= 1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + +growl@1.9.2: + version "1.9.2" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f" + +handlebars@3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-3.0.3.tgz#0e09651a2f0fb3c949160583710d551f92e6d2ad" + dependencies: + optimist "^0.6.1" + source-map "^0.1.40" + optionalDependencies: + uglify-js "~2.3" + +handlebars@^4.0.3: + version "4.0.10" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.10.tgz#3d30c718b09a3d96f23ea4cc1f403c4d3ba9ff4f" + dependencies: + async "^1.4.0" + optimist "^0.6.1" + source-map "^0.4.4" + optionalDependencies: + uglify-js "^2.6" + +har-schema@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" + +har-validator@~4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a" + dependencies: + ajv "^4.9.1" + har-schema "^1.0.5" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + dependencies: + ansi-regex "^2.0.0" + +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + +has@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28" + dependencies: + function-bind "^1.0.2" + +hawk@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" + dependencies: + boom "2.x.x" + cryptiles "2.x.x" + hoek "2.x.x" + sntp "1.x.x" + +hoek@2.x.x: + version "2.16.3" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" + +home-or-tmp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.1" + +home-path@^1.0.3, home-path@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/home-path/-/home-path-1.0.5.tgz#788b29815b12d53bacf575648476e6f9041d133f" + +hosted-git-info@^2.1.4: + version "2.5.0" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c" + +http-signature@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" + dependencies: + assert-plus "^0.2.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +i@0.3.x: + version "0.3.5" + resolved "https://registry.yarnpkg.com/i/-/i-0.3.5.tgz#1d2b854158ec8169113c6cb7f6b6801e99e211d5" + +ignore@^3.2.0, ignore@^3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.3.tgz#432352e57accd87ab3110e82d3fea0e47812156d" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +ini@~1.3.0: + version "1.3.4" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" + +inquirer@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e" + dependencies: + ansi-escapes "^1.1.0" + ansi-regex "^2.0.0" + chalk "^1.0.0" + cli-cursor "^1.0.1" + cli-width "^2.0.0" + figures "^1.3.5" + lodash "^4.3.0" + readline2 "^1.0.1" + run-async "^0.1.0" + rx-lite "^3.1.2" + string-width "^1.0.1" + strip-ansi "^3.0.0" + through "^2.3.6" + +interpret@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.3.tgz#cbc35c62eeee73f19ab7b10a801511401afc0f90" + +invariant@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" + dependencies: + loose-envify "^1.0.0" + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + dependencies: + binary-extensions "^1.0.0" + +is-buffer@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.5.tgz#1f3b26ef613b214b88cbca23cc6c01d87961eecc" + +is-builtin-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" + dependencies: + builtin-modules "^1.0.0" + +is-dotfile@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + dependencies: + is-primitive "^2.0.0" + +is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + +is-finite@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + +is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + dependencies: + is-extglob "^1.0.0" + +is-my-json-valid@^2.10.0: + version "2.16.0" + resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz#f079dd9bfdae65ee2038aae8acbc86ab109e3693" + dependencies: + generate-function "^2.0.0" + generate-object-property "^1.1.0" + jsonpointer "^4.0.0" + xtend "^4.0.0" + +is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + dependencies: + kind-of "^3.0.2" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + dependencies: + kind-of "^3.0.2" + +is-path-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" + +is-path-in-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz#6477582b8214d602346094567003be8a9eac04dc" + dependencies: + is-path-inside "^1.0.0" + +is-path-inside@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.0.tgz#fc06e5a1683fbda13de667aff717bbc10a48f37f" + dependencies: + path-is-inside "^1.0.1" + +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + +is-property@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" + +is-resolvable@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.0.tgz#8df57c61ea2e3c501408d100fb013cf8d6e0cc62" + dependencies: + tryit "^1.0.1" + +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + dependencies: + isarray "1.0.0" + +isstream@0.1.x, isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + +istanbul-lib-coverage@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz#73bfb998885299415c93d38a3e9adf784a77a9da" + +istanbul-lib-hook@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.0.7.tgz#dd6607f03076578fe7d6f2a630cf143b49bacddc" + dependencies: + append-transform "^0.4.0" + +istanbul-lib-instrument@^1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.7.4.tgz#e9fd920e4767f3d19edc765e2d6b3f5ccbd0eea8" + dependencies: + babel-generator "^6.18.0" + babel-template "^6.16.0" + babel-traverse "^6.18.0" + babel-types "^6.18.0" + babylon "^6.17.4" + istanbul-lib-coverage "^1.1.1" + semver "^5.3.0" + +istanbul-lib-report@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz#f0e55f56655ffa34222080b7a0cd4760e1405fc9" + dependencies: + istanbul-lib-coverage "^1.1.1" + mkdirp "^0.5.1" + path-parse "^1.0.5" + supports-color "^3.1.2" + +istanbul-lib-source-maps@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.1.tgz#a6fe1acba8ce08eebc638e572e294d267008aa0c" + dependencies: + debug "^2.6.3" + istanbul-lib-coverage "^1.1.1" + mkdirp "^0.5.1" + rimraf "^2.6.1" + source-map "^0.5.3" + +istanbul-reports@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.1.1.tgz#042be5c89e175bc3f86523caab29c014e77fee4e" + dependencies: + handlebars "^4.0.3" + +js-tokens@^3.0.0, js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + +js-yaml@^3.5.1: + version "3.9.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.9.1.tgz#08775cebdfdd359209f0d2acd383c8f86a6904a0" + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +js2xmlparser@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/js2xmlparser/-/js2xmlparser-1.0.0.tgz#5a170f2e8d6476ce45405e04823242513782fe30" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + +jsdoc-75lb@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/jsdoc-75lb/-/jsdoc-75lb-3.6.0.tgz#a807119528b4009ccbcab49b7522f63fec6cd0bd" + dependencies: + bluebird "~3.4.6" + catharsis "~0.8.8" + escape-string-regexp "~1.0.5" + espree "~3.1.7" + js2xmlparser "~1.0.0" + klaw "~1.3.0" + marked "~0.3.6" + mkdirp "~0.5.1" + requizzle "~0.2.1" + strip-json-comments "~2.0.1" + taffydb "2.6.2" + underscore "~1.8.3" + +jsdoc-api@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/jsdoc-api/-/jsdoc-api-3.0.0.tgz#0d52700235f865bd4a8bad5ebc1efb562fc8ad2a" + dependencies: + array-back "^1.0.4" + cache-point "~0.4.0" + collect-all "^1.0.2" + file-set "^1.1.1" + fs-then-native "^2.0.0" + jsdoc-75lb "^3.6.0" + object-to-spawn-args "^1.1.0" + temp-path "^1.0.0" + walk-back "^2.0.1" + +jsdoc-parse@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/jsdoc-parse/-/jsdoc-parse-3.0.0.tgz#271531d88f19df2520b1632a7f6c989441a87fde" + dependencies: + array-back "^1.0.4" + lodash.omit "^4.5.0" + lodash.pick "^4.4.0" + reduce-extract "^1.0.0" + sort-array "^1.1.1" + test-value "^2.1.0" + +jsdoc-to-markdown@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/jsdoc-to-markdown/-/jsdoc-to-markdown-3.0.0.tgz#cc8a94f1f412ac1da4bac1657475b0975ee8161a" + dependencies: + array-back "^1.0.4" + command-line-tool "^0.7.0" + config-master "^3.0.0" + dmd "^3.0.0" + jsdoc-api "^3.0.0" + jsdoc-parse "^3.0.0" + jsdoc2md-stats "^2.0.0" + walk-back "^2.0.1" + +jsdoc2md-stats@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/jsdoc2md-stats/-/jsdoc2md-stats-2.0.1.tgz#bd8343734cfe69ea8050a17931251293f0d9047b" + dependencies: + app-usage-stats "^0.5.0" + +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + +json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + dependencies: + jsonify "~0.0.0" + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + +json3@3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" + +json5@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + +jsonfile@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-3.0.1.tgz#a5ecc6f65f53f662c4415c7675a0331d0992ec66" + optionalDependencies: + graceful-fs "^4.1.6" + +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + +jsonpointer@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +just-extend@^1.1.22: + version "1.1.22" + resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-1.1.22.tgz#3330af756cab6a542700c64b2e4e4aa062d52fff" + +kind-of@^3.0.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + dependencies: + is-buffer "^1.1.5" + +klaw@~1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" + optionalDependencies: + graceful-fs "^4.1.9" + +lazy-cache@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + dependencies: + invert-kv "^1.0.0" + +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +load-json-file@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + strip-bom "^3.0.0" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +lodash._baseassign@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" + dependencies: + lodash._basecopy "^3.0.0" + lodash.keys "^3.0.0" + +lodash._basecopy@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" + +lodash._basecreate@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz#1bc661614daa7fc311b7d03bf16806a0213cf821" + +lodash._getnative@^3.0.0: + version "3.9.1" + resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" + +lodash._isiterateecall@^3.0.0: + version "3.0.9" + resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" + +lodash.cond@^4.3.0: + version "4.5.2" + resolved "https://registry.yarnpkg.com/lodash.cond/-/lodash.cond-4.5.2.tgz#f471a1da486be60f6ab955d17115523dd1d255d5" + +lodash.create@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lodash.create/-/lodash.create-3.1.1.tgz#d7f2849f0dbda7e04682bb8cd72ab022461debe7" + dependencies: + lodash._baseassign "^3.0.0" + lodash._basecreate "^3.0.0" + lodash._isiterateecall "^3.0.0" + +lodash.isarguments@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" + +lodash.isarray@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" + +lodash.keys@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" + dependencies: + lodash._getnative "^3.0.0" + lodash.isarguments "^3.0.0" + lodash.isarray "^3.0.0" + +lodash.omit@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.omit/-/lodash.omit-4.5.0.tgz#6eb19ae5a1ee1dd9df0b969e66ce0b7fa30b5e60" + +lodash.padend@^4.6.1: + version "4.6.1" + resolved "https://registry.yarnpkg.com/lodash.padend/-/lodash.padend-4.6.1.tgz#53ccba047d06e158d311f45da625f4e49e6f166e" + +lodash.pick@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" + +lodash@^4.0.0, lodash@^4.17.4, lodash@^4.3.0: + version "4.17.4" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" + +lolex@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/lolex/-/lolex-1.6.0.tgz#3a9a0283452a47d7439e72731b9e07d7386e49f6" + +lolex@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/lolex/-/lolex-2.1.2.tgz#2694b953c9ea4d013e5b8bfba891c991025b2629" + +longest@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" + +loose-envify@^1.0.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" + dependencies: + js-tokens "^3.0.0" + +lru-cache@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55" + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +marked@^0.3.6, marked@~0.3.6: + version "0.3.6" + resolved "https://registry.yarnpkg.com/marked/-/marked-0.3.6.tgz#b2c6c618fccece4ef86c4fc6cb8a7cbf5aeda8d7" + +md5-hex@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-1.3.0.tgz#d2c4afe983c4370662179b8cad145219135046c4" + dependencies: + md5-o-matic "^0.1.1" + +md5-o-matic@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/md5-o-matic/-/md5-o-matic-0.1.1.tgz#822bccd65e117c514fab176b25945d54100a03c3" + +mem@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" + dependencies: + mimic-fn "^1.0.0" + +merge-source-map@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.0.4.tgz#a5de46538dae84d4114cc5ea02b4772a6346701f" + dependencies: + source-map "^0.5.6" + +micromatch@^2.1.5, micromatch@^2.3.11: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + +mime-db@~1.29.0: + version "1.29.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.29.0.tgz#48d26d235589651704ac5916ca06001914266878" + +mime-types@^2.1.12, mime-types@~2.1.7: + version "2.1.16" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.16.tgz#2b858a52e5ecd516db897ac2be87487830698e23" + dependencies: + mime-db "~1.29.0" + +mimic-fn@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18" + +minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + dependencies: + brace-expansion "^1.1.7" + +minimist@0.0.8, minimist@~0.0.1: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + +minimist@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + +mkdirp2@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/mkdirp2/-/mkdirp2-1.0.3.tgz#cc8dd8265f1f06e2d8f5b10b6e52f4e050bed21b" + +mkdirp@0.5.1, mkdirp@0.x.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + +mocha@^3.4.2: + version "3.5.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-3.5.0.tgz#1328567d2717f997030f8006234bce9b8cd72465" + dependencies: + browser-stdout "1.3.0" + commander "2.9.0" + debug "2.6.8" + diff "3.2.0" + escape-string-regexp "1.0.5" + glob "7.1.1" + growl "1.9.2" + json3 "3.3.2" + lodash.create "3.1.1" + mkdirp "0.5.1" + supports-color "3.1.2" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + +mute-stream@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" + +mute-stream@~0.0.4: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + +nan@^2.3.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.5.0.tgz#aa8f1e34531d807e9e27755b234b4a6ec0c152a8" + +nan@^2.6.2: + version "2.7.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.7.0.tgz#d95bf721ec877e08db276ed3fc6eb78f9083ad46" + +native-promise-only@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/native-promise-only/-/native-promise-only-0.8.1.tgz#20a318c30cb45f71fe7adfbf7b21c99c1472ef11" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + +ncp@1.0.x: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ncp/-/ncp-1.0.1.tgz#d15367e5cb87432ba117d2bf80fdf45aecfb4246" + +nise@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/nise/-/nise-1.0.1.tgz#0da92b10a854e97c0f496f6c2845a301280b3eef" + dependencies: + formatio "^1.2.0" + just-extend "^1.1.22" + lolex "^1.6.0" + path-to-regexp "^1.7.0" + +node-pre-gyp@^0.6.36: + version "0.6.36" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.36.tgz#db604112cb74e0d477554e9b505b17abddfab786" + dependencies: + mkdirp "^0.5.1" + nopt "^4.0.1" + npmlog "^4.0.2" + rc "^1.1.7" + request "^2.81.0" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^2.2.1" + tar-pack "^3.4.0" + +"node-pty@github:implausible/node-pty#57f5f4ef6b751ffcd056fb6f2b626a0a0d804301": + version "0.7.0" + resolved "https://codeload.github.com/implausible/node-pty/tar.gz/57f5f4ef6b751ffcd056fb6f2b626a0a0d804301" + dependencies: + nan "^2.6.2" + +nodegit-promise@~4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/nodegit-promise/-/nodegit-promise-4.0.0.tgz#5722b184f2df7327161064a791d2e842c9167b34" + dependencies: + asap "~2.0.3" + +nopt@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + dependencies: + abbrev "1" + osenv "^0.1.4" + +normalize-package-data@^2.3.2: + version "2.4.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" + dependencies: + hosted-git-info "^2.1.4" + is-builtin-module "^1.0.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.0.0, normalize-path@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + dependencies: + remove-trailing-separator "^1.0.1" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + dependencies: + path-key "^2.0.0" + +npmlog@^4.0.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + +nyc@^11.0.3: + version "11.1.0" + resolved "https://registry.yarnpkg.com/nyc/-/nyc-11.1.0.tgz#d6b3c5e16892a25af63138ba484676aa8a22eda7" + dependencies: + archy "^1.0.0" + arrify "^1.0.1" + caching-transform "^1.0.0" + convert-source-map "^1.3.0" + debug-log "^1.0.1" + default-require-extensions "^1.0.0" + find-cache-dir "^0.1.1" + find-up "^2.1.0" + foreground-child "^1.5.3" + glob "^7.0.6" + istanbul-lib-coverage "^1.1.1" + istanbul-lib-hook "^1.0.7" + istanbul-lib-instrument "^1.7.4" + istanbul-lib-report "^1.1.1" + istanbul-lib-source-maps "^1.2.1" + istanbul-reports "^1.1.1" + md5-hex "^1.2.0" + merge-source-map "^1.0.2" + micromatch "^2.3.11" + mkdirp "^0.5.0" + resolve-from "^2.0.0" + rimraf "^2.5.4" + signal-exit "^3.0.1" + spawn-wrap "^1.3.8" + test-exclude "^4.1.1" + yargs "^8.0.1" + yargs-parser "^5.0.0" + +oauth-sign@~0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" + +object-assign@^4.0.1, object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + +object-get@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/object-get/-/object-get-2.1.0.tgz#722bbdb60039efa47cad3c6dc2ce51a85c02c5ae" + +object-to-spawn-args@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-to-spawn-args/-/object-to-spawn-args-1.1.1.tgz#77da8827f073d011c9e1b173f895781470246785" + +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + +once@^1.3.0, once@^1.3.3: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + dependencies: + wrappy "1" + +onetime@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" + +optimist@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + dependencies: + minimist "~0.0.1" + wordwrap "~0.0.2" + +optimist@~0.3.5: + version "0.3.7" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.3.7.tgz#c90941ad59e4273328923074d2cf2e7cbc6ec0d9" + dependencies: + wordwrap "~0.0.2" + +optionator@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + +os-homedir@^1.0.0, os-homedir@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + +os-locale@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" + dependencies: + execa "^0.7.0" + lcid "^1.0.0" + mem "^1.1.0" + +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + +osenv@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.4.tgz#42fe6d5953df06c8064be6f176c3d05aaaa34644" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +output-file-sync@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/output-file-sync/-/output-file-sync-1.1.2.tgz#d0a33eefe61a205facb90092e826598d5245ce76" + dependencies: + graceful-fs "^4.1.4" + mkdirp "^0.5.1" + object-assign "^4.1.0" + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + +p-limit@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.1.0.tgz#b07ff2d9a5d88bec806035895a2bab66a27988bc" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + dependencies: + p-limit "^1.1.0" + +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + dependencies: + error-ex "^1.2.0" + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + dependencies: + pinkie-promise "^2.0.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + +path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + +path-is-inside@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + +path-key@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + +path-parse@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" + +path-to-regexp@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d" + dependencies: + isarray "0.0.1" + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +path-type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" + dependencies: + pify "^2.0.0" + +pathval@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" + +performance-now@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + +pkg-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" + dependencies: + find-up "^1.0.0" + +pkginfo@0.3.x: + version "0.3.1" + resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.3.1.tgz#5b29f6a81f70717142e09e765bbeab97b4f81e21" + +pkginfo@0.x.x: + version "0.4.0" + resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.4.0.tgz#349dbb7ffd38081fcadc0853df687f0c7744cd65" + +pluralize@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + +private@^0.1.6, private@^0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.7.tgz#68ce5e8a1ef0a23bb570cc28537b5332aba63ef1" + +process-nextick-args@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" + +progress@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" + +promisify-node@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/promisify-node/-/promisify-node-0.4.0.tgz#32803874ec411784e4786c339902a87a179a469c" + dependencies: + nodegit-promise "~4.0.0" + object-assign "^4.0.1" + +prompt@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prompt/-/prompt-1.0.0.tgz#8e57123c396ab988897fb327fd3aedc3e735e4fe" + dependencies: + colors "^1.1.2" + pkginfo "0.x.x" + read "1.0.x" + revalidator "0.1.x" + utile "0.3.x" + winston "2.1.x" + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + +punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + +qs@~6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" + +ramda@^0.24.1: + version "0.24.1" + resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.24.1.tgz#c3b7755197f35b8dc3502228262c4c91ddb6b857" + +randomatic@^1.1.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +rc@^1.1.7: + version "1.2.1" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.1.tgz#2e03e8e42ee450b8cb3dce65be1bf8974e1dfd95" + dependencies: + deep-extend "~0.4.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" + dependencies: + find-up "^2.0.0" + read-pkg "^2.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +read-pkg@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" + dependencies: + load-json-file "^2.0.0" + normalize-package-data "^2.3.2" + path-type "^2.0.0" + +read@1.0.x: + version "1.0.7" + resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" + dependencies: + mute-stream "~0.0.4" + +readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.2.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + safe-buffer "~5.1.1" + string_decoder "~1.0.3" + util-deprecate "~1.0.1" + +readdirp@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" + dependencies: + graceful-fs "^4.1.2" + minimatch "^3.0.2" + readable-stream "^2.0.2" + set-immediate-shim "^1.0.1" + +readline2@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35" + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + mute-stream "0.0.5" + +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + dependencies: + resolve "^1.1.6" + +reduce-extract@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/reduce-extract/-/reduce-extract-1.0.0.tgz#67f2385beda65061b5f5f4312662e8b080ca1525" + dependencies: + test-value "^1.0.1" + +reduce-flatten@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/reduce-flatten/-/reduce-flatten-1.0.1.tgz#258c78efd153ddf93cb561237f61184f3696e327" + +reduce-unique@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/reduce-unique/-/reduce-unique-1.0.0.tgz#7e586bcf87a4e32b6d7abd8277fad6cdec9f4803" + +reduce-without@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/reduce-without/-/reduce-without-1.0.1.tgz#68ad0ead11855c9a37d4e8256c15bbf87972fc8c" + dependencies: + test-value "^2.0.0" + +regenerate@^1.2.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.2.tgz#d1941c67bad437e1be76433add5b385f95b19260" + +regenerator-runtime@^0.10.5: + version "0.10.5" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" + +regenerator-runtime@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz#7e54fe5b5ccd5d6624ea6255c3473be090b802e1" + +regenerator-transform@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.0.tgz#f9ab3eac9cc2de38431d996a6a8abf1c50f2e459" + dependencies: + babel-runtime "^6.18.0" + babel-types "^6.19.0" + private "^0.1.6" + +regex-cache@^0.4.2: + version "0.4.3" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.3.tgz#9b1a6c35d4d0dfcef5711ae651e8e9d3d7114145" + dependencies: + is-equal-shallow "^0.1.3" + is-primitive "^2.0.0" + +regexpu-core@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" + dependencies: + regenerate "^1.2.1" + regjsgen "^0.2.0" + regjsparser "^0.1.4" + +regjsgen@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" + +regjsparser@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" + dependencies: + jsesc "~0.5.0" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + +repeat-element@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" + +repeat-string@^1.5.2: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + dependencies: + is-finite "^1.0.0" + +req-then@^0.6.4: + version "0.6.4" + resolved "https://registry.yarnpkg.com/req-then/-/req-then-0.6.4.tgz#9f9c04626afd311ae01d727846a0a1075c0e1965" + dependencies: + array-back "^2.0.0" + defer-promise "^1.0.1" + lodash.pick "^4.4.0" + stream-read-all "^0.1.0" + typical "^2.6.1" + +request@^2.81.0: + version "2.81.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" + dependencies: + aws-sign2 "~0.6.0" + aws4 "^1.2.1" + caseless "~0.12.0" + combined-stream "~1.0.5" + extend "~3.0.0" + forever-agent "~0.6.1" + form-data "~2.1.1" + har-validator "~4.2.1" + hawk "~3.1.3" + http-signature "~1.1.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.7" + oauth-sign "~0.8.1" + performance-now "^0.2.0" + qs "~6.4.0" + safe-buffer "^5.0.1" + stringstream "~0.0.4" + tough-cookie "~2.3.0" + tunnel-agent "^0.6.0" + uuid "^3.0.0" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + +require-uncached@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" + dependencies: + caller-path "^0.1.0" + resolve-from "^1.0.0" + +requizzle@~0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/requizzle/-/requizzle-0.2.1.tgz#6943c3530c4d9a7e46f1cddd51c158fc670cdbde" + dependencies: + underscore "~1.6.0" + +resolve-from@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" + +resolve-from@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57" + +resolve@^1.1.6, resolve@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.4.0.tgz#a75be01c53da25d934a98ebd0e4c4a7312f92a86" + dependencies: + path-parse "^1.0.5" + +restore-cursor@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" + dependencies: + exit-hook "^1.0.0" + onetime "^1.0.0" + +revalidator@0.1.x: + version "0.1.8" + resolved "https://registry.yarnpkg.com/revalidator/-/revalidator-0.1.8.tgz#fece61bfa0c1b52a206bd6b18198184bdd523a3b" + +right-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" + dependencies: + align-text "^0.1.1" + +rimraf@2, rimraf@2.x.x, rimraf@^2.2.8, rimraf@^2.3.3, rimraf@^2.5.1, rimraf@^2.5.4, rimraf@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d" + dependencies: + glob "^7.0.5" + +run-async@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389" + dependencies: + once "^1.3.0" + +rx-lite@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" + +safe-buffer@^5.0.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" + +samsam@1.x, samsam@^1.1.3: + version "1.2.1" + resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.2.1.tgz#edd39093a3184370cb859243b2bdf255e7d8ea67" + +"semver@2 || 3 || 4 || 5", semver@^5.3.0: + version "5.4.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + +set-immediate-shim@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + +shelljs@^0.7.5: + version "0.7.8" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3" + dependencies: + glob "^7.0.0" + interpret "^1.0.0" + rechoir "^0.6.2" + +signal-exit@^3.0.0, signal-exit@^3.0.1, signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + +sinon-chai@^2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/sinon-chai/-/sinon-chai-2.13.0.tgz#b9a42e801c20234bfc2f43b29e6f4f61b60990c4" + +sinon@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-3.2.0.tgz#8848a66ab6e8b80b5532e3824f59f83ea2628c77" + dependencies: + diff "^3.1.0" + formatio "1.2.0" + lolex "^2.1.2" + native-promise-only "^0.8.1" + nise "^1.0.1" + path-to-regexp "^1.7.0" + samsam "^1.1.3" + text-encoding "0.6.4" + type-detect "^4.0.0" + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + +slice-ansi@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" + +slide@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" + +sntp@1.x.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" + dependencies: + hoek "2.x.x" + +sort-array@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sort-array/-/sort-array-1.1.2.tgz#b88986053c0170a7f9de63f18a49ec79c24c3e64" + dependencies: + array-back "^1.0.4" + object-get "^2.1.0" + typical "^2.6.0" + +source-map-support@^0.4.15: + version "0.4.15" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.15.tgz#03202df65c06d2bd8c7ec2362a193056fef8d3b1" + dependencies: + source-map "^0.5.6" + +source-map@^0.1.40, source-map@~0.1.7: + version "0.1.43" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" + dependencies: + amdefine ">=0.0.4" + +source-map@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" + dependencies: + amdefine ">=0.0.4" + +source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1: + version "0.5.6" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" + +spawn-wrap@^1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-1.3.8.tgz#fa2a79b990cbb0bb0018dca6748d88367b19ec31" + dependencies: + foreground-child "^1.5.6" + mkdirp "^0.5.0" + os-homedir "^1.0.1" + rimraf "^2.3.3" + signal-exit "^3.0.2" + which "^1.2.4" + +spdx-correct@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" + dependencies: + spdx-license-ids "^1.0.2" + +spdx-expression-parse@~1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c" + +spdx-license-ids@^1.0.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + +sshpk@^1.7.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3" + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + dashdash "^1.12.0" + getpass "^0.1.1" + optionalDependencies: + bcrypt-pbkdf "^1.0.0" + ecc-jsbn "~0.1.1" + jsbn "~0.1.0" + tweetnacl "~0.14.0" + +stack-trace@0.0.x: + version "0.0.10" + resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" + +stream-connect@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/stream-connect/-/stream-connect-1.0.2.tgz#18bc81f2edb35b8b5d9a8009200a985314428a97" + dependencies: + array-back "^1.0.2" + +stream-read-all@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/stream-read-all/-/stream-read-all-0.1.2.tgz#748718e89281fff6b0742918233415a6900387e1" + +stream-via@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/stream-via/-/stream-via-1.0.4.tgz#8dccbb0ac909328eb8bc8e2a4bd3934afdaf606c" + +string-width@^1.0.1, string-width@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +string-width@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string_decoder@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" + dependencies: + safe-buffer "~5.1.0" + +stringstream@~0.0.4: + version "0.0.5" + resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + dependencies: + ansi-regex "^3.0.0" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + dependencies: + is-utf8 "^0.2.0" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + +supports-color@3.1.2, supports-color@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" + dependencies: + has-flag "^1.0.0" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + +table-layout@^0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/table-layout/-/table-layout-0.4.2.tgz#10e9043c142a1e2d155da7257e478f0ef4981786" + dependencies: + array-back "^2.0.0" + deep-extend "~0.5.0" + lodash.padend "^4.6.1" + typical "^2.6.1" + wordwrapjs "^3.0.0" + +table@^3.7.8: + version "3.8.3" + resolved "https://registry.yarnpkg.com/table/-/table-3.8.3.tgz#2bbc542f0fda9861a755d3947fefd8b3f513855f" + dependencies: + ajv "^4.7.0" + ajv-keywords "^1.0.0" + chalk "^1.1.1" + lodash "^4.0.0" + slice-ansi "0.0.4" + string-width "^2.0.0" + +taffydb@2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/taffydb/-/taffydb-2.6.2.tgz#7cbcb64b5a141b6a2efc2c5d2c67b4e150b2a268" + +tar-pack@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.0.tgz#23be2d7f671a8339376cbdb0b8fe3fdebf317984" + dependencies: + debug "^2.2.0" + fstream "^1.0.10" + fstream-ignore "^1.0.5" + once "^1.3.3" + readable-stream "^2.1.4" + rimraf "^2.5.1" + tar "^2.2.1" + uid-number "^0.0.6" + +tar@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" + dependencies: + block-stream "*" + fstream "^1.0.2" + inherits "2" + +temp-path@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/temp-path/-/temp-path-1.0.0.tgz#24b1543973ab442896d9ad367dd9cbdbfafe918b" + +test-exclude@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.1.1.tgz#4d84964b0966b0087ecc334a2ce002d3d9341e26" + dependencies: + arrify "^1.0.1" + micromatch "^2.3.11" + object-assign "^4.1.0" + read-pkg-up "^1.0.1" + require-main-filename "^1.0.1" + +test-value@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/test-value/-/test-value-1.1.0.tgz#a09136f72ec043d27c893707c2b159bfad7de93f" + dependencies: + array-back "^1.0.2" + typical "^2.4.2" + +test-value@^2.0.0, test-value@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/test-value/-/test-value-2.1.0.tgz#11da6ff670f3471a73b625ca4f3fdcf7bb748291" + dependencies: + array-back "^1.0.3" + typical "^2.6.0" + +text-encoding@0.6.4: + version "0.6.4" + resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19" + +text-table@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + +through@^2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + dependencies: + os-tmpdir "~1.0.2" + +to-fast-properties@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + +tough-cookie@~2.3.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a" + dependencies: + punycode "^1.4.1" + +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + +tryit@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + dependencies: + prelude-ls "~1.1.2" + +type-detect@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-3.0.0.tgz#46d0cc8553abb7b13a352b0d6dea2fd58f2d9b55" + +type-detect@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.3.tgz#0e3f2670b44099b0b46c284d136a7ef49c74c2ea" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + +typical@^2.4.2, typical@^2.6.0, typical@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/typical/-/typical-2.6.1.tgz#5c080e5d661cbbe38259d2e70a3c7253e873881d" + +uglify-js@^2.6: + version "2.8.29" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" + dependencies: + source-map "~0.5.1" + yargs "~3.10.0" + optionalDependencies: + uglify-to-browserify "~1.0.0" + +uglify-js@~2.3: + version "2.3.6" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.3.6.tgz#fa0984770b428b7a9b2a8058f46355d14fef211a" + dependencies: + async "~0.2.6" + optimist "~0.3.5" + source-map "~0.1.7" + +uglify-to-browserify@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" + +uid-number@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" + +underscore-contrib@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/underscore-contrib/-/underscore-contrib-0.3.0.tgz#665b66c24783f8fa2b18c9f8cbb0e2c7d48c26c7" + dependencies: + underscore "1.6.0" + +underscore@1.6.0, underscore@~1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.6.0.tgz#8b38b10cacdef63337b8b24e4ff86d45aea529a8" + +underscore@~1.8.3: + version "1.8.3" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022" + +universalify@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7" + +usage-stats@^0.9.0: + version "0.9.4" + resolved "https://registry.yarnpkg.com/usage-stats/-/usage-stats-0.9.4.tgz#ff06ba51d824faa1982f48a055dea8495a249077" + dependencies: + array-back "^2.0.0" + home-path "^1.0.5" + mkdirp2 "^1.0.3" + req-then "^0.6.4" + typical "^2.6.1" + uuid "^3.1.0" + +user-home@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" + +user-home@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" + dependencies: + os-homedir "^1.0.0" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + +utile@0.3.x: + version "0.3.0" + resolved "https://registry.yarnpkg.com/utile/-/utile-0.3.0.tgz#1352c340eb820e4d8ddba039a4fbfaa32ed4ef3a" + dependencies: + async "~0.9.0" + deep-equal "~0.2.1" + i "0.3.x" + mkdirp "0.x.x" + ncp "1.0.x" + rimraf "2.x.x" + +uuid@^3.0.0, uuid@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" + +v8flags@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.1.1.tgz#aab1a1fa30d45f88dd321148875ac02c0b55e5b4" + dependencies: + user-home "^1.1.1" + +validate-npm-package-license@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" + dependencies: + spdx-correct "~1.0.0" + spdx-expression-parse "~1.0.0" + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +walk-back@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/walk-back/-/walk-back-2.0.1.tgz#554e2a9d874fac47a8cb006bf44c2f0c4998a0a4" + +walk-back@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/walk-back/-/walk-back-3.0.0.tgz#2358787a35da91032dad5e92f80b12370d8795c5" + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + +which@^1.2.4, which@^1.2.9: + version "1.3.0" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.2.tgz#571e0f1b0604636ebc0dfc21b0339bbe31341710" + dependencies: + string-width "^1.0.2" + +window-size@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" + +winston@2.1.x: + version "2.1.1" + resolved "https://registry.yarnpkg.com/winston/-/winston-2.1.1.tgz#3c9349d196207fd1bdff9d4bc43ef72510e3a12e" + dependencies: + async "~1.0.0" + colors "1.0.x" + cycle "1.0.x" + eyes "0.1.x" + isstream "0.1.x" + pkginfo "0.3.x" + stack-trace "0.0.x" + +wordwrap@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" + +wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + +wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + +wordwrapjs@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/wordwrapjs/-/wordwrapjs-3.0.0.tgz#c94c372894cadc6feb1a66bff64e1d9af92c5d1e" + dependencies: + reduce-flatten "^1.0.1" + typical "^2.6.1" + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + +write-file-atomic@^1.1.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.3.4.tgz#f807a4f0b1d9e913ae7a48112e6cc3af1991b45f" + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + slide "^1.1.5" + +write@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" + dependencies: + mkdirp "^0.5.1" + +xtend@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + +y18n@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + +yargs-parser@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a" + dependencies: + camelcase "^3.0.0" + +yargs-parser@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9" + dependencies: + camelcase "^4.1.0" + +yargs@^8.0.1: + version "8.0.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-8.0.2.tgz#6299a9055b1cefc969ff7e79c1d918dceb22c360" + dependencies: + camelcase "^4.1.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^2.0.0" + read-pkg-up "^2.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1" + yargs-parser "^7.0.0" + +yargs@~3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" + dependencies: + camelcase "^1.0.2" + cliui "^2.1.0" + decamelize "^1.0.0" + window-size "0.1.0" From f1f8ba072eb08badfcdb689f4a9d319e730c77af Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Fri, 18 Aug 2017 09:15:22 -0700 Subject: [PATCH 12/42] Bump `sinon` to 3.2.1 --- package.json | 2 +- yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index f236246..2ebef2d 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "mocha": "^3.4.2", "nyc": "^11.0.3", "prompt": "^1.0.0", - "sinon": "^3.2.0", + "sinon": "^3.2.1", "sinon-chai": "^2.13.0" }, "dependencies": { diff --git a/yarn.lock b/yarn.lock index b31bb8f..82845e9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3038,9 +3038,9 @@ sinon-chai@^2.13.0: version "2.13.0" resolved "https://registry.yarnpkg.com/sinon-chai/-/sinon-chai-2.13.0.tgz#b9a42e801c20234bfc2f43b29e6f4f61b60990c4" -sinon@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/sinon/-/sinon-3.2.0.tgz#8848a66ab6e8b80b5532e3824f59f83ea2628c77" +sinon@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-3.2.1.tgz#d8adabd900730fd497788a027049c64b08be91c2" dependencies: diff "^3.1.0" formatio "1.2.0" From 4c099e5df426179ead6d72a68919fc37cb4f7e9c Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Mon, 21 Aug 2017 08:25:34 -0700 Subject: [PATCH 13/42] Stop swallowing Promise rejections in specs For a more complete description: http://eng.wealthfront.com/2016/11/03/handling-unhandledrejections-in-node-and-the-browser/ --- test/runner.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/test/runner.js b/test/runner.js index d1cb728..fed9d77 100644 --- a/test/runner.js +++ b/test/runner.js @@ -19,6 +19,12 @@ import exec from '../build/src/utils/execHelper'; import * as testLFSServer from './server/server'; +// http://eng.wealthfront.com/2016/11/03/handling-unhandledrejections-in-node-and-the-browser/ +process.on('unhandledRejection', (err) => { + console.error(err); // eslint-disable-line no-console + process.exit(1); +}); + chai.use(sinonChai); before(function () { // eslint-disable-line prefer-arrow-callback @@ -39,12 +45,9 @@ before(function () { // eslint-disable-line prefer-arrow-callback })) .then(() => fse.appendFile( path.join(lfsTestRepoPath, '.git', 'config'), -`[http] + `[http] sslverify = false` - )) - .catch((err) => { - throw new Error(err); - }); + )); }); beforeEach(() => From 9a333dd34c682d38d1c5208b44d4aa2da5202139 Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Mon, 21 Aug 2017 08:33:47 -0700 Subject: [PATCH 14/42] Finish `spawnHelper` tests --- test/tests/utils/execHelper.spec.js | 18 +- test/tests/utils/spawnHelper.spec.js | 312 +++++++++++++++++++++++++-- test/utils.js | 13 -- 3 files changed, 311 insertions(+), 32 deletions(-) diff --git a/test/tests/utils/execHelper.spec.js b/test/tests/utils/execHelper.spec.js index 65c912f..f599d6b 100644 --- a/test/tests/utils/execHelper.spec.js +++ b/test/tests/utils/execHelper.spec.js @@ -2,17 +2,27 @@ import { expect } from 'chai'; import childProcess from 'child_process'; +import sinon from 'sinon'; import { - fail, - spyDescribe + fail } from '../../utils'; import exec from '../../../src/utils/execHelper'; -spyDescribe('exec', (sandbox) => { +describe('exec', () => { beforeEach(function () { - this.execSpy = sandbox.stub(childProcess, 'exec').returns('proc object'); + this.sandbox = sinon.sandbox.create(); + + this.execSpy = this.sandbox.stub(childProcess, 'exec').returns('proc object'); + }); + + afterEach(function () { + const { + sandbox + } = this; + + sandbox.restore(); }); it('resolves with the spawned process and its stdout and stderr on success', function () { diff --git a/test/tests/utils/spawnHelper.spec.js b/test/tests/utils/spawnHelper.spec.js index 35093af..64808da 100644 --- a/test/tests/utils/spawnHelper.spec.js +++ b/test/tests/utils/spawnHelper.spec.js @@ -1,27 +1,309 @@ -import path from 'path'; +import { + expect +} from 'chai'; +import childProcess from 'child_process'; +import sinon from 'sinon'; + +import { + fail +} from '../../utils'; -import { todo } from '../../utils'; import spawn from '../../../build/src/utils/spawnHelper'; describe('spawn', () => { - it('mimics child_process.spawn when no arguments are provided', () => { - spawn('git lfs version') - .then(() => todo()); + beforeEach(function () { + this.sandbox = sinon.sandbox.create(); + + this.mockProcess = { + kill: this.sandbox.spy(), + on: this.sandbox.spy(), + stderr: { + on: this.sandbox.spy() + }, + stdin: { + write: this.sandbox.spy() + }, + stdout: { + on: this.sandbox.spy() + }, + unref: this.sandbox.spy() + }; + this.spawnStub = this.sandbox.stub(childProcess, 'spawn').returns(this.mockProcess); }); - it('mimics child_process.spawn when arguments are provided', () => { - spawn('ls', ['-lart']) - .then(() => todo()); + afterEach(function () { + const { + sandbox + } = this; + + sandbox.restore(); }); - it('mimics child_process.spawn when options are provided', () => { - spawn('ls -lart', { cwd: path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository') }) - .then(() => todo()); + if (process.platform === 'win32') { + it('correctly overrides `detached` on Windows', function () { + const { + spawnStub + } = this; + + spawn('command', { detached: true, foo: 'bar' }); + expect(spawnStub).to.have.been.calledWithMatch('command', [], { + detached: false, + foo: 'bar', + env: process.env, + shell: true + }); + }); + } + + if (process.platform === 'darwin') { + it('correctly overrides `detached` on macOS', function () { + const { + spawnStub + } = this; + + spawn('command', { detached: true, foo: 'bar' }); + expect(spawnStub).to.have.been.calledWithMatch('command', [], { + detached: false, + foo: 'bar', + env: process.env, + shell: true + }); + }); + } + + if (process.platform === 'linux') { + it('correctly overrides `detached` on Linux', function () { + const { + spawnStub + } = this; + + spawn('command', { detached: false, foo: 'bar' }); + expect(spawnStub).to.have.been.calledWithMatch('command', [], { + detached: true, + foo: 'bar', + env: process.env, + shell: true + }); + }); + } + + it("merges the calling process' env into the provided env", function () { + const { + sandbox, + spawnStub + } = this; + + sandbox.stub(process, 'env').get(() => ({ + foo: 'override', + baz: 'quux' + })); + + spawn('command', { env: { foo: 'bar' } }); + expect(spawnStub).to.have.been.calledWithMatch('command', [], { + env: { + foo: 'bar', + baz: 'quux' + } + }); }); - it('can take a callback', () => { - const callback = innerCb => innerCb('John Doe', 'password'); - return spawn('./mock-creds', { cwd: path.resolve(__dirname, '..', '..') }, callback) - .then(() => todo()); + it('correctly overrides `shell`', function () { + const { + spawnStub + } = this; + + spawn('command', { shell: false }); + expect(spawnStub).to.have.been.calledWithMatch('command', [], { + shell: true + }); + }); + + if (process.platform === 'darwin' || process.platform === 'win32') { + it('correctly calculates arguments on Windows or macOS', function () { + const { + spawnStub + } = this; + + spawn('command arg1 arg2'); + expect(spawnStub).to.have.been.calledWithMatch('command', ['arg1', 'arg2'], { + detached: false, + env: process.env, + shell: true + }); + }); + } + + if (process.platform === 'linux') { + it('correctly calculates arguments on Linux', function () { + const { + spawnStub + } = this; + + spawn('command arg1 arg2'); + expect(spawnStub).to.have.been.calledWithMatch( + 'script --return -c "command arg1 arg2" /dev/null', + [], + { + detached: true, + env: process.env, + shell: true + } + ); + }); + } + + if (process.platform === 'linux') { + it('correctly handles `git lfs smudge` on Linux', function () { + const { + spawnStub + } = this; + + spawn('git lfs smudge', { + input: 'file.txt' + }); + expect(spawnStub).to.have.been.calledWithMatch( + 'cat file.txt | git lfs smudge', + [], + { + detached: true, + env: process.env, + shell: true + } + ); + }); + } + + describe('when passed a callback', () => { + afterEach(function () { + const { + sandbox + } = this; + + sandbox.restore(); + }); + + it('ignores the callback if it is not a `Function`', function () { + const { + mockProcess + } = this; + + spawn('', {}, 'not a callback'); + const stdoutHandler = mockProcess.stdout.on.firstCall.args[1]; + stdoutHandler(new Buffer('some data')); + }); + + it('uses the callback to obtain credentials', function () { + const { + mockProcess, + sandbox + } = this; + + const cbStub = sandbox.stub().callsFake((cb) => { + cb('some username', 'some password', false); + }); + spawn('', {}, cbStub); + const stdoutHandler = mockProcess.stdout.on.firstCall.args[1]; + stdoutHandler(new Buffer('Username: ')); + expect(mockProcess.stdin.write.firstCall.args[0].toString()).to.equal('some username\n'); + stdoutHandler(new Buffer('Password: ')); + expect(mockProcess.stdin.write.secondCall.args[0].toString()).to.equal('some password\n'); + + expect(cbStub).to.have.been.calledOnce; + }); + + it('does not require the callback to send a password', function () { + const { + mockProcess, + sandbox + } = this; + + const cbStub = sandbox.stub().callsFake((cb) => { + cb('some username', '', false); + }); + spawn('', {}, cbStub); + const stdoutHandler = mockProcess.stdout.on.firstCall.args[1]; + stdoutHandler(new Buffer('Username: ')); + expect(mockProcess.stdin.write.firstCall.args[0].toString()).to.equal('some username\n'); + stdoutHandler(new Buffer('Password: ')); + expect(mockProcess.stdin.write.secondCall.args[0].toString()).to.equal('\n'); + + expect(cbStub).to.have.been.calledOnce; + }); + + it('allows the callback to cancel', function () { + const { + mockProcess + } = this; + + const promise = spawn('', {}, (cb) => { + cb(undefined, undefined, true); + }); + const stdoutHandler = mockProcess.stdout.on.firstCall.args[1]; + stdoutHandler(new Buffer('Username: ')); + return promise + .then(() => fail('The promise should have failed!')) + .catch((err) => { + expect(err.message).to.equal('LFS action cancelled'); + }); + }); + }); + + describe('when `spawn` completes successfully', () => { + afterEach(function () { + const { + sandbox + } = this; + + sandbox.restore(); + }); + + it('resolves with the exit code, processed stdout, and stderr', function () { + const { + mockProcess + } = this; + + const promise = spawn(''); + const closeHandler = mockProcess.on.firstCall.args[1]; + const stderrHandler = mockProcess.stderr.on.firstCall.args[1]; + const stdoutHandler = mockProcess.stdout.on.firstCall.args[1]; + stderrHandler('some stderr, line 1\n'); + stderrHandler('some stderr, line 2'); + stdoutHandler('some stdout, line 1\n'); + stdoutHandler('some stdout, line 2'); + closeHandler(0); + return promise + .then((result) => { + expect(result).to.eql({ + code: 0, + stderr: 'some stderr, line 1\nsome stderr, line 2', + stdout: 'some stdout, line 1\nsome stdout, line 2' + }); + }); + }); + }); + + describe('when `spawn` errors', () => { + afterEach(function () { + const { + sandbox + } = this; + + sandbox.restore(); + }); + + it('rejects with the exit code', function () { + const { + mockProcess + } = this; + + const promise = spawn(''); + const errorHandler = mockProcess.on.secondCall.args[1]; + errorHandler(-1337); + return promise + .then(() => fail('This promise should have failed!')) + .catch((err) => { + expect(err).to.equal(-1337); + }); + }); }); }); diff --git a/test/utils.js b/test/utils.js index f76d10a..6104dc2 100644 --- a/test/utils.js +++ b/test/utils.js @@ -3,7 +3,6 @@ import { } from 'chai'; import crypto from 'crypto'; import fse from 'fs-extra'; -import sinon from 'sinon'; import spawn from '../build/src/utils/spawnHelper'; @@ -22,18 +21,6 @@ export const getFilePointer = (workdir, fileName) => spawn(`git show HEAD:${fileName}`, { cwd: workdir, env: { GIT_PAGER: 'cat' } }) .then(({ stdout }) => stdout.toString()); -export const spyDescribe = (message, fn) => { - const sandbox = sinon.createSandbox(); - - describe(message, () => { - fn(sandbox); - - afterEach(() => { - sandbox.restore(); - }); - }); -}; - export const todo = () => { fail('TODO'); }; From 3dba9143edd371db73abc5d70090aedca9f2113e Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Mon, 21 Aug 2017 08:45:06 -0700 Subject: [PATCH 15/42] Finish helper tests --- test/tests/utils/generateResponse.spec.js | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/test/tests/utils/generateResponse.spec.js b/test/tests/utils/generateResponse.spec.js index d3e2486..f89795d 100644 --- a/test/tests/utils/generateResponse.spec.js +++ b/test/tests/utils/generateResponse.spec.js @@ -1,7 +1,19 @@ -import { todo } from '../../utils'; +import { + expect +} from 'chai'; +import { + Error +} from 'nodegit'; + +import generateResponse from '../../../build/src/utils/generateResponse'; describe('generateResponse', () => { - it('does generate response', () => { - todo(); + it('generates a default successful response', () => { + expect(generateResponse()).to.eql({ + success: true, + errno: Error.CODE.OK, + raw: '', + stderr: '' + }); }); }); From eb68183ab172a193deb15a4ca2376f13da4d7228 Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Mon, 21 Aug 2017 10:10:45 -0700 Subject: [PATCH 16/42] Add object rest spread Babel plugin and fix devDependencies issue On CI, `devDependencies` won't be installed, but Babel is required to `compile`, etc. --- .babelrc | 3 ++- package.json | 7 ++++--- yarn.lock | 11 +++++++++++ 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/.babelrc b/.babelrc index af0f0c3..dd162c5 100644 --- a/.babelrc +++ b/.babelrc @@ -1,3 +1,4 @@ { + "plugins": ["transform-object-rest-spread"], "presets": ["es2015"] -} \ No newline at end of file +} diff --git a/package.json b/package.json index 2ebef2d..96e724c 100644 --- a/package.json +++ b/package.json @@ -36,9 +36,6 @@ "nodegit": ">=0.20.1" }, "devDependencies": { - "babel-cli": "^6.24.1", - "babel-core": "^6.25.0", - "babel-preset-es2015": "^6.24.1", "chai": "^4.0.2", "eslint": "^3.19.0", "eslint-config-airbnb-base": "^11.2.0", @@ -53,6 +50,10 @@ "sinon-chai": "^2.13.0" }, "dependencies": { + "babel-cli": "^6.24.1", + "babel-core": "^6.25.0", + "babel-plugin-transform-object-rest-spread": "^6.26.0", + "babel-preset-es2015": "^6.24.1", "default-shell": "^1.0.1", "fs-extra": "^3.0.1", "ignore": "^3.3.3", diff --git a/yarn.lock b/yarn.lock index 82845e9..2dfec11 100644 --- a/yarn.lock +++ b/yarn.lock @@ -359,6 +359,10 @@ babel-plugin-check-es2015-constants@^6.22.0: dependencies: babel-runtime "^6.22.0" +babel-plugin-syntax-object-rest-spread@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" + babel-plugin-transform-es2015-arrow-functions@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" @@ -527,6 +531,13 @@ babel-plugin-transform-es2015-unicode-regex@^6.24.1: babel-runtime "^6.22.0" regexpu-core "^2.0.0" +babel-plugin-transform-object-rest-spread@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz#0f36692d50fef6b7e2d4b3ac1478137a963b7b06" + dependencies: + babel-plugin-syntax-object-rest-spread "^6.8.0" + babel-runtime "^6.26.0" + babel-plugin-transform-regenerator@^6.24.1: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" From afd61543dc190a72d8419cf04034f3354a72a1ca Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Mon, 21 Aug 2017 12:48:50 -0700 Subject: [PATCH 17/42] Don't redefine `NodeGitLFS` in tests --- test/tests/commands/clone.spec.js | 9 +++++---- test/tests/commands/ls.spec.js | 9 +++++---- test/tests/commands/pointer.spec.js | 9 +++++---- test/tests/commands/prune.spec.js | 9 +++++---- test/tests/commands/push.spec.js | 9 +++++---- test/tests/commands/track.spec.js | 9 +++++---- test/tests/commands/untrack.spec.js | 11 +++++++---- test/tests/commands/version.spec.js | 9 +++++---- test/tests/index.spec.js | 30 +++++++++++++++++++---------- test/tests/initialize.spec.js | 15 ++++++++++----- test/tests/register.spec.js | 18 ++++++++++------- 11 files changed, 83 insertions(+), 54 deletions(-) diff --git a/test/tests/commands/clone.spec.js b/test/tests/commands/clone.spec.js index 237015d..32674b0 100644 --- a/test/tests/commands/clone.spec.js +++ b/test/tests/commands/clone.spec.js @@ -1,12 +1,13 @@ import path from 'path'; -import NodeGit from 'nodegit'; import { todo } from '../../utils'; -import LFS from '../../../build/src'; describe('Clone', () => { - it('should generate clone repsonse', () => { + it('should generate clone repsonse', function () { + const { + NodeGitLFS + } = this; + const emptyRepoPath = path.resolve(__dirname, '..', '..', 'repos', 'empty'); - const NodeGitLFS = LFS(NodeGit); const url = 'https://github.com/jgrosso/nodegit-lfs-test-repo'; return NodeGitLFS.LFS.clone(url, emptyRepoPath, { branch: 'test', env: { GIT_SSL_NO_VERIFY: 1 } }) diff --git a/test/tests/commands/ls.spec.js b/test/tests/commands/ls.spec.js index 7a709c6..b737e88 100644 --- a/test/tests/commands/ls.spec.js +++ b/test/tests/commands/ls.spec.js @@ -1,13 +1,14 @@ -import NodeGit from 'nodegit'; import path from 'path'; import { todo } from '../../utils'; -import LFS from '../../../build/src'; import ls from '../../../build/src/commands/ls'; describe('ls-files', () => { - it('does generate ls response', () => { + it('does generate ls response', function () { + const { + NodeGitLFS + } = this; + const lfsTestRepoPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); - const NodeGitLFS = LFS(NodeGit); return NodeGitLFS.Repository.open(lfsTestRepoPath) .then(repo => ls(repo, { long: true })) diff --git a/test/tests/commands/pointer.spec.js b/test/tests/commands/pointer.spec.js index 188385c..ff28be2 100644 --- a/test/tests/commands/pointer.spec.js +++ b/test/tests/commands/pointer.spec.js @@ -1,13 +1,14 @@ -import NodeGit from 'nodegit'; import path from 'path'; import { todo } from '../../utils'; -import LFS from '../../../build/src'; import pointer from '../../../build/src/commands/pointer'; describe('Pointer', () => { - it('does generate pointer response', () => { + it('does generate pointer response', function () { + const { + NodeGitLFS + } = this; + const lfsTestRepoPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); - const NodeGitLFS = LFS(NodeGit); const packageJson = path.join(lfsTestRepoPath, 'package.json'); diff --git a/test/tests/commands/prune.spec.js b/test/tests/commands/prune.spec.js index acf896c..e67b086 100644 --- a/test/tests/commands/prune.spec.js +++ b/test/tests/commands/prune.spec.js @@ -1,13 +1,14 @@ -import NodeGit from 'nodegit'; import path from 'path'; import { todo } from '../../utils'; -import LFS from '../../../build/src'; import prune from '../../../build/src/commands/prune'; describe('Prune', () => { - it('does generate prune response', () => { + it('does generate prune response', function () { + const { + NodeGitLFS + } = this; + const lfsTestRepoPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); - const NodeGitLFS = LFS(NodeGit); return NodeGitLFS.Repository.open(lfsTestRepoPath) .then(repo => prune(repo)) diff --git a/test/tests/commands/push.spec.js b/test/tests/commands/push.spec.js index f0327c9..bbb3922 100644 --- a/test/tests/commands/push.spec.js +++ b/test/tests/commands/push.spec.js @@ -1,16 +1,17 @@ import path from 'path'; -import NodeGit from 'nodegit'; import { createDummyFile, todo } from '../../utils'; -import LFS from '../../../build/src'; import exec from '../../../build/src/utils/execHelper'; describe('Push', () => { - it('should generate push response', () => { + it('should generate push response', function () { + const { + NodeGitLFS + } = this; + const lfsTestRepoPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); - const NodeGitLFS = LFS(NodeGit); return createDummyFile(path.join(lfsTestRepoPath, 'test_file.txt'), 20) .then(() => exec('git add test_file.txt', { cwd: lfsTestRepoPath })) diff --git a/test/tests/commands/track.spec.js b/test/tests/commands/track.spec.js index c88e016..ed6bff3 100644 --- a/test/tests/commands/track.spec.js +++ b/test/tests/commands/track.spec.js @@ -1,13 +1,14 @@ -import NodeGit from 'nodegit'; import path from 'path'; import { todo } from '../../utils'; -import LFS from '../../../build/src'; import track from '../../../build/src/commands/track'; describe('Track', () => { - it('does generate track response', () => { + it('does generate track response', function () { + const { + NodeGitLFS + } = this; + const lfsTestRepoPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); - const NodeGitLFS = LFS(NodeGit); return NodeGitLFS.Repository.open(lfsTestRepoPath) .then(repo => track(repo, ['*.png', '*.dmg'])) diff --git a/test/tests/commands/untrack.spec.js b/test/tests/commands/untrack.spec.js index 3a74f93..13a17e6 100644 --- a/test/tests/commands/untrack.spec.js +++ b/test/tests/commands/untrack.spec.js @@ -1,15 +1,18 @@ -import NodeGit from 'nodegit'; import path from 'path'; import { todo } from '../../utils'; -import LFS from '../../../build/src'; import track from '../../../build/src/commands/track'; import untrack from '../../../build/src/commands/untrack'; describe('Untrack', () => { - it('does generate untrack response', () => { + it('does generate untrack response', function () { + const { + NodeGitLFS + } = this; + const lfsTestRepoPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); - const NodeGitLFS = LFS(NodeGit); + let repository; + return NodeGitLFS.Repository.open(lfsTestRepoPath) .then((repo) => { repository = repo; diff --git a/test/tests/commands/version.spec.js b/test/tests/commands/version.spec.js index f39fca8..e6ecf29 100644 --- a/test/tests/commands/version.spec.js +++ b/test/tests/commands/version.spec.js @@ -1,13 +1,14 @@ -import NodeGit from 'nodegit'; import path from 'path'; import { todo } from '../../utils'; -import LFS from '../../../build/src'; import version from '../../../build/src/commands/version'; describe('Version', () => { - it('does provide version number', () => { + it('does provide version number', function () { + const { + NodeGitLFS + } = this; + const lfsTestRepoPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); - const NodeGitLFS = LFS(NodeGit); return NodeGitLFS.Repository.open(lfsTestRepoPath) .then(repo => version(repo)) diff --git a/test/tests/index.spec.js b/test/tests/index.spec.js index 58cf86e..16df915 100644 --- a/test/tests/index.spec.js +++ b/test/tests/index.spec.js @@ -1,26 +1,36 @@ import { expect } from 'chai'; -import NodeGit from 'nodegit'; -import LFS from '../../build/src'; describe('LFS', () => { - it('LFS exists', () => { - const NodeGitLFS = LFS(NodeGit); + it('LFS exists', function () { + const { + NodeGitLFS + } = this; + expect(NodeGitLFS).to.have.property('LFS'); }); - it('initialize exists', () => { - const NodeGitLFS = LFS(NodeGit); + it('initialize exists', function () { + const { + NodeGitLFS + } = this; + expect(NodeGitLFS.LFS).to.have.property('initialize'); }); - it('register exists', () => { - const NodeGitLFS = LFS(NodeGit); + it('register exists', function () { + const { + NodeGitLFS + } = this; + expect(NodeGitLFS.LFS).to.have.property('register'); expect(NodeGitLFS.LFS.register).to.be.a('function'); }); - it('unregister exists', () => { - const NodeGitLFS = LFS(NodeGit); + it('unregister exists', function () { + const { + NodeGitLFS + } = this; + expect(NodeGitLFS.LFS).to.have.property('unregister'); expect(NodeGitLFS.LFS.unregister).to.be.a('function'); }); diff --git a/test/tests/initialize.spec.js b/test/tests/initialize.spec.js index bd4c75c..b82414f 100644 --- a/test/tests/initialize.spec.js +++ b/test/tests/initialize.spec.js @@ -1,12 +1,13 @@ import path from 'path'; import fs from 'fs'; -import NodeGit from 'nodegit'; import { expect } from 'chai'; -import LFS from '../../build/src'; describe('Initialize', () => { it('initialize is a promise', () => { - const NodeGitLFS = LFS(NodeGit); + const { + NodeGitLFS + } = this; + const lfsTestRepoPath = path.resolve(__dirname, '..', 'repos', 'lfs-test-repository'); return NodeGitLFS.Repository.open(lfsTestRepoPath) @@ -16,9 +17,13 @@ describe('Initialize', () => { }); }); - it('creates .gitattributes for empty repo', () => { - const NodeGitLFS = LFS(NodeGit); + it('creates .gitattributes for empty repo', function () { + const { + NodeGitLFS + } = this; + const emptyRepoPath = path.resolve(__dirname, '..', 'repos', 'empty'); + expect(fs.existsSync(path.join(emptyRepoPath, '.gitattributes'))).to.be.false; return NodeGitLFS.Repository.open(emptyRepoPath) diff --git a/test/tests/register.spec.js b/test/tests/register.spec.js index 8dc4e2b..4507608 100644 --- a/test/tests/register.spec.js +++ b/test/tests/register.spec.js @@ -1,10 +1,11 @@ import { expect } from 'chai'; -import NodeGit from 'nodegit'; -import LFS from '../../build/src'; -describe('Register:', () => { - it('has register callback', () => { - const NodeGitLFS = LFS(NodeGit); +describe('Register', () => { + it('has register callback', function () { + const { + NodeGitLFS + } = this; + return NodeGitLFS.LFS.register() .then((result) => { expect(result).to.be.a('number'); @@ -12,8 +13,11 @@ describe('Register:', () => { }); }); - it('cannot re-register LFS filter twice', () => { - const NodeGitLFS = LFS(NodeGit); + it('cannot re-register LFS filter twice', function () { + const { + NodeGitLFS + } = this; + return NodeGitLFS.LFS.register() .then((result) => { expect(result).to.be.a('number'); From 0cd12afbfe96dbd0b7408f0fc2b76ab9b9eb6d8c Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Mon, 21 Aug 2017 12:55:44 -0700 Subject: [PATCH 18/42] Finish `unregister` tests --- test/tests/unregister.spec.js | 40 +++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 test/tests/unregister.spec.js diff --git a/test/tests/unregister.spec.js b/test/tests/unregister.spec.js new file mode 100644 index 0000000..6f4bf9a --- /dev/null +++ b/test/tests/unregister.spec.js @@ -0,0 +1,40 @@ +import { + expect +} from 'chai'; + +describe('Unregister', () => { + beforeEach(function () { + const { + NodeGitLFS + } = this; + + return NodeGitLFS.LFS.register(); + }); + + it('can unregister the LFS filter', function () { + const { + NodeGitLFS + } = this; + + return NodeGitLFS.LFS.unregister() + .then((result) => { + expect(result).to.equal(0); + }); + }); + + it('cannot unregister the LFS filter twice', function () { + const { + NodeGitLFS + } = this; + + return NodeGitLFS.LFS.unregister() + .then((result) => { + expect(result).to.equal(0); + }) + .then(() => NodeGitLFS.LFS.unregister()) + .then(() => expect.fail('Failed to re-unregister!')) + .catch((err) => { + expect(err.errno).to.equal(-3); + }); + }); +}); From 9a7ed042c0817e0f5a12a1547481eb4e69a317e0 Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Mon, 21 Aug 2017 13:03:08 -0700 Subject: [PATCH 19/42] Remove unnecessary `regexResult` helper --- src/commands/checkout.js | 9 ++++----- src/commands/clone.js | 12 ++++++------ src/commands/fetch.js | 12 ++++++------ src/commands/pull.js | 12 ++++++------ src/commands/push.js | 12 ++++++------ src/helpers.js | 2 -- 6 files changed, 28 insertions(+), 31 deletions(-) diff --git a/src/commands/checkout.js b/src/commands/checkout.js index f24e56d..878c5c5 100644 --- a/src/commands/checkout.js +++ b/src/commands/checkout.js @@ -8,7 +8,6 @@ import { import generateResponse from '../utils/generateResponse'; import { - regexResult, verifyOutput, errorCatchHandler } from '../helpers'; @@ -22,7 +21,7 @@ const generateCheckoutStats = (raw) => { const filteredLines = R.filter(isValidLine, outputLines); const statLine = filteredLines.pop(); - const byteResults = regexResult(statLine, regex.TOTAL_BYTES); + const byteResults = statLine.match(regex.TOTAL_BYTES); stats.total_bytes_checked_out = byteResults !== null ? @@ -32,19 +31,19 @@ const generateCheckoutStats = (raw) => { byteResults !== null ? byteResults[1].trim() : BAD_REGEX_PARSE_RESULT; - const fileResults = regexResult(statLine, regex.TOTAL_FILES); + const fileResults = statLine.match(regex.TOTAL_FILES); stats.total_files_checked_out = fileResults !== null ? fileResults[0].trim() : BAD_REGEX_PARSE_RESULT; - const skippedByteResults = regexResult(statLine, regex.SKIPPED_BYTES); + const skippedByteResults = statLine.match(regex.SKIPPED_BYTES); stats.total_bytes_skipped = skippedByteResults !== null ? skippedByteResults[0].trim() : BAD_REGEX_PARSE_RESULT; - const skippedFileResults = regexResult(statLine, regex.SKIPPED_FILES); + const skippedFileResults = statLine.match(regex.SKIPPED_FILES); stats.total_files_skipped = skippedFileResults !== null ? diff --git a/src/commands/clone.js b/src/commands/clone.js index ebb91a3..d5f4492 100644 --- a/src/commands/clone.js +++ b/src/commands/clone.js @@ -6,9 +6,9 @@ import { } from '../constants'; import generateResponse from '../utils/generateResponse'; import { - regexResult, errorCatchHandler, - verifyOutput } from '../helpers'; + verifyOutput +} from '../helpers'; const isValidLine = str => str !== ''; @@ -19,7 +19,7 @@ const generateCloneStats = (raw) => { const filteredLines = R.filter(isValidLine, outputLines); const statLine = filteredLines.pop(); - const byteResults = regexResult(statLine, regex.TOTAL_BYTES); + const byteResults = statLine.match(regex.TOTAL_BYTES); stats.total_bytes_cloned = byteResults !== null ? @@ -29,19 +29,19 @@ const generateCloneStats = (raw) => { byteResults !== null ? byteResults[1].trim() : BAD_REGEX_PARSE_RESULT; - const fileResults = regexResult(statLine, regex.TOTAL_FILES); + const fileResults = statLine.match(regex.TOTAL_FILES); stats.total_files_cloned = fileResults !== null ? fileResults[0].trim() : BAD_REGEX_PARSE_RESULT; - const skippedByteResults = regexResult(statLine, regex.SKIPPED_BYTES); + const skippedByteResults = statLine.match(regex.SKIPPED_BYTES); stats.total_bytes_skipped = skippedByteResults !== null ? skippedByteResults[0].trim() : BAD_REGEX_PARSE_RESULT; - const skippedFileResults = regexResult(statLine, regex.SKIPPED_FILES); + const skippedFileResults = statLine.match(regex.SKIPPED_FILES); stats.total_files_skipped = skippedFileResults !== null ? diff --git a/src/commands/fetch.js b/src/commands/fetch.js index 5c01748..0ebd738 100644 --- a/src/commands/fetch.js +++ b/src/commands/fetch.js @@ -7,9 +7,9 @@ import { } from '../constants'; import generateResponse from '../utils/generateResponse'; import { - regexResult, errorCatchHandler, - verifyOutput } from '../helpers'; + verifyOutput +} from '../helpers'; const isValidLine = str => str !== ''; @@ -20,7 +20,7 @@ const generateFetchStats = (raw) => { const filteredLines = R.filter(isValidLine, outputLines); const statLine = filteredLines.pop(); - const byteResults = regexResult(statLine, regex.TOTAL_BYTES); + const byteResults = statLine.match(regex.TOTAL_BYTES); stats.total_bytes_fetched = byteResults !== null ? @@ -30,19 +30,19 @@ const generateFetchStats = (raw) => { byteResults !== null ? byteResults[1].trim() : BAD_REGEX_PARSE_RESULT; - const fileResults = regexResult(statLine, regex.TOTAL_FILES); + const fileResults = statLine.match(regex.TOTAL_FILES); stats.total_files_fetched = fileResults !== null ? fileResults[0].trim() : BAD_REGEX_PARSE_RESULT; - const skippedByteResults = regexResult(statLine, regex.SKIPPED_BYTES); + const skippedByteResults = statLine.match(regex.SKIPPED_BYTES); stats.total_bytes_skipped = skippedByteResults !== null ? skippedByteResults[0].trim() : BAD_REGEX_PARSE_RESULT; - const skippedFileResults = regexResult(statLine, regex.SKIPPED_FILES); + const skippedFileResults = statLine.match(regex.SKIPPED_FILES); stats.total_files_skipped = skippedFileResults !== null ? diff --git a/src/commands/pull.js b/src/commands/pull.js index a6b2771..277bbb2 100644 --- a/src/commands/pull.js +++ b/src/commands/pull.js @@ -7,9 +7,9 @@ import { } from '../constants'; import generateResponse from '../utils/generateResponse'; import { - regexResult, verifyOutput, - errorCatchHandler } from '../helpers'; + errorCatchHandler +} from '../helpers'; const isValidLine = str => str !== ''; @@ -20,7 +20,7 @@ const generatePullStats = (raw) => { const filteredLines = R.filter(isValidLine, outputLines); const statLine = filteredLines.pop(); - const byteResults = regexResult(statLine, regex.TOTAL_BYTES); + const byteResults = statLine.match(regex.TOTAL_BYTES); stats.total_bytes_pulled = byteResults !== null ? @@ -30,19 +30,19 @@ const generatePullStats = (raw) => { byteResults !== null ? byteResults[1].trim() : BAD_REGEX_PARSE_RESULT; - const fileResults = regexResult(statLine, regex.TOTAL_FILES); + const fileResults = statLine.match(regex.TOTAL_FILES); stats.total_files_pulled = fileResults !== null ? fileResults[0].trim() : BAD_REGEX_PARSE_RESULT; - const skippedByteResults = regexResult(statLine, regex.SKIPPED_BYTES); + const skippedByteResults = statLine.match(regex.SKIPPED_BYTES); stats.total_bytes_skipped = skippedByteResults !== null ? skippedByteResults[0].trim() : BAD_REGEX_PARSE_RESULT; - const skippedFileResults = regexResult(statLine, regex.SKIPPED_FILES); + const skippedFileResults = statLine.match(regex.SKIPPED_FILES); stats.total_files_skipped = skippedFileResults !== null ? diff --git a/src/commands/push.js b/src/commands/push.js index 11125b7..ce59848 100644 --- a/src/commands/push.js +++ b/src/commands/push.js @@ -6,9 +6,9 @@ import { } from '../constants'; import generateResponse from '../utils/generateResponse'; import { - regexResult, errorCatchHandler, - verifyOutput } from '../helpers'; + verifyOutput +} from '../helpers'; /** * Note to future maintainers, I do not like this; at all. But at the moment this is the @@ -31,7 +31,7 @@ const generatePushStats = (raw) => { const filteredLines = R.filter(isValidLine, outputLines); const statLine = filteredLines.pop(); - const byteResults = regexResult(statLine, regex.TOTAL_BYTES); + const byteResults = statLine.match(regex.TOTAL_BYTES); stats.total_bytes_transferred = byteResults !== null ? byteResults[0].trim() @@ -41,19 +41,19 @@ const generatePushStats = (raw) => { ? byteResults[1].trim() : BAD_REGEX_PARSE_RESULT; - const fileResults = regexResult(statLine, regex.TOTAL_FILES); + const fileResults = statLine.match(regex.TOTAL_FILES); stats.total_files_transferred = fileResults !== null ? fileResults[0].trim() : BAD_REGEX_PARSE_RESULT; - const skippedByteResults = regexResult(statLine, regex.SKIPPED_BYTES); + const skippedByteResults = statLine.match(regex.SKIPPED_BYTES); stats.total_bytes_skipped = skippedByteResults !== null ? skippedByteResults[0].trim() : BAD_REGEX_PARSE_RESULT; - const skippedFileResults = regexResult(statLine, regex.SKIPPED_FILES); + const skippedFileResults = statLine.match(regex.SKIPPED_FILES); stats.total_files_skipped = skippedFileResults !== null ? skippedFileResults[0].trim() diff --git a/src/helpers.js b/src/helpers.js index d03e40d..9cf927b 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -49,8 +49,6 @@ export const repoHasLfsObjectBin = repo => export const repoHasLfs = repo => repoHasLfsFilters(repo) .then(hasFilters => hasFilters || repoHasLfsObjectBin(repo)); -export const regexResult = (input, regularExpression) => input.match(regularExpression); - export const verifyOutput = (stats, raw) => { // Check to see if it was a permissions error const wasPermissionDenied = raw.trim().toLowerCase().match(regex.PERMISSION_DENIED); From e0fcf43930e02cc5d86ae0d07937668eb6e73d7c Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Mon, 21 Aug 2017 13:52:28 -0700 Subject: [PATCH 20/42] Add tests for project-wide helpers --- test/tests/helpers.spec.js | 102 +++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 test/tests/helpers.spec.js diff --git a/test/tests/helpers.spec.js b/test/tests/helpers.spec.js new file mode 100644 index 0000000..97a7d28 --- /dev/null +++ b/test/tests/helpers.spec.js @@ -0,0 +1,102 @@ +import { + expect +} from 'chai'; +import path from 'path'; + +import { + emptyRepoPath, + lfsTestRepoPath +} from '../constants'; +import { + fail +} from '../utils'; + +import * as helpers from '../../build/src/helpers'; +import track from '../../build/src/commands/track'; + +describe('helpers', () => { + beforeEach(function () { + const { + NodeGitLFS + } = this; + + return NodeGitLFS.Repository.open(lfsTestRepoPath) + .then((repo) => { + this.repo = repo; + }); + }); + + describe('getGitattributesPathFromRepo', () => { + beforeEach(function () { + const { + NodeGitLFS + } = this; + + return NodeGitLFS.Repository.open(lfsTestRepoPath) + .then((repo) => { + this.repo = repo; + }); + }); + + it("gets the location of a repository's `.gitattributes` file", function () { + const { + repo + } = this; + + expect(helpers.getGitattributesPathFromRepo(repo)) + .to.equal(path.join(lfsTestRepoPath, '.gitattributes')); + }); + }); + + describe('loadGitattributeFiltersFromRepo', () => { + it('reads globs from `.gitattributes`', function () { + const { + repo + } = this; + + return track(repo, ['"*.md"', 'test.txt']) + .then(() => helpers.loadGitattributeFiltersFromRepo(repo)) + .then((result) => { + expect(result).to.have.members(['*.md', 'test.txt']); + }); + }); + + it('errors if `.gitattributes` does not exist', function () { + const { + NodeGitLFS + } = this; + + return NodeGitLFS.Repository.open(emptyRepoPath) + .then(repo => helpers.loadGitattributeFiltersFromRepo(repo)) + .then(() => fail('Expected promise to fail!')) + .catch((err) => { + expect(err.message).to.equal('No .gitattributes found'); + }); + }); + }); + + describe('hasLfsFilters', () => { + it('returns `false` if the repo has no filters', function () { + const { + repo + } = this; + + return helpers.hasLfsFilters(repo) + .then((result) => { + expect(result).to.be.false; + }); + }); + + it('returns `true` if the repo has filters', function () { + const { + repo + } = this; + + return track(repo, ['test.txt']) + .then(() => helpers.hasLfsFilters(repo)) + .then((result) => { + expect(result).to.be.true; + }); + }); + }); +}); From e501cad975af496bc1811b87f97c1af5e5ef904a Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Tue, 22 Aug 2017 12:52:59 -0700 Subject: [PATCH 21/42] Finish 'clone' tests --- src/commands/clone.js | 2 +- test/tests/commands/clone.spec.js | 170 ++++++++++++++++++++++++++++-- 2 files changed, 165 insertions(+), 7 deletions(-) diff --git a/src/commands/clone.js b/src/commands/clone.js index d5f4492..113eeb8 100644 --- a/src/commands/clone.js +++ b/src/commands/clone.js @@ -71,7 +71,7 @@ function clone(url, cwd, options) { const args = branch ? `-b ${branch}` : ''; const response = generateResponse(); - return core.clone(`${url} ${args}`, { cwd }, callback) + return core.clone(`${url} ${args}`, { cwd, env }, callback) .then(({ stdout }) => { response.raw = stdout; response.clone = generateCloneStats(stdout); diff --git a/test/tests/commands/clone.spec.js b/test/tests/commands/clone.spec.js index 32674b0..49a1ed4 100644 --- a/test/tests/commands/clone.spec.js +++ b/test/tests/commands/clone.spec.js @@ -1,16 +1,174 @@ +import { + expect +} from 'chai'; +import fse from 'fs-extra'; import path from 'path'; -import { todo } from '../../utils'; +import sinon from 'sinon'; + +import { + lfsTestRepoUrl, + testReposPath +} from '../../constants'; +import { + fail +} from '../../utils'; + +import { + BAD_CORE_RESPONSE, + BAD_REGEX_PARSE_RESULT +} from '../../../build/src/constants'; +import { + core +} from '../../../build/src/commands/lfsCommands'; + +const tempRepoPath = path.join(testReposPath, 'nodegit-lfs-test-repo'); describe('Clone', () => { - it('should generate clone repsonse', function () { + beforeEach(function () { + this.sandbox = sinon.sandbox.create(); + + return fse.remove(tempRepoPath); + }); + + afterEach(function () { + const { + sandbox + } = this; + + sandbox.restore(); + }); + + it('should clone a repo', function () { + const { + NodeGitLFS + } = this; + + // We are testing the returned value in the specific branch test, because the test repo's + // `master` branch doesn't have LFS enabled by default + return NodeGitLFS.LFS.clone( + lfsTestRepoUrl, + testReposPath + ) + .then(() => NodeGitLFS.Repository.open(tempRepoPath)); + }); + + it('should clone a repo at a specific branch', function () { + const { + NodeGitLFS + } = this; + + return NodeGitLFS.LFS.clone( + lfsTestRepoUrl, + testReposPath, + { branch: 'with-files' } + ) + .then((result) => { + expect(result.clone).to.eql({ + total_bytes: '24 B', + total_bytes_cloned: '24 B', + total_bytes_skipped: BAD_REGEX_PARSE_RESULT, + total_files_cloned: '1', + total_files_skipped: BAD_REGEX_PARSE_RESULT + }); + }) + .then(() => NodeGitLFS.Repository.open(tempRepoPath)) + .then(repo => repo.getCurrentBranch()) + .then((branch) => { + expect(branch.shorthand()).to.equal('with-files'); + }); + }).timeout(10000); + + it('should allow the environment to be customized', function () { + const { + NodeGitLFS, + sandbox, + } = this; + + const cloneStub = sandbox.stub(core, 'clone').returns(Promise.resolve({})); + + NodeGitLFS.LFS.clone( + lfsTestRepoUrl, + testReposPath, + { + env: { + foo: 'bar' + } + } + ); + expect(cloneStub).to.have.been.calledWithMatch(`${lfsTestRepoUrl} `, { + cwd: testReposPath, + env: { + foo: 'bar' + } + }); + }); + + it('should pass a callback through into `spawn`', function () { + const { + NodeGitLFS, + sandbox + } = this; + + const callback = () => { }; + + const cloneStub = sandbox.stub(core, 'clone').returns(Promise.resolve({})); + + NodeGitLFS.LFS.clone(lfsTestRepoUrl, testReposPath, { callback }); + expect(cloneStub.firstCall.args[2]).to.equal(callback); + }); + + it('requires the repository URL to be passed in', function () { + const { + NodeGitLFS + } = this; + + try { + NodeGitLFS.LFS.clone( + null, + testReposPath + ); + + fail('This should throw an error!'); + } catch (e) { + expect(e.message).to.equal('A valid URL and working directory are required'); + } + }); + + it('requires the directory to clone into to be passed in', function () { const { NodeGitLFS } = this; - const emptyRepoPath = path.resolve(__dirname, '..', '..', 'repos', 'empty'); - const url = 'https://github.com/jgrosso/nodegit-lfs-test-repo'; + try { + NodeGitLFS.LFS.clone( + lfsTestRepoUrl, + null + ); + + fail('This should throw an error!'); + } catch (e) { + expect(e.message).to.equal('A valid URL and working directory are required'); + } + }); + + it('should return an appropriate result on error', function () { + const { + NodeGitLFS + } = this; - return NodeGitLFS.LFS.clone(url, emptyRepoPath, { branch: 'test', env: { GIT_SSL_NO_VERIFY: 1 } }) - .then(() => todo()); + return NodeGitLFS.LFS.clone( + 'invalid', + testReposPath + ) + .then((result) => { + expect(result.errno).to.equal(BAD_CORE_RESPONSE); + expect(result.stderr).to.equal( +`fatal: repository 'invalid' does not exist +Error(s) during clone: +git clone failed: exit status 128 +`, + ); + expect(result.success).to.be.false; + }); }); }); From 5285d8de4374b3137a8ea6eae0f786b06440bd73 Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Wed, 23 Aug 2017 08:38:05 -0700 Subject: [PATCH 22/42] Remove trailing commas --- .eslintrc | 2 +- src/commands/checkout.js | 2 +- src/commands/fetch.js | 4 ++-- src/commands/ls.js | 2 +- src/commands/pointer.js | 2 +- src/commands/pull.js | 2 +- src/commands/push.js | 4 ++-- src/commands/track.js | 2 +- src/commands/untrack.js | 2 +- src/commands/version.js | 2 +- src/constants.js | 2 +- src/index.js | 2 +- src/utils/generateResponse.js | 2 +- 13 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.eslintrc b/.eslintrc index fbbe2cd..6a2e614 100644 --- a/.eslintrc +++ b/.eslintrc @@ -10,7 +10,7 @@ ], "rules": { "chai-friendly/no-unused-expressions": 2, - "comma-dangle": 0, + "comma-dangle": ["error", "never"], "consistent-return": 0, "func-names": 0, "import/prefer-default-export": 0, diff --git a/src/commands/checkout.js b/src/commands/checkout.js index 878c5c5..eaeea25 100644 --- a/src/commands/checkout.js +++ b/src/commands/checkout.js @@ -3,7 +3,7 @@ import { core } from './lfsCommands'; import { regex, BAD_CORE_RESPONSE, - BAD_REGEX_PARSE_RESULT, + BAD_REGEX_PARSE_RESULT } from '../constants'; import generateResponse from '../utils/generateResponse'; diff --git a/src/commands/fetch.js b/src/commands/fetch.js index 0ebd738..bea7bbb 100644 --- a/src/commands/fetch.js +++ b/src/commands/fetch.js @@ -2,8 +2,8 @@ import R from 'ramda'; import { core } from './lfsCommands'; import { regex, - BAD_REGEX_PARSE_RESULT, BAD_CORE_RESPONSE, + BAD_REGEX_PARSE_RESULT } from '../constants'; import generateResponse from '../utils/generateResponse'; import { @@ -66,7 +66,7 @@ function fetch(repo, options) { const { remoteName, branchName, - callback, + callback } = (options || {}); if (remoteName) { diff --git a/src/commands/ls.js b/src/commands/ls.js index 3ae1107..e66ae0c 100644 --- a/src/commands/ls.js +++ b/src/commands/ls.js @@ -1,7 +1,7 @@ import R from 'ramda'; import { core } from './lfsCommands'; import { - BAD_CORE_RESPONSE, + BAD_CORE_RESPONSE } from '../constants'; import generateResponse from '../utils/generateResponse'; diff --git a/src/commands/pointer.js b/src/commands/pointer.js index 58b57ac..28849d9 100644 --- a/src/commands/pointer.js +++ b/src/commands/pointer.js @@ -1,6 +1,6 @@ import { core } from './lfsCommands'; import { - BAD_CORE_RESPONSE, + BAD_CORE_RESPONSE } from '../constants'; import generateResponse from '../utils/generateResponse'; diff --git a/src/commands/pull.js b/src/commands/pull.js index 277bbb2..697dd1c 100644 --- a/src/commands/pull.js +++ b/src/commands/pull.js @@ -66,7 +66,7 @@ function pull(repo, options) { const { remoteName, branchName, - callback, + callback } = (options || {}); if (remoteName) { diff --git a/src/commands/push.js b/src/commands/push.js index ce59848..6a3d6f3 100644 --- a/src/commands/push.js +++ b/src/commands/push.js @@ -22,7 +22,7 @@ const isValidLine = str => str !== ''; const generatePushStats = (raw) => { if (!raw || typeof raw !== 'string') { return { - error: 'invalid output', + error: 'invalid output' }; } const stats = {}; @@ -74,7 +74,7 @@ function push(repo, options) { const { remoteName, branchName, - callback, + callback } = (options || {}); let branch = branchName; diff --git a/src/commands/track.js b/src/commands/track.js index bc771ba..36ae9c3 100644 --- a/src/commands/track.js +++ b/src/commands/track.js @@ -3,7 +3,7 @@ import { core } from './lfsCommands'; import generateResponse from '../utils/generateResponse'; import { regex as Regex, - BAD_CORE_RESPONSE, + BAD_CORE_RESPONSE } from '../constants'; const isString = str => typeof str === 'string'; diff --git a/src/commands/untrack.js b/src/commands/untrack.js index 9db503c..b4b4f04 100644 --- a/src/commands/untrack.js +++ b/src/commands/untrack.js @@ -3,7 +3,7 @@ import { core } from './lfsCommands'; import generateResponse from '../utils/generateResponse'; import { regex as Regex, - BAD_CORE_RESPONSE, + BAD_CORE_RESPONSE } from '../constants'; const isString = str => typeof str === 'string'; diff --git a/src/commands/version.js b/src/commands/version.js index 08c32da..7d487d8 100644 --- a/src/commands/version.js +++ b/src/commands/version.js @@ -2,7 +2,7 @@ import { core } from './lfsCommands'; import { parseVersion } from '../utils/checkDependencies'; import { regex, - BAD_CORE_RESPONSE, + BAD_CORE_RESPONSE } from '../constants'; import generateResponse from '../utils/generateResponse'; diff --git a/src/constants.js b/src/constants.js index cdd2bd1..7d30db4 100644 --- a/src/constants.js +++ b/src/constants.js @@ -29,7 +29,7 @@ export const BAD_REGEX_PARSE_RESULT = '-2'; export const minimumVersions = { GIT: '1.8.5', - LFS: '2.0.0', + LFS: '2.0.0' }; // Copied from NodeGit for now... eventually we will find a way to change that diff --git a/src/index.js b/src/index.js index 2b00cfd..de19ca5 100644 --- a/src/index.js +++ b/src/index.js @@ -38,7 +38,7 @@ LFS.prototype = { push, version, unregister, - untrack, + untrack }; module.exports = (nodegit) => { diff --git a/src/utils/generateResponse.js b/src/utils/generateResponse.js index 0a4695a..5479ff0 100644 --- a/src/utils/generateResponse.js +++ b/src/utils/generateResponse.js @@ -4,7 +4,7 @@ const generateResponse = () => ({ success: true, errno: Error.CODE.OK, raw: '', - stderr: '', + stderr: '' }); export default generateResponse; From 068f2064caa9933890d44e15d631a3a5a83ef6a8 Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Thu, 24 Aug 2017 08:43:43 -0700 Subject: [PATCH 23/42] Add machinery to simulate a remote locally --- .gitignore | 2 + test/constants.js | 5 ++- test/runner.js | 61 +++++++++++++++++++++---------- test/server/initializeObjects.sh | 8 ++++ test/server/server.js | 31 +++++++++++++--- test/server/start.sh | 20 +++++----- test/tests/commands/clone.spec.js | 2 +- test/utils.js | 10 +++++ 8 files changed, 103 insertions(+), 36 deletions(-) create mode 100755 test/server/initializeObjects.sh diff --git a/.gitignore b/.gitignore index 991f839..2a454fb 100644 --- a/.gitignore +++ b/.gitignore @@ -39,5 +39,7 @@ node_modules # Generated test files test/repos test/server/lfs-test-server +test/server/local-repo +test/server/local-repo-cached \.DS_Store diff --git a/test/constants.js b/test/constants.js index 5cad4ef..4798f15 100644 --- a/test/constants.js +++ b/test/constants.js @@ -3,5 +3,6 @@ import path from 'path'; export const testReposPath = path.join(__dirname, 'repos'); export const emptyRepoPath = path.join(testReposPath, 'empty'); export const lfsTestRepoPath = path.join(testReposPath, 'lfs-test-repository'); - -export const lfsTestRepoUrl = 'https://github.com/jgrosso/nodegit-lfs-test-repo'; +export const lfsTestRepoUrl = 'https://github.com/jgrosso/nodegit-lfs-test-repo.git'; +export const lfsTestRemotePath = path.join(__dirname, 'server', 'local-repo'); +export const cachedLfsTestRemotePath = path.join(__dirname, 'server', 'local-repo-cached'); diff --git a/test/runner.js b/test/runner.js index fed9d77..bd4b2fa 100644 --- a/test/runner.js +++ b/test/runner.js @@ -8,14 +8,15 @@ import { core } from '../build/src/commands/lfsCommands'; import { + cachedLfsTestRemotePath, emptyRepoPath, lfsTestRepoPath, lfsTestRepoUrl, + lfsTestRemotePath, testReposPath } from './constants'; import LFS from '../build/src'; -import exec from '../build/src/utils/execHelper'; import * as testLFSServer from './server/server'; @@ -27,39 +28,61 @@ process.on('unhandledRejection', (err) => { chai.use(sinonChai); -before(function () { // eslint-disable-line prefer-arrow-callback - this.timeout(30000); +// We cache the test remote to avoid the overhead of re-cloning it before each test. +const cacheLfsTestRemote = () => + fse.remove(cachedLfsTestRemotePath) + .then(() => core.git(`clone ${lfsTestRepoUrl} ${cachedLfsTestRemotePath}`, { + env: { + GIT_SSL_NO_VERIFY: 1 + } + })); - this.NodeGitLFS = LFS(NodeGit); +// We have to re-copy the test remote before each test to avoid pollution in pull, fetch, etc. tests +const setupLfsTestRemote = () => + fse.remove(lfsTestRemotePath) + .then(() => fse.copy(cachedLfsTestRemotePath, lfsTestRemotePath)); - return testLFSServer.start() - .then(() => fse.remove(testReposPath)) - .then(() => fse.mkdir(testReposPath)) - .then(() => fse.mkdir(lfsTestRepoPath)) - .then(() => fse.mkdir(emptyRepoPath)) - .then(() => core.git(`init ${emptyRepoPath}`)) - .then(() => core.git(`clone ${lfsTestRepoUrl} ${lfsTestRepoPath}`, { +const setupLfsTestRepo = () => + fse.remove(lfsTestRepoPath) + .then(() => core.git(`clone ${lfsTestRemotePath} ${lfsTestRepoPath}`, { env: { GIT_SSL_NO_VERIFY: 1 } })) .then(() => fse.appendFile( - path.join(lfsTestRepoPath, '.git', 'config'), - `[http] + path.join(cachedLfsTestRemotePath, '.git', 'config'), +`[http] sslverify = false` )); + +const setupEmptyTestRepo = () => + fse.remove(emptyRepoPath) + .then(() => core.git(`init ${emptyRepoPath}`)); + +before(function () { // eslint-disable-line prefer-arrow-callback + this.timeout(30000); + + this.NodeGitLFS = LFS(NodeGit); + + return testLFSServer.start() + .then(() => fse.remove(testReposPath)) + .then(() => fse.mkdir(testReposPath)) + .then(() => cacheLfsTestRemote()); }); beforeEach(() => - exec('git clean -xdf && git reset --hard', { cwd: lfsTestRepoPath }) - .then(() => exec('git clean -xdff', { cwd: emptyRepoPath }))); + setupEmptyTestRepo() + .then(() => setupLfsTestRemote()) + .then(() => setupLfsTestRepo())); + +after(function () { + const { + NodeGitLFS + } = this; -after(() => { testLFSServer.stop(); -}); -afterEach(function () { - return this.NodeGitLFS.LFS.unregister() + return NodeGitLFS.LFS.unregister() .catch((error) => { // -3 implies LFS filter was not registered if (error.errno !== -3) { diff --git a/test/server/initializeObjects.sh b/test/server/initializeObjects.sh new file mode 100755 index 0000000..65f36f7 --- /dev/null +++ b/test/server/initializeObjects.sh @@ -0,0 +1,8 @@ +set -eu +set -o pipefail + +# Push objects to LFS server +git lfs track README.md +git add -A +git commit -m "Create objects to push" +git lfs push origin master diff --git a/test/server/server.js b/test/server/server.js index 895923e..583fa2d 100644 --- a/test/server/server.js +++ b/test/server/server.js @@ -3,6 +3,10 @@ import { spawn } from 'child_process'; +import { + spawnOnRemote +} from '../utils'; + let serverPid = null; const getWin32BashCommand = () => { @@ -19,11 +23,17 @@ const getWin32BashCommand = () => { return `"${shPath}" `; }; +export const populate = () => + spawnOnRemote('sh ../initializeObjects.sh'); + export const start = () => { if (serverPid) { throw new Error('LFS test server has already been started!'); } + let stderr = ''; + let stdout = ''; + return new Promise((resolve, reject) => { const cmdRunner = process.platform === 'win32' ? getWin32BashCommand() @@ -32,23 +42,34 @@ export const start = () => { cwd: __dirname, shell: true }); - server.stdout.on('data', (data) => { + server.stdout.on('data', (chunk) => { + const data = chunk.toString(); + + stdout += data; + // Store outputted server PID - const pid = data.toString().match(/pid=(\d+)/); + const pid = data.match(/pid=(\d+)/); if (pid) { serverPid = parseInt(pid[1], 10); return resolve(); } // Handle Go errors - const err = data.toString().match(/ err=(.*)/); + const err = data.match(/ err=(.*)/); if (err) { throw new Error(err[1]); } }); - server.stderr.on('data', (err) => { - throw new Error(err.toString()); + server.stderr.on('data', (chunk) => { + const data = chunk.toString(); + + stderr += data; }); + server.on('exit', code => ( + code === 0 + ? resolve() + : reject({ code, stderr, stdout }) + )); }); }; diff --git a/test/server/start.sh b/test/server/start.sh index 8755d7b..0722185 100755 --- a/test/server/start.sh +++ b/test/server/start.sh @@ -2,19 +2,21 @@ set -eu set -o pipefail # Download LFS test server -GOPATH=`pwd`/lfs-test-server go get github.com/github/lfs-test-server +GOPATH="$(pwd)/lfs-test-server" go get github.com/github/lfs-test-server # Configure LFS test server -LFS_LISTEN=tcp://:9001 -LFS_HOST=127.0.0.1:9001 -LFS_ADMINUSER=admin -LFS_ADMINPASS=admin -LFS_CERT=`pwd`/server.crt -LFS_KEY=`pwd`/server.key -LFS_SCHEME=https +LFS_LISTEN="tcp://:9001" +LFS_HOST="127.0.0.1:9001" +LFS_ADMINUSER="admin" +LFS_ADMINPASS="admin" +LFS_CERT="$(pwd)/server.crt" +LFS_KEY="$(pwd)/server.key" +LFS_SCHEME="https" export LFS_LISTEN LFS_HOST LFS_ADMINUSER LFS_ADMINPASS LFS_CERT LFS_KEY LFS_SCHEME # Run LFS test server -cd lfs-test-server # `cd` into the `lfs-test-server` directory so that server-created files don't pollute `test/server` +# We `cd` into the `lfs-test-server` directory so that server-created files don't pollute `test/server` +cd lfs-test-server ./bin/lfs-test-server& +cd .. echo "pid=$!" # Echo the server's PID so that it can be manually killed diff --git a/test/tests/commands/clone.spec.js b/test/tests/commands/clone.spec.js index 49a1ed4..9eb0c34 100644 --- a/test/tests/commands/clone.spec.js +++ b/test/tests/commands/clone.spec.js @@ -81,7 +81,7 @@ describe('Clone', () => { it('should allow the environment to be customized', function () { const { NodeGitLFS, - sandbox, + sandbox } = this; const cloneStub = sandbox.stub(core, 'clone').returns(Promise.resolve({})); diff --git a/test/utils.js b/test/utils.js index 6104dc2..92429b7 100644 --- a/test/utils.js +++ b/test/utils.js @@ -4,6 +4,10 @@ import { import crypto from 'crypto'; import fse from 'fs-extra'; +import { + lfsTestRemotePath +} from './constants'; + import spawn from '../build/src/utils/spawnHelper'; export const createDummyFile = (fileName, length) => { @@ -21,6 +25,12 @@ export const getFilePointer = (workdir, fileName) => spawn(`git show HEAD:${fileName}`, { cwd: workdir, env: { GIT_PAGER: 'cat' } }) .then(({ stdout }) => stdout.toString()); +export const spawnOnRemote = (command, opts) => + spawn(command, { + ...opts, + cwd: lfsTestRemotePath + }); + export const todo = () => { fail('TODO'); }; From fea3c933803bd5fd264420c768aa891c10ce96db Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Thu, 24 Aug 2017 09:33:34 -0700 Subject: [PATCH 24/42] Require `nodegit` 0.20.1 Tests rely on NodeGit calling the LFS filters when necessary, so we need to be using a version of NodeGit that supports this machinery in the first place. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 96e724c..88fdb50 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "nodegit-lfs", "version": "0.0.11", - "description": "A wrapper for NodeGit to facilitate LFS Support", + "description": "A wrapper for NodeGit to facilitate LFS support", "main": "build/src/index.js", "scripts": { "build": "yarn eslint && yarn compile", From 3d0da1ba14818094ed12d02a091a6765b2226b96 Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Thu, 24 Aug 2017 10:23:56 -0700 Subject: [PATCH 25/42] Automatically register and unregister the LFS filters before and after each test --- test/runner.js | 22 ++++++++++++++++++---- test/tests/callbacks/apply.spec.js | 3 +-- test/tests/callbacks/check.spec.js | 3 +-- test/tests/initialize.spec.js | 2 +- test/tests/register.spec.js | 10 ++++++++++ test/tests/unregister.spec.js | 3 ++- 6 files changed, 33 insertions(+), 10 deletions(-) diff --git a/test/runner.js b/test/runner.js index bd4b2fa..3fb47b9 100644 --- a/test/runner.js +++ b/test/runner.js @@ -22,7 +22,7 @@ import * as testLFSServer from './server/server'; // http://eng.wealthfront.com/2016/11/03/handling-unhandledrejections-in-node-and-the-browser/ process.on('unhandledRejection', (err) => { - console.error(err); // eslint-disable-line no-console + console.error('CAUGHT ERROR:', err); // eslint-disable-line no-console process.exit(1); }); @@ -70,10 +70,16 @@ before(function () { // eslint-disable-line prefer-arrow-callback .then(() => cacheLfsTestRemote()); }); -beforeEach(() => - setupEmptyTestRepo() +beforeEach(function () { + const { + NodeGitLFS + } = this; + + return NodeGitLFS.LFS.register() + .then(() => setupEmptyTestRepo()) .then(() => setupLfsTestRemote()) - .then(() => setupLfsTestRepo())); + .then(() => setupLfsTestRepo()); +}); after(function () { const { @@ -90,3 +96,11 @@ after(function () { } }); }); + +afterEach(function () { + const { + NodeGitLFS + } = this; + + return NodeGitLFS.LFS.unregister(); +}); diff --git a/test/tests/callbacks/apply.spec.js b/test/tests/callbacks/apply.spec.js index 6f2324b..4966b60 100644 --- a/test/tests/callbacks/apply.spec.js +++ b/test/tests/callbacks/apply.spec.js @@ -88,8 +88,7 @@ describe('apply', () => { expect(pointer).to.have.string(`size ${testFileSize}`); }); - return NodeGitLFS.LFS.register() - .then(() => NodeGitLFS.Repository.open(lfsTestRepoPath)) + return NodeGitLFS.Repository.open(lfsTestRepoPath) .then((repo) => { this.repo = repo; }); diff --git a/test/tests/callbacks/check.spec.js b/test/tests/callbacks/check.spec.js index 49b5a58..33de172 100644 --- a/test/tests/callbacks/check.spec.js +++ b/test/tests/callbacks/check.spec.js @@ -23,8 +23,7 @@ describe('check', () => { repo: () => this.repo }); - return NodeGitLFS.LFS.register() - .then(() => NodeGitLFS.Repository.open(lfsTestRepoPath)) + return NodeGitLFS.Repository.open(lfsTestRepoPath) .then((repo) => { this.repo = repo; }); diff --git a/test/tests/initialize.spec.js b/test/tests/initialize.spec.js index b82414f..080f857 100644 --- a/test/tests/initialize.spec.js +++ b/test/tests/initialize.spec.js @@ -3,7 +3,7 @@ import fs from 'fs'; import { expect } from 'chai'; describe('Initialize', () => { - it('initialize is a promise', () => { + it('initialize is a promise', function () { const { NodeGitLFS } = this; diff --git a/test/tests/register.spec.js b/test/tests/register.spec.js index 4507608..9a1a2a8 100644 --- a/test/tests/register.spec.js +++ b/test/tests/register.spec.js @@ -1,6 +1,16 @@ import { expect } from 'chai'; describe('Register', () => { + beforeEach(function () { + const { + NodeGitLFS + } = this; + + // Undo the global `beforeEach`'s registration of the LFS filters + // so these tests can re-register them + return NodeGitLFS.LFS.unregister(); + }); + it('has register callback', function () { const { NodeGitLFS diff --git a/test/tests/unregister.spec.js b/test/tests/unregister.spec.js index 6f4bf9a..2a01da4 100644 --- a/test/tests/unregister.spec.js +++ b/test/tests/unregister.spec.js @@ -3,11 +3,12 @@ import { } from 'chai'; describe('Unregister', () => { - beforeEach(function () { + afterEach(function () { const { NodeGitLFS } = this; + // Prepare for the global `afterEach`'s unregistration of the LFS filters by re-registering them return NodeGitLFS.LFS.register(); }); From 7338e57bd04ddbca78ce188d3d3d7aa535784a00 Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Thu, 24 Aug 2017 10:32:53 -0700 Subject: [PATCH 26/42] Fix clone specs to use new simulated remote machinery --- README.md | 7 ++++- test/server/initializeObjects.sh | 4 ++- test/server/server.js | 17 +++++++++++- test/tests/commands/clone.spec.js | 43 +++++++++++++++++++++---------- 4 files changed, 55 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index f274c91..c3eb18a 100644 --- a/README.md +++ b/README.md @@ -46,4 +46,9 @@ Once cloned: ``` cd nodegit-lfs yarn -``` \ No newline at end of file +``` + +## Tests + +**Tests are still a Work In Progress.** +The tests rely on `mocha`, `chai`, `sinon`, and `sinon-chai`, and are currently a mix of system and unit tests. diff --git a/test/server/initializeObjects.sh b/test/server/initializeObjects.sh index 65f36f7..ee1c187 100755 --- a/test/server/initializeObjects.sh +++ b/test/server/initializeObjects.sh @@ -1,8 +1,10 @@ set -eu set -o pipefail +current_branch="$(git rev-parse --abbrev-ref HEAD)" + # Push objects to LFS server git lfs track README.md git add -A git commit -m "Create objects to push" -git lfs push origin master +GIT_SSL_NO_VERIFY=1 git lfs push origin "$current_branch" diff --git a/test/server/server.js b/test/server/server.js index 583fa2d..dd8b1f1 100644 --- a/test/server/server.js +++ b/test/server/server.js @@ -23,7 +23,7 @@ const getWin32BashCommand = () => { return `"${shPath}" `; }; -export const populate = () => +export const populateCurrentBranch = () => spawnOnRemote('sh ../initializeObjects.sh'); export const start = () => { @@ -80,3 +80,18 @@ export const stop = () => { process.kill(serverPid, 'SIGKILL'); }; + +export const withRemoteBranch = (branchName, fn) => { + let result; + + return spawnOnRemote(`git checkout -b ${branchName}`) + .then(() => fn()) + .then((_result) => { + result = _result; + return spawnOnRemote('git checkout master'); + }) + .then(() => result); +}; + +export const populateRemoteBranch = branchName => + withRemoteBranch(branchName, populateCurrentBranch); diff --git a/test/tests/commands/clone.spec.js b/test/tests/commands/clone.spec.js index 9eb0c34..fe0ec89 100644 --- a/test/tests/commands/clone.spec.js +++ b/test/tests/commands/clone.spec.js @@ -6,9 +6,12 @@ import path from 'path'; import sinon from 'sinon'; import { - lfsTestRepoUrl, + lfsTestRemotePath, testReposPath } from '../../constants'; +import { + populateRemoteBranch +} from '../../server/server'; import { fail } from '../../utils'; @@ -46,8 +49,13 @@ describe('Clone', () => { // We are testing the returned value in the specific branch test, because the test repo's // `master` branch doesn't have LFS enabled by default return NodeGitLFS.LFS.clone( - lfsTestRepoUrl, - testReposPath + `${lfsTestRemotePath} ${tempRepoPath}`, + testReposPath, + { + env: { + GIT_SSL_NO_VERIFY: 1 + } + } ) .then(() => NodeGitLFS.Repository.open(tempRepoPath)); }); @@ -57,11 +65,20 @@ describe('Clone', () => { NodeGitLFS } = this; - return NodeGitLFS.LFS.clone( - lfsTestRepoUrl, - testReposPath, - { branch: 'with-files' } - ) + const branchName = 'other-branch'; + + return populateRemoteBranch(branchName) + .then(() => NodeGitLFS.LFS.clone( + // https://github.com/git-lfs/git-lfs/issues/2523 + `${lfsTestRemotePath} ${tempRepoPath}`, + testReposPath, + { + branch: branchName, + env: { + GIT_SSL_NO_VERIFY: 1 + } + } + )) .then((result) => { expect(result.clone).to.eql({ total_bytes: '24 B', @@ -74,7 +91,7 @@ describe('Clone', () => { .then(() => NodeGitLFS.Repository.open(tempRepoPath)) .then(repo => repo.getCurrentBranch()) .then((branch) => { - expect(branch.shorthand()).to.equal('with-files'); + expect(branch.shorthand()).to.equal(branchName); }); }).timeout(10000); @@ -87,7 +104,7 @@ describe('Clone', () => { const cloneStub = sandbox.stub(core, 'clone').returns(Promise.resolve({})); NodeGitLFS.LFS.clone( - lfsTestRepoUrl, + lfsTestRemotePath, testReposPath, { env: { @@ -95,7 +112,7 @@ describe('Clone', () => { } } ); - expect(cloneStub).to.have.been.calledWithMatch(`${lfsTestRepoUrl} `, { + expect(cloneStub).to.have.been.calledWithMatch(`${lfsTestRemotePath} `, { cwd: testReposPath, env: { foo: 'bar' @@ -113,7 +130,7 @@ describe('Clone', () => { const cloneStub = sandbox.stub(core, 'clone').returns(Promise.resolve({})); - NodeGitLFS.LFS.clone(lfsTestRepoUrl, testReposPath, { callback }); + NodeGitLFS.LFS.clone(lfsTestRemotePath, testReposPath, { callback }); expect(cloneStub.firstCall.args[2]).to.equal(callback); }); @@ -141,7 +158,7 @@ describe('Clone', () => { try { NodeGitLFS.LFS.clone( - lfsTestRepoUrl, + lfsTestRemotePath, null ); From 5ed34e51603f937de077d2f2dbc0a37d79886c21 Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Thu, 24 Aug 2017 15:05:33 -0700 Subject: [PATCH 27/42] Remove trailing commas (post-rebase) --- src/commands/clone.js | 2 +- src/commands/lfsCommands.js | 2 +- src/commands/pull.js | 2 +- src/commands/push.js | 2 +- src/constants.js | 2 +- src/register.js | 2 +- src/utils/spawnHelper.js | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/commands/clone.js b/src/commands/clone.js index 113eeb8..72fb81b 100644 --- a/src/commands/clone.js +++ b/src/commands/clone.js @@ -2,7 +2,7 @@ import R from 'ramda'; import { core } from './lfsCommands'; import { regex, - BAD_REGEX_PARSE_RESULT, + BAD_REGEX_PARSE_RESULT } from '../constants'; import generateResponse from '../utils/generateResponse'; import { diff --git a/src/commands/lfsCommands.js b/src/commands/lfsCommands.js index 0f0b7a6..21ab42a 100644 --- a/src/commands/lfsCommands.js +++ b/src/commands/lfsCommands.js @@ -18,5 +18,5 @@ export const core = { track: (args = '', options) => exec(`git lfs track ${args}`, null, options), untrack: (args = '', options) => exec(`git lfs untrack ${args}`, null, options), update: (args = '', options) => exec(`git lfs update ${args}`, null, options), - version: options => exec('git lfs version', null, options), + version: options => exec('git lfs version', null, options) }; diff --git a/src/commands/pull.js b/src/commands/pull.js index 697dd1c..b0c8350 100644 --- a/src/commands/pull.js +++ b/src/commands/pull.js @@ -2,8 +2,8 @@ import R from 'ramda'; import { core } from './lfsCommands'; import { regex, - BAD_REGEX_PARSE_RESULT, BAD_CORE_RESPONSE, + BAD_REGEX_PARSE_RESULT } from '../constants'; import generateResponse from '../utils/generateResponse'; import { diff --git a/src/commands/push.js b/src/commands/push.js index 6a3d6f3..ac42012 100644 --- a/src/commands/push.js +++ b/src/commands/push.js @@ -2,7 +2,7 @@ import R from 'ramda'; import { core } from './lfsCommands'; import { regex, - BAD_REGEX_PARSE_RESULT, + BAD_REGEX_PARSE_RESULT } from '../constants'; import generateResponse from '../utils/generateResponse'; import { diff --git a/src/constants.js b/src/constants.js index 7d30db4..688557d 100644 --- a/src/constants.js +++ b/src/constants.js @@ -36,6 +36,6 @@ export const minimumVersions = { export const Error = { CODE: { OK: 0, - PASSTHROUGH: -30, + PASSTHROUGH: -30 } }; diff --git a/src/register.js b/src/register.js index c59ca07..588b2bf 100644 --- a/src/register.js +++ b/src/register.js @@ -12,7 +12,7 @@ function register(credentialsCallback) { apply: buildApply(credentialsCallback), check, initialize, - attribute: 'filter=lfs', + attribute: 'filter=lfs' }; return this.NodeGit.FilterRegistry.register(LFS_FILTER_NAME, filter, 0); diff --git a/src/utils/spawnHelper.js b/src/utils/spawnHelper.js index cbafd7b..cd7ae49 100644 --- a/src/utils/spawnHelper.js +++ b/src/utils/spawnHelper.js @@ -145,7 +145,7 @@ export const winSpawn = (command, input, opts) => new Promise( const closeOrExit = (code = 0) => resolve({ code, - stdout: Buffer.concat(bufferList), + stdout: Buffer.concat(bufferList) }); spawnedProcess.on('close', closeOrExit); From 2652ae16269163c26d2bced1035634946a22ea7e Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Thu, 24 Aug 2017 15:15:09 -0700 Subject: [PATCH 28/42] Remove unnecessary variable assignments (post-rebase) --- src/commands/checkout.js | 2 +- src/commands/fetch.js | 2 +- src/commands/pull.js | 2 +- src/commands/push.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/commands/checkout.js b/src/commands/checkout.js index eaeea25..ed1f506 100644 --- a/src/commands/checkout.js +++ b/src/commands/checkout.js @@ -63,7 +63,7 @@ const generateCheckoutStats = (raw) => { function checkout(repo, callback) { const response = generateResponse(); - return core.checkout('', { cwd: repoPath }, callback) + return core.checkout('', { cwd: repo.workdir() }, callback) .then(({ stdout }) => { response.raw = stdout; response.checkout = generateCheckoutStats(stdout); diff --git a/src/commands/fetch.js b/src/commands/fetch.js index bea7bbb..7954353 100644 --- a/src/commands/fetch.js +++ b/src/commands/fetch.js @@ -78,7 +78,7 @@ function fetch(repo, options) { } const argsString = R.join(' ', args); - return core.fetch(argsString, { cwd: repoPath, shell: true }, callback) + return core.fetch(argsString, { cwd: repo.workdir(), shell: true }, callback) .then(({ stdout }) => { response.raw = stdout; response.fetch = generateFetchStats(stdout); diff --git a/src/commands/pull.js b/src/commands/pull.js index b0c8350..230f718 100644 --- a/src/commands/pull.js +++ b/src/commands/pull.js @@ -77,7 +77,7 @@ function pull(repo, options) { } const argsString = R.join(' ', args); - return core.pull(argsString, { cwd: repoPath, shell: true }, callback) + return core.pull(argsString, { cwd: repo.workdir(), shell: true }, callback) .then(({ stdout }) => { response.raw = stdout; response.pull = generatePullStats(stdout); diff --git a/src/commands/push.js b/src/commands/push.js index ac42012..f54bb05 100644 --- a/src/commands/push.js +++ b/src/commands/push.js @@ -102,7 +102,7 @@ function push(repo, options) { } return getRemoteAndBranchPromise - .then(() => core.push(`${remote} ${branch}`, { cwd: repoPath }, callback)) + .then(() => core.push(`${remote} ${branch}`, { cwd: repo.path() }, callback)) .then(({ stdout }) => { response.raw = stdout; response.push = generatePushStats(stdout); From d375041fa3dd47868bd787e2b6cfaea341a83700 Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Fri, 25 Aug 2017 08:48:04 -0700 Subject: [PATCH 29/42] Allow `spawnHelper` to have the created process' `env` overwritten --- src/utils/spawnHelper.js | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/utils/spawnHelper.js b/src/utils/spawnHelper.js index cd7ae49..3f0330e 100644 --- a/src/utils/spawnHelper.js +++ b/src/utils/spawnHelper.js @@ -97,14 +97,17 @@ const buildSocket = (size, closeProcess, socketName, mainResolve, mainReject) => socketServer.on('close', closed); }); -export const spawnShell = (command, opts, size, callback) => new Promise( +export const spawnShell = (command, opts = {}, size, callback) => new Promise( (resolve, reject) => { let spawnedProcess; const destroyProcess = () => spawnedProcess.destroy(); return buildSocketPath() .then(socket => buildSocket(size, destroyProcess, socket, resolve, reject)) .then((socketName) => { - const options = R.mergeDeepRight(opts, { env: process.env, encoding: null }); + const options = R.mergeDeepRight( + { env: process.env }, + R.mergeDeepRight(opts, { encoding: null }) + ); spawnedProcess = pty.spawn(defaultShell, [], options); @@ -128,9 +131,12 @@ export const spawnShell = (command, opts, size, callback) => new Promise( .catch(reject); }); -export const winSpawn = (command, input, opts) => new Promise( +export const winSpawn = (command, input, opts = {}) => new Promise( (resolve, reject) => { - const options = R.mergeDeepRight(opts, { env: process.env, shell: true }); + const options = R.mergeDeepRight( + { env: process.env }, + R.mergeDeepRight(opts, { shell: true }) + ); const argList = command.trim().split(' '); const cmd = argList.shift(); @@ -159,9 +165,9 @@ export const winSpawn = (command, input, opts) => new Promise( } ); -const spawn = (command, opts, callback) => new Promise( +const spawn = (command, opts = {}, callback) => new Promise( (resolve, reject) => { - const options = R.mergeDeepRight(opts, { env: process.env }); + const options = R.mergeDeepRight({ env: process.env }, opts); const argList = command.trim().split(' '); const cmd = argList.shift() + (IS_WINDOWS ? '.exe' : ''); From b7d61cee09d8d36c6a7f7b8cf3f14c0c97c00ede Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Fri, 25 Aug 2017 14:17:36 -0700 Subject: [PATCH 30/42] The `spawn` helper should reject if a non-0 exit code is returned --- src/helpers.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/helpers.js b/src/helpers.js index 9cf927b..2c4870f 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -74,14 +74,14 @@ export const verifyOutput = (stats, raw) => { } }; -export const errorCatchHandler = response => (err) => { +export const errorCatchHandler = response => (code) => { // This is a manually detected error we get from LFS - if (err.errno === BAD_CORE_RESPONSE) { + if (code === BAD_CORE_RESPONSE) { response.stderr = response.raw; response.errno = BAD_CORE_RESPONSE; response.success = false; return response; } - throw err; + throw code; }; From bb30f6f14a67273ab76cafc0e11b9cadf175cb70 Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Fri, 25 Aug 2017 14:26:33 -0700 Subject: [PATCH 31/42] Use pre-defined `*RepoPath` constants in tests --- test/tests/commands/ls.spec.js | 11 +++++++---- test/tests/commands/pointer.spec.js | 11 ++++++++--- test/tests/commands/prune.spec.js | 11 +++++++---- test/tests/commands/push.spec.js | 7 +++++-- test/tests/commands/track.spec.js | 11 +++++++---- test/tests/commands/untrack.spec.js | 11 +++++++---- test/tests/commands/version.spec.js | 12 ++++++++---- test/tests/initialize.spec.js | 15 +++++++++------ 8 files changed, 58 insertions(+), 31 deletions(-) diff --git a/test/tests/commands/ls.spec.js b/test/tests/commands/ls.spec.js index b737e88..bb7468a 100644 --- a/test/tests/commands/ls.spec.js +++ b/test/tests/commands/ls.spec.js @@ -1,5 +1,10 @@ -import path from 'path'; -import { todo } from '../../utils'; +import { + lfsTestRepoPath +} from '../../constants'; +import { + todo +} from '../../utils'; + import ls from '../../../build/src/commands/ls'; describe('ls-files', () => { @@ -8,8 +13,6 @@ describe('ls-files', () => { NodeGitLFS } = this; - const lfsTestRepoPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); - return NodeGitLFS.Repository.open(lfsTestRepoPath) .then(repo => ls(repo, { long: true })) .then(() => todo()); diff --git a/test/tests/commands/pointer.spec.js b/test/tests/commands/pointer.spec.js index ff28be2..33aab2e 100644 --- a/test/tests/commands/pointer.spec.js +++ b/test/tests/commands/pointer.spec.js @@ -1,5 +1,12 @@ import path from 'path'; -import { todo } from '../../utils'; + +import { + lfsTestRepoPath +} from '../../constants'; +import { + todo +} from '../../utils'; + import pointer from '../../../build/src/commands/pointer'; describe('Pointer', () => { @@ -8,8 +15,6 @@ describe('Pointer', () => { NodeGitLFS } = this; - const lfsTestRepoPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); - const packageJson = path.join(lfsTestRepoPath, 'package.json'); return NodeGitLFS.Repository.open(lfsTestRepoPath) diff --git a/test/tests/commands/prune.spec.js b/test/tests/commands/prune.spec.js index e67b086..4652e4b 100644 --- a/test/tests/commands/prune.spec.js +++ b/test/tests/commands/prune.spec.js @@ -1,5 +1,10 @@ -import path from 'path'; -import { todo } from '../../utils'; +import { + lfsTestRepoPath +} from '../../constants'; +import { + todo +} from '../../utils'; + import prune from '../../../build/src/commands/prune'; describe('Prune', () => { @@ -8,8 +13,6 @@ describe('Prune', () => { NodeGitLFS } = this; - const lfsTestRepoPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); - return NodeGitLFS.Repository.open(lfsTestRepoPath) .then(repo => prune(repo)) .then(() => todo()); diff --git a/test/tests/commands/push.spec.js b/test/tests/commands/push.spec.js index bbb3922..5bf2ea6 100644 --- a/test/tests/commands/push.spec.js +++ b/test/tests/commands/push.spec.js @@ -1,8 +1,13 @@ import path from 'path'; + +import { + lfsTestRepoPath +} from '../../constants'; import { createDummyFile, todo } from '../../utils'; + import exec from '../../../build/src/utils/execHelper'; describe('Push', () => { @@ -11,8 +16,6 @@ describe('Push', () => { NodeGitLFS } = this; - const lfsTestRepoPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); - return createDummyFile(path.join(lfsTestRepoPath, 'test_file.txt'), 20) .then(() => exec('git add test_file.txt', { cwd: lfsTestRepoPath })) .then(() => exec('git commit -m "LFS: push unit test"', { cwd: lfsTestRepoPath })) diff --git a/test/tests/commands/track.spec.js b/test/tests/commands/track.spec.js index ed6bff3..1196666 100644 --- a/test/tests/commands/track.spec.js +++ b/test/tests/commands/track.spec.js @@ -1,5 +1,10 @@ -import path from 'path'; -import { todo } from '../../utils'; +import { + lfsTestRepoPath +} from '../../constants'; +import { + todo +} from '../../utils'; + import track from '../../../build/src/commands/track'; describe('Track', () => { @@ -8,8 +13,6 @@ describe('Track', () => { NodeGitLFS } = this; - const lfsTestRepoPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); - return NodeGitLFS.Repository.open(lfsTestRepoPath) .then(repo => track(repo, ['*.png', '*.dmg'])) .then(() => todo()); diff --git a/test/tests/commands/untrack.spec.js b/test/tests/commands/untrack.spec.js index 13a17e6..5253806 100644 --- a/test/tests/commands/untrack.spec.js +++ b/test/tests/commands/untrack.spec.js @@ -1,5 +1,10 @@ -import path from 'path'; -import { todo } from '../../utils'; +import { + lfsTestRepoPath +} from '../../constants'; +import { + todo +} from '../../utils'; + import track from '../../../build/src/commands/track'; import untrack from '../../../build/src/commands/untrack'; @@ -9,8 +14,6 @@ describe('Untrack', () => { NodeGitLFS } = this; - const lfsTestRepoPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); - let repository; return NodeGitLFS.Repository.open(lfsTestRepoPath) diff --git a/test/tests/commands/version.spec.js b/test/tests/commands/version.spec.js index e6ecf29..1d25f27 100644 --- a/test/tests/commands/version.spec.js +++ b/test/tests/commands/version.spec.js @@ -1,5 +1,11 @@ -import path from 'path'; -import { todo } from '../../utils'; +import { + lfsTestRepoPath +} from '../../constants'; + +import { + todo +} from '../../utils'; + import version from '../../../build/src/commands/version'; describe('Version', () => { @@ -8,8 +14,6 @@ describe('Version', () => { NodeGitLFS } = this; - const lfsTestRepoPath = path.resolve(__dirname, '..', '..', 'repos', 'lfs-test-repository'); - return NodeGitLFS.Repository.open(lfsTestRepoPath) .then(repo => version(repo)) .then(() => todo()); diff --git a/test/tests/initialize.spec.js b/test/tests/initialize.spec.js index 080f857..3613ff0 100644 --- a/test/tests/initialize.spec.js +++ b/test/tests/initialize.spec.js @@ -1,6 +1,13 @@ -import path from 'path'; +import { + expect +} from 'chai'; import fs from 'fs'; -import { expect } from 'chai'; +import path from 'path'; + +import { + emptyRepoPath, + lfsTestRepoPath +} from '../constants'; describe('Initialize', () => { it('initialize is a promise', function () { @@ -8,8 +15,6 @@ describe('Initialize', () => { NodeGitLFS } = this; - const lfsTestRepoPath = path.resolve(__dirname, '..', 'repos', 'lfs-test-repository'); - return NodeGitLFS.Repository.open(lfsTestRepoPath) .then((repo) => { const init = NodeGitLFS.LFS.initialize(repo); @@ -22,8 +27,6 @@ describe('Initialize', () => { NodeGitLFS } = this; - const emptyRepoPath = path.resolve(__dirname, '..', 'repos', 'empty'); - expect(fs.existsSync(path.join(emptyRepoPath, '.gitattributes'))).to.be.false; return NodeGitLFS.Repository.open(emptyRepoPath) From 178fb61d106fd36f12d18ea461c44b733cb77214 Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Fri, 25 Aug 2017 15:05:21 -0700 Subject: [PATCH 32/42] Fix segfaults and such (and broken tests) --- test/tests/callbacks/apply.spec.js | 4 +-- test/tests/callbacks/check.spec.js | 2 +- test/tests/initialize.spec.js | 5 +-- test/tests/utils/spawnHelper.spec.js | 48 ---------------------------- 4 files changed, 4 insertions(+), 55 deletions(-) diff --git a/test/tests/callbacks/apply.spec.js b/test/tests/callbacks/apply.spec.js index 4966b60..aacdf95 100644 --- a/test/tests/callbacks/apply.spec.js +++ b/test/tests/callbacks/apply.spec.js @@ -32,7 +32,7 @@ describe('apply', () => { NodeGitLFS } = this; - const testFileSize = 20; + const testFileSize = 2000000; this.testFileName = 'bigFileTest.md'; this.commitFile = (repo, fileName, commitMessage) => { @@ -119,5 +119,5 @@ describe('apply', () => { checkoutStrategy: NodeGitLFS.Checkout.STRATEGY.FORCE })) .then(() => verifyTestFileTracked()); - }); + }).timeout(10000); }); diff --git a/test/tests/callbacks/check.spec.js b/test/tests/callbacks/check.spec.js index 33de172..73e5f6f 100644 --- a/test/tests/callbacks/check.spec.js +++ b/test/tests/callbacks/check.spec.js @@ -10,7 +10,7 @@ import { } from '../../constants'; import track from '../../../build/src/commands/track'; -import { check as checkCallback } from '../../../build/src/callbacks/check'; +import checkCallback from '../../../build/src/callbacks/check'; describe('check', () => { beforeEach(function () { diff --git a/test/tests/initialize.spec.js b/test/tests/initialize.spec.js index 3613ff0..c0f10c5 100644 --- a/test/tests/initialize.spec.js +++ b/test/tests/initialize.spec.js @@ -16,10 +16,7 @@ describe('Initialize', () => { } = this; return NodeGitLFS.Repository.open(lfsTestRepoPath) - .then((repo) => { - const init = NodeGitLFS.LFS.initialize(repo); - expect(init).to.be.a('promise'); - }); + .then(repo => NodeGitLFS.LFS.initialize(repo)); }); it('creates .gitattributes for empty repo', function () { diff --git a/test/tests/utils/spawnHelper.spec.js b/test/tests/utils/spawnHelper.spec.js index 64808da..7a1bbd7 100644 --- a/test/tests/utils/spawnHelper.spec.js +++ b/test/tests/utils/spawnHelper.spec.js @@ -39,54 +39,6 @@ describe('spawn', () => { sandbox.restore(); }); - if (process.platform === 'win32') { - it('correctly overrides `detached` on Windows', function () { - const { - spawnStub - } = this; - - spawn('command', { detached: true, foo: 'bar' }); - expect(spawnStub).to.have.been.calledWithMatch('command', [], { - detached: false, - foo: 'bar', - env: process.env, - shell: true - }); - }); - } - - if (process.platform === 'darwin') { - it('correctly overrides `detached` on macOS', function () { - const { - spawnStub - } = this; - - spawn('command', { detached: true, foo: 'bar' }); - expect(spawnStub).to.have.been.calledWithMatch('command', [], { - detached: false, - foo: 'bar', - env: process.env, - shell: true - }); - }); - } - - if (process.platform === 'linux') { - it('correctly overrides `detached` on Linux', function () { - const { - spawnStub - } = this; - - spawn('command', { detached: false, foo: 'bar' }); - expect(spawnStub).to.have.been.calledWithMatch('command', [], { - detached: true, - foo: 'bar', - env: process.env, - shell: true - }); - }); - } - it("merges the calling process' env into the provided env", function () { const { sandbox, From 68e9f1171f7dded001998363c95c107b92788ae3 Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Tue, 29 Aug 2017 12:05:19 -0700 Subject: [PATCH 33/42] Add spec stubs [WIP] --- src/commands/push.js | 7 - src/index.js | 5 +- src/utils/spawnHelper.js | 27 +- ...initialize.check.js => initialize.spec.js} | 0 test/tests/commands/checkout.spec.js | 9 + test/tests/commands/clone.spec.js | 25 +- test/tests/commands/lfsCommands.spec.js | 39 +++ test/tests/commands/ls.spec.js | 17 +- test/tests/commands/pointer.spec.js | 19 +- test/tests/commands/prune.spec.js | 15 +- test/tests/commands/push.spec.js | 23 +- test/tests/commands/track.spec.js | 17 +- test/tests/commands/untrack.spec.js | 22 +- test/tests/constants.spec.js | 27 ++ test/tests/helpers.spec.js | 2 +- test/tests/index.spec.js | 87 ++++-- test/tests/initialize.spec.js | 34 +- test/tests/utils/execHelper.spec.js | 23 +- test/tests/utils/spawnHelper.spec.js | 295 ++++++------------ 19 files changed, 304 insertions(+), 389 deletions(-) rename test/tests/callbacks/{initialize.check.js => initialize.spec.js} (100%) create mode 100644 test/tests/commands/checkout.spec.js create mode 100644 test/tests/commands/lfsCommands.spec.js create mode 100644 test/tests/constants.spec.js diff --git a/src/commands/push.js b/src/commands/push.js index f54bb05..e3b75ce 100644 --- a/src/commands/push.js +++ b/src/commands/push.js @@ -10,13 +10,6 @@ import { verifyOutput } from '../helpers'; -/** - * Note to future maintainers, I do not like this; at all. But at the moment this is the - * best we got, inorder to parse the result from git core. Any slight change to the LFS output - * in subsequent versions of CORE for LFS, will surely break this. Until we migrate off - * git core dependency, we will have to regex the output. Godspeed. - */ - const isValidLine = str => str !== ''; const generatePushStats = (raw) => { diff --git a/src/index.js b/src/index.js index de19ca5..13897b4 100644 --- a/src/index.js +++ b/src/index.js @@ -2,7 +2,10 @@ import initialize from './initialize'; import register from './register'; import unregister from './unregister'; import { core } from './commands/lfsCommands'; -import { loadGitattributeFiltersFromRepo, repoHasLfs } from './helpers'; +import { + loadGitattributeFiltersFromRepo, + repoHasLfs +} from './helpers'; import checkout from './commands/checkout'; import push from './commands/push'; import track from './commands/track'; diff --git a/src/utils/spawnHelper.js b/src/utils/spawnHelper.js index 3f0330e..c0aaf80 100644 --- a/src/utils/spawnHelper.js +++ b/src/utils/spawnHelper.js @@ -24,10 +24,27 @@ const buildSocketPath = () => tmp.dir() return path.join(prefix, cleanedPath, 'echo.sock'); }); +/** + * Flow type definition: + * + * type BuildCredentialsCallbackProcess = + * ( + * spawnedProcess: ChildProcess, + * callback: ( + * passwordOnly: boolean, + * callback: (usernamePrompt: boolean) => + * (username: string, password: ?string, cancel: boolean) => + * void + * ) + * ), + * reject: Error => Promise + * ) => + * (chunk: Buffer) => + * string; + */ const buildCredentialsCallbackProcess = (spawnedProcess, callback, reject) => { const credentialsCallback = promptType => (username, password, cancel) => { if (cancel) { - // we are done here spawnedProcess.destroy(); return reject(new Error('LFS action cancelled')); } @@ -49,6 +66,7 @@ const buildCredentialsCallbackProcess = (spawnedProcess, callback, reject) => { } else if (output.match(regex.PASSPHRASE)) { callback(output, credentialsCallback(promptTypes.PASSPHRASE)); } + return output; }; }; @@ -89,6 +107,7 @@ const buildSocket = (size, closeProcess, socketName, mainResolve, mainReject) => }); socket.on('error', handleErrorWith(mainReject)); }); + socketServer.listen(socketName); socketServer.on('listening', () => { resolve(socketName); @@ -207,3 +226,9 @@ const spawn = (command, opts = {}, callback) => new Promise( }); export default spawn; + +export const __TESTING__ = { // eslint-disable-line no-underscore-dangle + buildCredentialsCallbackProcess, + buildSocket, + buildSocketPath +}; diff --git a/test/tests/callbacks/initialize.check.js b/test/tests/callbacks/initialize.spec.js similarity index 100% rename from test/tests/callbacks/initialize.check.js rename to test/tests/callbacks/initialize.spec.js diff --git a/test/tests/commands/checkout.spec.js b/test/tests/commands/checkout.spec.js new file mode 100644 index 0000000..f1d4da0 --- /dev/null +++ b/test/tests/commands/checkout.spec.js @@ -0,0 +1,9 @@ +import { + todo +} from '../../utils'; + +describe('checkout', () => { + it('can checkout in the provided repo', todo); + + it('responds appropriately on error', todo); +}); diff --git a/test/tests/commands/clone.spec.js b/test/tests/commands/clone.spec.js index fe0ec89..3d8b54d 100644 --- a/test/tests/commands/clone.spec.js +++ b/test/tests/commands/clone.spec.js @@ -13,11 +13,11 @@ import { populateRemoteBranch } from '../../server/server'; import { - fail + fail, + todo } from '../../utils'; import { - BAD_CORE_RESPONSE, BAD_REGEX_PARSE_RESULT } from '../../../build/src/constants'; import { @@ -168,24 +168,5 @@ describe('Clone', () => { } }); - it('should return an appropriate result on error', function () { - const { - NodeGitLFS - } = this; - - return NodeGitLFS.LFS.clone( - 'invalid', - testReposPath - ) - .then((result) => { - expect(result.errno).to.equal(BAD_CORE_RESPONSE); - expect(result.stderr).to.equal( -`fatal: repository 'invalid' does not exist -Error(s) during clone: -git clone failed: exit status 128 -`, - ); - expect(result.success).to.be.false; - }); - }); + it('should return an appropriate result on error', todo); }); diff --git a/test/tests/commands/lfsCommands.spec.js b/test/tests/commands/lfsCommands.spec.js new file mode 100644 index 0000000..4ef31a9 --- /dev/null +++ b/test/tests/commands/lfsCommands.spec.js @@ -0,0 +1,39 @@ +import { + todo +} from '../../utils'; + +describe('lfsCommands', () => { + it('can run `git lfs checkout`', todo); + + it('can run `git lfs clone`', todo); + + it('can run `git lfs fetch`', todo); + + it('can run `git lfs fsck`', todo); + + it('can run any `git` command', todo); + + it('can run `git lfs install`', todo); + + it('can run `git lfs logs`', todo); + + it('can run `git lfs ls-files`', todo); + + it('can run `git lfs pointer`', todo); + + it('can run `git lfs prune`', todo); + + it('can run `git lfs pull`', todo); + + it('can run `git lfs push`', todo); + + it('can run `git lfs status`', todo); + + it('can run `git lfs track`', todo); + + it('can run `git lfs untrack`', todo); + + it('can run `git lfs update`', todo); + + it('can run `git lfs version`', todo); +}); diff --git a/test/tests/commands/ls.spec.js b/test/tests/commands/ls.spec.js index bb7468a..6e1cdf3 100644 --- a/test/tests/commands/ls.spec.js +++ b/test/tests/commands/ls.spec.js @@ -1,20 +1,11 @@ -import { - lfsTestRepoPath -} from '../../constants'; import { todo } from '../../utils'; -import ls from '../../../build/src/commands/ls'; - describe('ls-files', () => { - it('does generate ls response', function () { - const { - NodeGitLFS - } = this; + it('builds args from the provided options', todo); + + it('can list LFS-tracked files in the provided repo', todo); - return NodeGitLFS.Repository.open(lfsTestRepoPath) - .then(repo => ls(repo, { long: true })) - .then(() => todo()); - }); + it('returns the correct response on error', todo); }); diff --git a/test/tests/commands/pointer.spec.js b/test/tests/commands/pointer.spec.js index 33aab2e..600ec0f 100644 --- a/test/tests/commands/pointer.spec.js +++ b/test/tests/commands/pointer.spec.js @@ -1,24 +1,11 @@ -import path from 'path'; - -import { - lfsTestRepoPath -} from '../../constants'; import { todo } from '../../utils'; -import pointer from '../../../build/src/commands/pointer'; - describe('Pointer', () => { - it('does generate pointer response', function () { - const { - NodeGitLFS - } = this; + it('creates args from provided file and pointer paths', todo); - const packageJson = path.join(lfsTestRepoPath, 'package.json'); + it('can build a pointer', todo); - return NodeGitLFS.Repository.open(lfsTestRepoPath) - .then(repo => pointer(repo, packageJson)) - .then(() => todo()); - }); + it('responds appropriately on error', todo); }); diff --git a/test/tests/commands/prune.spec.js b/test/tests/commands/prune.spec.js index 4652e4b..08773d4 100644 --- a/test/tests/commands/prune.spec.js +++ b/test/tests/commands/prune.spec.js @@ -1,20 +1,9 @@ -import { - lfsTestRepoPath -} from '../../constants'; import { todo } from '../../utils'; -import prune from '../../../build/src/commands/prune'; - describe('Prune', () => { - it('does generate prune response', function () { - const { - NodeGitLFS - } = this; + it('can prune the provided repository', todo); - return NodeGitLFS.Repository.open(lfsTestRepoPath) - .then(repo => prune(repo)) - .then(() => todo()); - }); + it('responds appropriately on error', todo); }); diff --git a/test/tests/commands/push.spec.js b/test/tests/commands/push.spec.js index 5bf2ea6..d2daab3 100644 --- a/test/tests/commands/push.spec.js +++ b/test/tests/commands/push.spec.js @@ -1,26 +1,9 @@ -import path from 'path'; - -import { - lfsTestRepoPath -} from '../../constants'; import { - createDummyFile, todo } from '../../utils'; -import exec from '../../../build/src/utils/execHelper'; - describe('Push', () => { - it('should generate push response', function () { - const { - NodeGitLFS - } = this; + it('defaults to the current branch and its upstream', todo); - return createDummyFile(path.join(lfsTestRepoPath, 'test_file.txt'), 20) - .then(() => exec('git add test_file.txt', { cwd: lfsTestRepoPath })) - .then(() => exec('git commit -m "LFS: push unit test"', { cwd: lfsTestRepoPath })) - .then(() => NodeGitLFS.Repository.open(lfsTestRepoPath)) - .then(repo => NodeGitLFS.LFS.push(repo, 'origin', 'test')) - .then(() => todo()); - }); -}).timeout(5000); + it('responds appropriately on error', todo); +}); diff --git a/test/tests/commands/track.spec.js b/test/tests/commands/track.spec.js index 1196666..99b5633 100644 --- a/test/tests/commands/track.spec.js +++ b/test/tests/commands/track.spec.js @@ -1,20 +1,11 @@ -import { - lfsTestRepoPath -} from '../../constants'; import { todo } from '../../utils'; -import track from '../../../build/src/commands/track'; - describe('Track', () => { - it('does generate track response', function () { - const { - NodeGitLFS - } = this; + it('requires globs to be provided', todo); + + it('can track files', todo); - return NodeGitLFS.Repository.open(lfsTestRepoPath) - .then(repo => track(repo, ['*.png', '*.dmg'])) - .then(() => todo()); - }); + it('responds appropriately on error', todo); }); diff --git a/test/tests/commands/untrack.spec.js b/test/tests/commands/untrack.spec.js index 5253806..f265699 100644 --- a/test/tests/commands/untrack.spec.js +++ b/test/tests/commands/untrack.spec.js @@ -1,27 +1,11 @@ -import { - lfsTestRepoPath -} from '../../constants'; import { todo } from '../../utils'; -import track from '../../../build/src/commands/track'; -import untrack from '../../../build/src/commands/untrack'; - describe('Untrack', () => { - it('does generate untrack response', function () { - const { - NodeGitLFS - } = this; + it('requires globs to be provided', todo); - let repository; + it('can untrack currently-tracked files', todo); - return NodeGitLFS.Repository.open(lfsTestRepoPath) - .then((repo) => { - repository = repo; - return track(repo, ['*.png', '*.dmg', '*.txt', '*.a']); - }) - .then(() => untrack(repository, ['*.dmg', '*.a'])) - .then(() => todo()); - }); + it('responds appropriately on error', todo); }); diff --git a/test/tests/constants.spec.js b/test/tests/constants.spec.js new file mode 100644 index 0000000..a3eead1 --- /dev/null +++ b/test/tests/constants.spec.js @@ -0,0 +1,27 @@ +import { + todo +} from '../utils'; + +describe('Constants', () => { + describe('Regexes', () => { + it('GIT', todo); + + it('LFS', todo); + + it('PASSWORD', todo); + + it('SKIPPED_BYTES', todo); + + it('SKIPPED_FILES', todo); + + it('TOTAL_BYTES', todo); + + it('TOTAL_FILES', todo); + + it('TRACK', todo); + + it('USERNAME', todo); + + it('VERSION', todo); + }); +}); diff --git a/test/tests/helpers.spec.js b/test/tests/helpers.spec.js index 97a7d28..7ebe5a2 100644 --- a/test/tests/helpers.spec.js +++ b/test/tests/helpers.spec.js @@ -54,7 +54,7 @@ describe('helpers', () => { repo } = this; - return track(repo, ['"*.md"', 'test.txt']) + return track(repo, ['*.md', 'test.txt']) .then(() => helpers.loadGitattributeFiltersFromRepo(repo)) .then((result) => { expect(result).to.have.members(['*.md', 'test.txt']); diff --git a/test/tests/index.spec.js b/test/tests/index.spec.js index 16df915..08e7eb9 100644 --- a/test/tests/index.spec.js +++ b/test/tests/index.spec.js @@ -1,37 +1,56 @@ -import { expect } from 'chai'; - +import { + expect +} from 'chai'; +import NodeGit from 'nodegit'; + +import checkout from '../../build/src/commands/checkout'; +import clone from '../../build/src/commands/clone'; +import fetch from '../../build/src/commands/fetch'; +import initialize from '../../build/src/initialize'; +import { + core +} from '../../build/src/commands/lfsCommands'; +import list from '../../build/src/commands/ls'; +import prune from '../../build/src/commands/prune'; +import pull from '../../build/src/commands/pull'; +import push from '../../build/src/commands/push'; +import testPointer from '../../build/src/commands/pointer'; +import register from '../../build/src/register'; +import track from '../../build/src/commands/track'; +import unregister from '../../build/src/unregister'; +import untrack from '../../build/src/commands/untrack'; +import version from '../../build/src/commands/version'; +import { + loadGitattributeFiltersFromRepo, + hasLfsFilters +} from '../../build/src/helpers'; +import { + dependencyCheck +} from '../../build/src/utils/checkDependencies'; + +// NOTE These tests depend on `LFS(NodeGit)` being called in the global `beforeEach`. describe('LFS', () => { - it('LFS exists', function () { - const { - NodeGitLFS - } = this; - - expect(NodeGitLFS).to.have.property('LFS'); - }); - - it('initialize exists', function () { - const { - NodeGitLFS - } = this; - - expect(NodeGitLFS.LFS).to.have.property('initialize'); - }); - - it('register exists', function () { - const { - NodeGitLFS - } = this; - - expect(NodeGitLFS.LFS).to.have.property('register'); - expect(NodeGitLFS.LFS.register).to.be.a('function'); - }); - - it('unregister exists', function () { - const { - NodeGitLFS - } = this; - - expect(NodeGitLFS.LFS).to.have.property('unregister'); - expect(NodeGitLFS.LFS.unregister).to.be.a('function'); + it('permanently adds itself to NodeGit', () => { + expect(NodeGit.LFS).to.eql({ + checkout, + clone, + core, + dependencyCheck, + fetch, + filters: loadGitattributeFiltersFromRepo, + hasLfsFilters, + initialize, + list, + NodeGit, + register, + testPointer, + track, + prune, + pull, + push, + version, + unregister, + untrack + }); }); }); diff --git a/test/tests/initialize.spec.js b/test/tests/initialize.spec.js index c0f10c5..3fef37f 100644 --- a/test/tests/initialize.spec.js +++ b/test/tests/initialize.spec.js @@ -1,35 +1,11 @@ import { - expect -} from 'chai'; -import fs from 'fs'; -import path from 'path'; - -import { - emptyRepoPath, - lfsTestRepoPath -} from '../constants'; + todo +} from '../utils'; describe('Initialize', () => { - it('initialize is a promise', function () { - const { - NodeGitLFS - } = this; - - return NodeGitLFS.Repository.open(lfsTestRepoPath) - .then(repo => NodeGitLFS.LFS.initialize(repo)); - }); - - it('creates .gitattributes for empty repo', function () { - const { - NodeGitLFS - } = this; + it('correctly calculates arguments from options', todo); - expect(fs.existsSync(path.join(emptyRepoPath, '.gitattributes'))).to.be.false; + it('initializes a non-LFS repo', todo); - return NodeGitLFS.Repository.open(emptyRepoPath) - .then(repo => NodeGitLFS.LFS.initialize(repo)) - .then(() => { - expect(fs.existsSync(path.join(emptyRepoPath, '.gitattributes'))).to.be.true; - }); - }); + it('skips initializing on a repo that has already been initializing', todo); }); diff --git a/test/tests/utils/execHelper.spec.js b/test/tests/utils/execHelper.spec.js index f599d6b..c2e5199 100644 --- a/test/tests/utils/execHelper.spec.js +++ b/test/tests/utils/execHelper.spec.js @@ -5,7 +5,8 @@ import childProcess from 'child_process'; import sinon from 'sinon'; import { - fail + fail, + todo } from '../../utils'; import exec from '../../../src/utils/execHelper'; @@ -14,7 +15,14 @@ describe('exec', () => { beforeEach(function () { this.sandbox = sinon.sandbox.create(); - this.execSpy = this.sandbox.stub(childProcess, 'exec').returns('proc object'); + this.mockProcess = { + stdin: { + end: this.sandbox.spy(), + write: this.sandbox.spy() + } + }; + + this.execSpy = this.sandbox.stub(childProcess, 'exec').returns(this.mockProcess); }); afterEach(function () { @@ -27,7 +35,8 @@ describe('exec', () => { it('resolves with the spawned process and its stdout and stderr on success', function () { const { - execSpy + execSpy, + mockProcess } = this; const promise = exec('test', { foo: 'bar' }); @@ -35,13 +44,15 @@ describe('exec', () => { return promise .then((result) => { expect(result).to.eql({ - proc: 'proc object', + proc: mockProcess, stderr: 'some stderr', stdout: 'some stdout' }); }); }); + it('writes out provided input', todo); + it('rejects with the error on failure', function () { const { execSpy @@ -51,8 +62,8 @@ describe('exec', () => { execSpy.firstCall.args[2]('some error'); return promise .then(() => fail('Expected this promise to fail!')) - .catch((result) => { - expect(result).to.equal('some error'); + .catch((err) => { + expect(err).to.equal('some error'); }); }); }); diff --git a/test/tests/utils/spawnHelper.spec.js b/test/tests/utils/spawnHelper.spec.js index 7a1bbd7..da2a1d6 100644 --- a/test/tests/utils/spawnHelper.spec.js +++ b/test/tests/utils/spawnHelper.spec.js @@ -1,16 +1,11 @@ -import { - expect -} from 'chai'; import childProcess from 'child_process'; import sinon from 'sinon'; import { - fail + todo } from '../../utils'; -import spawn from '../../../build/src/utils/spawnHelper'; - -describe('spawn', () => { +describe('Spawn Helpers', () => { beforeEach(function () { this.sandbox = sinon.sandbox.create(); @@ -39,223 +34,135 @@ describe('spawn', () => { sandbox.restore(); }); - it("merges the calling process' env into the provided env", function () { - const { - sandbox, - spawnStub - } = this; + describe('spawn', () => { + it('defaults `opts` to `{}`', todo); - sandbox.stub(process, 'env').get(() => ({ - foo: 'override', - baz: 'quux' - })); + it("merges the calling process' env into the provided env", todo); - spawn('command', { env: { foo: 'bar' } }); - expect(spawnStub).to.have.been.calledWithMatch('command', [], { - env: { - foo: 'bar', - baz: 'quux' - } + if (process.platform === 'win32') { + it('adds the `.exe` prefix to commands', todo); + } else { + it('does not add a `.exe` prefix to commands', todo); + } + + it('parses arguments', todo); + + describe('when a callback argument is provided', () => { + it('uses it for credentials if it is a function', todo); + + it('ignores it if it is not a function', todo); }); + + it('spawns the command', todo); + + it('resolves with the correct data on a successful exit', todo); + + it('rejects on spawn error', todo); + + it('rejects on non-0 exit code', todo); }); - it('correctly overrides `shell`', function () { - const { - spawnStub - } = this; + describe('winSpawn', () => { + it('defaults `opts` to `{}`', todo); - spawn('command', { shell: false }); - expect(spawnStub).to.have.been.calledWithMatch('command', [], { - shell: true - }); + it("merges the calling process' env into the provided env", todo); + + it('overwrites `shell` to `true`', todo); + + it('parses arguments', todo); + + it('spawns the command', todo); + + it('resolves with the correct data on a successful exit', todo); + + it('writes to standard input'); + + it('rejects on spawn error', todo); + + it('rejects on non-0 exit code', todo); }); - if (process.platform === 'darwin' || process.platform === 'win32') { - it('correctly calculates arguments on Windows or macOS', function () { - const { - spawnStub - } = this; - - spawn('command arg1 arg2'); - expect(spawnStub).to.have.been.calledWithMatch('command', ['arg1', 'arg2'], { - detached: false, - env: process.env, - shell: true - }); - }); - } - - if (process.platform === 'linux') { - it('correctly calculates arguments on Linux', function () { - const { - spawnStub - } = this; - - spawn('command arg1 arg2'); - expect(spawnStub).to.have.been.calledWithMatch( - 'script --return -c "command arg1 arg2" /dev/null', - [], - { - detached: true, - env: process.env, - shell: true - } - ); - }); - } + describe('spawnShell', () => { + it('defaults `opts` to `{}`', todo); - if (process.platform === 'linux') { - it('correctly handles `git lfs smudge` on Linux', function () { - const { - spawnStub - } = this; + it("merges the calling process' env into the provided env", todo); - spawn('git lfs smudge', { - input: 'file.txt' - }); - expect(spawnStub).to.have.been.calledWithMatch( - 'cat file.txt | git lfs smudge', - [], - { - detached: true, - env: process.env, - shell: true - } - ); - }); - } + it('builds the socket with the right arguments', todo); - describe('when passed a callback', () => { - afterEach(function () { - const { - sandbox - } = this; + it('uses raw `Buffer`s', todo); - sandbox.restore(); - }); + describe('when a callback argument is provided', () => { + it('uses it for credentials if it is a function', todo); - it('ignores the callback if it is not a `Function`', function () { - const { - mockProcess - } = this; + it('ignores it if it is not a function', todo); - spawn('', {}, 'not a callback'); - const stdoutHandler = mockProcess.stdout.on.firstCall.args[1]; - stdoutHandler(new Buffer('some data')); - }); + if (process.platform === 'win32') { + it('pipes the command output', todo); + } else { + it('pipes the command output', todo); + } - it('uses the callback to obtain credentials', function () { - const { - mockProcess, - sandbox - } = this; + it('spawns the command', todo); - const cbStub = sandbox.stub().callsFake((cb) => { - cb('some username', 'some password', false); - }); - spawn('', {}, cbStub); - const stdoutHandler = mockProcess.stdout.on.firstCall.args[1]; - stdoutHandler(new Buffer('Username: ')); - expect(mockProcess.stdin.write.firstCall.args[0].toString()).to.equal('some username\n'); - stdoutHandler(new Buffer('Password: ')); - expect(mockProcess.stdin.write.secondCall.args[0].toString()).to.equal('some password\n'); - - expect(cbStub).to.have.been.calledOnce; + it('closes when the socket closes', todo); }); + }); - it('does not require the callback to send a password', function () { - const { - mockProcess, - sandbox - } = this; + describe('buildSocket', () => { + it('resolves the calling `Promise` with the correct data on a successful exit', todo); - const cbStub = sandbox.stub().callsFake((cb) => { - cb('some username', '', false); - }); - spawn('', {}, cbStub); - const stdoutHandler = mockProcess.stdout.on.firstCall.args[1]; - stdoutHandler(new Buffer('Username: ')); - expect(mockProcess.stdin.write.firstCall.args[0].toString()).to.equal('some username\n'); - stdoutHandler(new Buffer('Password: ')); - expect(mockProcess.stdin.write.secondCall.args[0].toString()).to.equal('\n'); - - expect(cbStub).to.have.been.calledOnce; - }); + it('only runs the successful close logic once', todo); - it('allows the callback to cancel', function () { - const { - mockProcess - } = this; + it('calls the close callback when the socket ends', todo); - const promise = spawn('', {}, (cb) => { - cb(undefined, undefined, true); - }); - const stdoutHandler = mockProcess.stdout.on.firstCall.args[1]; - stdoutHandler(new Buffer('Username: ')); - return promise - .then(() => fail('The promise should have failed!')) - .catch((err) => { - expect(err.message).to.equal('LFS action cancelled'); - }); - }); + it('calls the close callback when the socket closes', todo); + + it('reads incoming data, closing the socket server when enough bytes have been read', todo); + + it('rejects the calling `Promise` on socket error', todo); + + it('listens to the socket', todo); + + it('resolves with the socket name when the server is ready', todo); + + it('calls the close callback on server close', todo); + + it('rejects on server error', todo); }); - describe('when `spawn` completes successfully', () => { - afterEach(function () { - const { - sandbox - } = this; + describe('buildCredentialsCallbackProcess', () => { + describe('when prompted for a username', () => { + describe('when a username has not been cached', () => { + it('calls the callback to obtain a username and password and writes the username out', todo); + }); - sandbox.restore(); + describe('when the username has been cached', () => { + it('writes the cached username out', todo); + }); }); - it('resolves with the exit code, processed stdout, and stderr', function () { - const { - mockProcess - } = this; - - const promise = spawn(''); - const closeHandler = mockProcess.on.firstCall.args[1]; - const stderrHandler = mockProcess.stderr.on.firstCall.args[1]; - const stdoutHandler = mockProcess.stdout.on.firstCall.args[1]; - stderrHandler('some stderr, line 1\n'); - stderrHandler('some stderr, line 2'); - stdoutHandler('some stdout, line 1\n'); - stdoutHandler('some stdout, line 2'); - closeHandler(0); - return promise - .then((result) => { - expect(result).to.eql({ - code: 0, - stderr: 'some stderr, line 1\nsome stderr, line 2', - stdout: 'some stdout, line 1\nsome stdout, line 2' - }); - }); + describe('when prompted for a password', () => { + describe('when a password was provided by the callback', () => { + it('writes the password out', todo); + }); + + describe('when a password was not provided by the callback', () => { + it('calls the callback to obtain a password only and writes the password out', todo); + }); }); + + it('allows the callback to cancel', todo); }); - describe('when `spawn` errors', () => { - afterEach(function () { - const { - sandbox - } = this; + describe('buildSocketPath', () => { + if (process.platform === 'win32') { + it('prefixes `.pipe` to the socket path', todo); - sandbox.restore(); - }); + it('removes `C:\\` from the socket path', todo); - it('rejects with the exit code', function () { - const { - mockProcess - } = this; - - const promise = spawn(''); - const errorHandler = mockProcess.on.secondCall.args[1]; - errorHandler(-1337); - return promise - .then(() => fail('This promise should have failed!')) - .catch((err) => { - expect(err).to.equal(-1337); - }); - }); + it('removes `.tmp` from the socket path', todo); + } else { + it('removes `.tmp` from the socket path', todo); + } }); }); From 465d6e467cdc616333f0801f4500b17029b77e40 Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Wed, 30 Aug 2017 14:19:57 -0700 Subject: [PATCH 34/42] Standardize test style Fix tests post-rebase --- README.md | 138 +++++++++++++ src/constants.js | 1 - test/runner.js | 10 +- test/tests/callbacks/apply.spec.js | 54 +++--- test/tests/callbacks/check.spec.js | 97 +++++---- test/tests/callbacks/initialize.spec.js | 8 +- test/tests/commands/checkout.spec.js | 6 +- test/tests/commands/clone.spec.js | 216 +++++++++++---------- test/tests/commands/lfsCommands.spec.js | 102 ++++++---- test/tests/commands/ls.spec.js | 10 +- test/tests/commands/pointer.spec.js | 10 +- test/tests/commands/prune.spec.js | 8 +- test/tests/commands/push.spec.js | 18 +- test/tests/commands/track.spec.js | 10 +- test/tests/commands/untrack.spec.js | 10 +- test/tests/commands/version.spec.js | 21 -- test/tests/constants.spec.js | 58 ++++-- test/tests/helpers.spec.js | 87 ++++----- test/tests/index.spec.js | 48 ++--- test/tests/initialize.spec.js | 14 +- test/tests/register.spec.js | 54 +++--- test/tests/unregister.spec.js | 44 +++-- test/tests/utils/checkDependencies.spec.js | 73 ------- test/tests/utils/execHelper.spec.js | 68 ++++--- test/tests/utils/generateResponse.spec.js | 14 +- test/tests/utils/spawnHelper.spec.js | 4 +- 26 files changed, 664 insertions(+), 519 deletions(-) delete mode 100644 test/tests/commands/version.spec.js delete mode 100644 test/tests/utils/checkDependencies.spec.js diff --git a/README.md b/README.md index c3eb18a..5502c95 100644 --- a/README.md +++ b/README.md @@ -52,3 +52,141 @@ yarn **Tests are still a Work In Progress.** The tests rely on `mocha`, `chai`, `sinon`, and `sinon-chai`, and are currently a mix of system and unit tests. + +### Naming + +**TODO:** Split out system tests from unit tests and then revise the below guidlines. + +These guidelines are inspired by [Better Specs { rspec guidelines with ruby }](https://www.betterspecs.org). Given that these guidelines are, by necessity, quite subjective, consider them as beneficial for the consistency rather than the "correctness" that they provide. + +The linter should catch basic stylistic errors (e.g. prefer arrow functions unless `this` is needed). + +--- + +When naming individual `it` blocks, the resulting test name should read like a sentence. For example: `it('returns false if the repo has no filters')`. + +Directly describe what the test should do. Use verbs like `returns`, `errors`, `responds`, `reads`, etc. rather than prefixing tests with `should`, suffixing them with `correctly`, etc.. For example: + +``` javascript +/* Bad */ +it('should read globs from `.gitattributes` correctly', function () { + // ... +}); + +/* Good */ +it('reads globs from `.gitattributes`', function () { + // ... +}); +``` + +--- + +If you have the temptation to start a test with `can`, try to restructure the test to use a nested `describe` instead (whose message starts with `when`). For example: + +``` javascript +/* Bad */ +it('can initialize a non-LFS repo', function () { + // ... +}); + +/* Good */ +describe('when provided a non-LFS repo', () => { + it('initializes the repo', function () { + // ... + }); +}); +``` + +--- + +For tests whose behavior varies cross-platform, surround the tests with a `process.platform` test. Be sure to add tests for all platforms where behavior could vary, even if you cannot run them locally. Because CI will run on Windows, macOS, and Linux, this should not be an obstacle to thorough test coverage. For example: + +``` javascript +/* Bad */ +describe('when on Windows', () => { + beforeEach(() => { + sinon.stub(process, 'platform').returns('win32'); + }); + + it('runs the provided command', function () { + // ... + }); +}); + +describe('when on macOS', () => { + beforeEach(() => { + sinon.stub(process, 'platform').returns('darwin'); + }); + + it('runs the provided command', function () { + // ... + }); +}); + +describe('when on Linux', () => { + beforeEach(() => { + sinon.stub(process, 'platform').returns('linux'); + }); + + it('runs the provided command', function () { + // ... + }); +}); + +/* Good */ +switch (process.platform) { + case 'win32': + it('runs the provided command', function () { + // ... + }); + break; + case 'macOS': + it('runs the provided command', function () { + // ... + }); + break; + case 'linux': + it('runs the provided command', function () { + // ... + }); + break; +} +``` + +--- + +When referring to parameters, use `provided` rather than `passed-in`, `given`, etc. For example: + +``` javascript +/* Bad */ +it('runs the passed-in command', function () { + // ... +}); + +/* Good */ +it('runs the provided command', function () { + // ... +}); +``` + +--- + +Each implementation file should correspond to a similarly-named `.spec.js` test file in the same relative location. For example, `src/callbacks/check.js` should have a test file located in `test/tests/callbacks/check.spec.js`. + +The top-level `describe` should be named after the file. `describe`s for each function should be named after the function itself. On a related note, each function should have its own `describe` block, even if there is only `it` block inside it. In the case that a function does not have a pre-defined name (e.g. it's an anonymous function exported as the default), refer to it as `the default export`. For example: + +``` javascript +/* For named exports: */ +describe('helpers', () => { // Named after the file name, `helpers.spec.js` + describe('hasLfsFilters', () => { // Named after the exported function name, `hasLfsFilters` + // ... + }); +}); + +/* For default exports: */ +describe('check', () => { + describe('the default export', () => { + // ... + }); +}); +``` diff --git a/src/constants.js b/src/constants.js index 688557d..2f26de5 100644 --- a/src/constants.js +++ b/src/constants.js @@ -5,7 +5,6 @@ export const LFS_FILTER_NAME = 'nodegit_lfs'; export const regex = { LFS: /(?:git-lfs\/\s*)?(\d+)(?:.(\d+))?(?:.(\d+))?.*/, GIT: /(?:git\s+version\s+)(\d+)\.(\d+)\.(\d+)/, - VERSION: /(\d+\.){2}\d+/, TRACK: /([a-zA-Z*.]+(?="))/g, SKIPPED_BYTES: /[\d]+\s+B\s+(?=skipped)/g, SKIPPED_FILES: /[\d]\s+(?=skipped)/g, diff --git a/test/runner.js b/test/runner.js index 3fb47b9..d23514a 100644 --- a/test/runner.js +++ b/test/runner.js @@ -77,8 +77,16 @@ beforeEach(function () { return NodeGitLFS.LFS.register() .then(() => setupEmptyTestRepo()) + .then(() => NodeGitLFS.Repository.open(emptyRepoPath)) + .then((emptyRepo) => { + this.emptyRepo = emptyRepo; + }) .then(() => setupLfsTestRemote()) - .then(() => setupLfsTestRepo()); + .then(() => setupLfsTestRepo()) + .then(() => NodeGitLFS.Repository.open(lfsTestRepoPath)) + .then((lfsTestRepo) => { + this.lfsTestRepo = lfsTestRepo; + }); }); after(function () { diff --git a/test/tests/callbacks/apply.spec.js b/test/tests/callbacks/apply.spec.js index aacdf95..d0906b9 100644 --- a/test/tests/callbacks/apply.spec.js +++ b/test/tests/callbacks/apply.spec.js @@ -29,6 +29,7 @@ const track = (repo, globs) => { describe('apply', () => { beforeEach(function () { const { + lfsTestRepo, NodeGitLFS } = this; @@ -68,7 +69,7 @@ describe('apply', () => { }; this.trackTestFile = () => - track(this.repo, [this.testFileName]) + track(lfsTestRepo, [this.testFileName]) .then(() => createDummyFile( path.join(lfsTestRepoPath, this.testFileName), testFileSize @@ -76,7 +77,7 @@ describe('apply', () => { .then((contents) => { this.contents = contents; }) - .then(() => this.commitFile(this.repo, this.testFileName, 'LFS filter tests')); + .then(() => this.commitFile(lfsTestRepo, this.testFileName, 'LFS filter tests')); this.verifyTestFileTracked = () => fse.readFile(path.join(lfsTestRepoPath, this.testFileName), 'utf8') @@ -87,37 +88,36 @@ describe('apply', () => { .then((pointer) => { expect(pointer).to.have.string(`size ${testFileSize}`); }); - - return NodeGitLFS.Repository.open(lfsTestRepoPath) - .then((repo) => { - this.repo = repo; - }); }); - it('Clean', function () { - const { + describe('clean', () => { + it('cleans LFS-tracked files', function () { + const { trackTestFile, - verifyTestFileTracked + verifyTestFileTracked } = this; - return trackTestFile() - .then(() => verifyTestFileTracked()); + return trackTestFile() + .then(() => verifyTestFileTracked()); + }); }); - it('Smudge', function () { - const { - NodeGitLFS, - repo, - testFileName, - trackTestFile, - verifyTestFileTracked - } = this; + describe('smudge', () => { + it('smudges LFS blobs', function () { + const { + NodeGitLFS, + lfsTestRepo, + testFileName, + trackTestFile, + verifyTestFileTracked + } = this; - return trackTestFile() - .then(() => createDummyFile(path.join(lfsTestRepoPath, testFileName), 5)) - .then(() => NodeGitLFS.Checkout.head(repo, { - checkoutStrategy: NodeGitLFS.Checkout.STRATEGY.FORCE - })) - .then(() => verifyTestFileTracked()); - }).timeout(10000); + return trackTestFile() + .then(() => createDummyFile(path.join(lfsTestRepoPath, testFileName), 5)) + .then(() => NodeGitLFS.Checkout.head(lfsTestRepo, { + checkoutStrategy: NodeGitLFS.Checkout.STRATEGY.FORCE + })) + .then(() => verifyTestFileTracked()); + }).timeout(10000); + }); }); diff --git a/test/tests/callbacks/check.spec.js b/test/tests/callbacks/check.spec.js index 73e5f6f..1dc9057 100644 --- a/test/tests/callbacks/check.spec.js +++ b/test/tests/callbacks/check.spec.js @@ -5,77 +5,76 @@ import { Error } from 'nodegit'; -import { - lfsTestRepoPath -} from '../../constants'; - import track from '../../../build/src/commands/track'; import checkCallback from '../../../build/src/callbacks/check'; describe('check', () => { beforeEach(function () { const { - NodeGitLFS + lfsTestRepo } = this; this.check = fileName => checkCallback({ path: () => fileName, - repo: () => this.repo + repo: () => lfsTestRepo }); - - return NodeGitLFS.Repository.open(lfsTestRepoPath) - .then((repo) => { - this.repo = repo; - }); }); - it('returns `OK` for a file directly specified in .gitattributes', function () { - const { - check, - repo - } = this; + describe('the default export', () => { + describe('when the provided file is directly specified in `.gitattributes`', () => { + it('returns `OK` for the provided file', function () { + const { + check, + lfsTestRepo + } = this; - return track(repo, ['test.txt']) - .then(() => check('test.txt')) - .then((result) => { - expect(result).to.equal(Error.CODE.OK); + return track(lfsTestRepo, ['test.txt']) + .then(() => check('test.txt')) + .then((result) => { + expect(result).to.equal(Error.CODE.OK); + }); }); - }); + }); - it('returns `OK` for a file included in a glob in .gitattributes', function () { - const { - check, - repo - } = this; + describe('when the provided file is included in a glob in `.gitattributes`', () => { + it('returns `OK` for the provided file', function () { + const { + check, + lfsTestRepo + } = this; - return track(repo, ['*.txt']) - .then(() => check('test.txt')) - .then((result) => { - expect(result).to.equal(Error.CODE.OK); + return track(lfsTestRepo, ['*.txt']) + .then(() => check('test.txt')) + .then((result) => { + expect(result).to.equal(Error.CODE.OK); + }); }); - }); + }); - it('returns `PASSTHROUGH` for a file not included in .gitattributes', function () { - const { - check, - repo - } = this; + describe('when the provided file is not included in `.gitattributes`', () => { + it('returns `PASSTHROUGH`', function () { + const { + check, + lfsTestRepo + } = this; - return track(repo, ['other.txt']) - .then(() => check('test.txt')) - .then((result) => { - expect(result).to.equal(Error.CODE.PASSTHROUGH); + return track(lfsTestRepo, ['other.txt']) + .then(() => check('test.txt')) + .then((result) => { + expect(result).to.equal(Error.CODE.PASSTHROUGH); + }); }); - }); + }); - it('returns `PASSTHROUGH` on error', function () { - const { - check - } = this; + it('returns `PASSTHROUGH` on error', function () { + const { + check + } = this; - return check('test.txt') - .then((result) => { - expect(result).to.equal(Error.CODE.PASSTHROUGH); - }); + return check('test.txt') + .then((result) => { + expect(result).to.equal(Error.CODE.PASSTHROUGH); + }); + }); }); }); diff --git a/test/tests/callbacks/initialize.spec.js b/test/tests/callbacks/initialize.spec.js index 32569cc..913497d 100644 --- a/test/tests/callbacks/initialize.spec.js +++ b/test/tests/callbacks/initialize.spec.js @@ -7,8 +7,10 @@ import { import initialize from '../../../build/src/callbacks/initialize'; -describe('Initialize', () => { - it('returns `OK`', () => { - expect(initialize()).to.equal(Error.CODE.OK); +describe('initialize', () => { + describe('the default export', () => { + it('returns `OK`', () => { + expect(initialize()).to.equal(Error.CODE.OK); + }); }); }); diff --git a/test/tests/commands/checkout.spec.js b/test/tests/commands/checkout.spec.js index f1d4da0..c8980b6 100644 --- a/test/tests/commands/checkout.spec.js +++ b/test/tests/commands/checkout.spec.js @@ -3,7 +3,9 @@ import { } from '../../utils'; describe('checkout', () => { - it('can checkout in the provided repo', todo); + describe('the default export', () => { + it('runs checkout in the provided repo', todo); - it('responds appropriately on error', todo); + it('handles errors', todo); + }); }); diff --git a/test/tests/commands/clone.spec.js b/test/tests/commands/clone.spec.js index 3d8b54d..3acb9e9 100644 --- a/test/tests/commands/clone.spec.js +++ b/test/tests/commands/clone.spec.js @@ -26,7 +26,7 @@ import { const tempRepoPath = path.join(testReposPath, 'nodegit-lfs-test-repo'); -describe('Clone', () => { +describe('clone', () => { beforeEach(function () { this.sandbox = sinon.sandbox.create(); @@ -41,132 +41,138 @@ describe('Clone', () => { sandbox.restore(); }); - it('should clone a repo', function () { - const { - NodeGitLFS - } = this; + describe('the default export', () => { + describe('when no branch is provided', () => { + it('clones a repo at `master`', function () { + const { + NodeGitLFS + } = this; + + // We are testing the returned value in the specific branch test, because the test repo's + // `master` branch doesn't have LFS enabled by default + return NodeGitLFS.LFS.clone( + `${lfsTestRemotePath} ${tempRepoPath}`, + testReposPath, + { + env: { + GIT_SSL_NO_VERIFY: 1 + } + } + ) + .then(() => NodeGitLFS.Repository.open(tempRepoPath)); + }); + }); - // We are testing the returned value in the specific branch test, because the test repo's - // `master` branch doesn't have LFS enabled by default - return NodeGitLFS.LFS.clone( - `${lfsTestRemotePath} ${tempRepoPath}`, - testReposPath, - { - env: { - GIT_SSL_NO_VERIFY: 1 - } - } - ) - .then(() => NodeGitLFS.Repository.open(tempRepoPath)); - }); + describe('when a branch is provided', () => { + it('clones a repo at the provided branch', function () { + const { + NodeGitLFS + } = this; + + const branchName = 'other-branch'; + + return populateRemoteBranch(branchName) + .then(() => NodeGitLFS.LFS.clone( + // https://github.com/git-lfs/git-lfs/issues/2523 + `${lfsTestRemotePath} ${tempRepoPath}`, + testReposPath, + { + branch: branchName, + env: { + GIT_SSL_NO_VERIFY: 1 + } + } + )) + .then((result) => { + expect(result.clone).to.eql({ + total_bytes: '24 B', + total_bytes_cloned: '24 B', + total_bytes_skipped: BAD_REGEX_PARSE_RESULT, + total_files_cloned: '1', + total_files_skipped: BAD_REGEX_PARSE_RESULT + }); + }) + .then(() => NodeGitLFS.Repository.open(tempRepoPath)) + .then(repo => repo.getCurrentBranch()) + .then((branch) => { + expect(branch.shorthand()).to.equal(branchName); + }); + }).timeout(10000); + }); - it('should clone a repo at a specific branch', function () { - const { - NodeGitLFS - } = this; + it('allows the environment to be customized', function () { + const { + NodeGitLFS, + sandbox + } = this; - const branchName = 'other-branch'; + const cloneStub = sandbox.stub(core, 'clone').returns(Promise.resolve({})); - return populateRemoteBranch(branchName) - .then(() => NodeGitLFS.LFS.clone( - // https://github.com/git-lfs/git-lfs/issues/2523 - `${lfsTestRemotePath} ${tempRepoPath}`, + NodeGitLFS.LFS.clone( + lfsTestRemotePath, testReposPath, { - branch: branchName, env: { - GIT_SSL_NO_VERIFY: 1 + foo: 'bar' } } - )) - .then((result) => { - expect(result.clone).to.eql({ - total_bytes: '24 B', - total_bytes_cloned: '24 B', - total_bytes_skipped: BAD_REGEX_PARSE_RESULT, - total_files_cloned: '1', - total_files_skipped: BAD_REGEX_PARSE_RESULT - }); - }) - .then(() => NodeGitLFS.Repository.open(tempRepoPath)) - .then(repo => repo.getCurrentBranch()) - .then((branch) => { - expect(branch.shorthand()).to.equal(branchName); - }); - }).timeout(10000); - - it('should allow the environment to be customized', function () { - const { - NodeGitLFS, - sandbox - } = this; - - const cloneStub = sandbox.stub(core, 'clone').returns(Promise.resolve({})); - - NodeGitLFS.LFS.clone( - lfsTestRemotePath, - testReposPath, - { + ); + expect(cloneStub).to.have.been.calledWithMatch(`${lfsTestRemotePath} `, { + cwd: testReposPath, env: { foo: 'bar' } - } - ); - expect(cloneStub).to.have.been.calledWithMatch(`${lfsTestRemotePath} `, { - cwd: testReposPath, - env: { - foo: 'bar' - } + }); }); - }); - it('should pass a callback through into `spawn`', function () { - const { - NodeGitLFS, - sandbox - } = this; + it('passes a provided callback through into `spawn`', function () { + const { + NodeGitLFS, + sandbox + } = this; - const callback = () => { }; + const callback = () => { }; - const cloneStub = sandbox.stub(core, 'clone').returns(Promise.resolve({})); + const cloneStub = sandbox.stub(core, 'clone').returns(Promise.resolve({})); - NodeGitLFS.LFS.clone(lfsTestRemotePath, testReposPath, { callback }); - expect(cloneStub.firstCall.args[2]).to.equal(callback); - }); + NodeGitLFS.LFS.clone(lfsTestRemotePath, testReposPath, { callback }); + expect(cloneStub.firstCall.args[2]).to.equal(callback); + }); - it('requires the repository URL to be passed in', function () { - const { - NodeGitLFS - } = this; + it('requires the repository URL to be provided', function () { + const { + NodeGitLFS + } = this; - try { - NodeGitLFS.LFS.clone( - null, - testReposPath - ); + try { + NodeGitLFS.LFS.clone( + null, + testReposPath + ); - fail('This should throw an error!'); - } catch (e) { - expect(e.message).to.equal('A valid URL and working directory are required'); - } - }); + fail('This should throw an error!'); + } catch (e) { + expect(e.message).to.equal('A valid URL and working directory are required'); + } + }); - it('requires the directory to clone into to be passed in', function () { - const { - NodeGitLFS - } = this; + it('requires the directory to clone into to be provided', function () { + const { + NodeGitLFS + } = this; - try { - NodeGitLFS.LFS.clone( - lfsTestRemotePath, - null - ); + try { + NodeGitLFS.LFS.clone( + lfsTestRemotePath, + null + ); - fail('This should throw an error!'); - } catch (e) { - expect(e.message).to.equal('A valid URL and working directory are required'); - } - }); + fail('This should throw an error!'); + } catch (e) { + expect(e.message).to.equal('A valid URL and working directory are required'); + } + }); - it('should return an appropriate result on error', todo); + it('handles errors', todo); + }); }); diff --git a/test/tests/commands/lfsCommands.spec.js b/test/tests/commands/lfsCommands.spec.js index 4ef31a9..f507d5d 100644 --- a/test/tests/commands/lfsCommands.spec.js +++ b/test/tests/commands/lfsCommands.spec.js @@ -3,37 +3,73 @@ import { } from '../../utils'; describe('lfsCommands', () => { - it('can run `git lfs checkout`', todo); - - it('can run `git lfs clone`', todo); - - it('can run `git lfs fetch`', todo); - - it('can run `git lfs fsck`', todo); - - it('can run any `git` command', todo); - - it('can run `git lfs install`', todo); - - it('can run `git lfs logs`', todo); - - it('can run `git lfs ls-files`', todo); - - it('can run `git lfs pointer`', todo); - - it('can run `git lfs prune`', todo); - - it('can run `git lfs pull`', todo); - - it('can run `git lfs push`', todo); - - it('can run `git lfs status`', todo); - - it('can run `git lfs track`', todo); - - it('can run `git lfs untrack`', todo); - - it('can run `git lfs update`', todo); - - it('can run `git lfs version`', todo); + describe('core', () => { + describe('checkout', () => { + it('runs `git lfs checkout`', todo); + }); + + describe('clone', () => { + it('can run `git lfs clone`', todo); + }); + + describe('fetch', () => { + it('can run `git lfs fetch`', todo); + }); + + describe('fsck', () => { + it('can run `git lfs fsck`', todo); + }); + + describe('git', () => { + it('can run any `git` command', todo); + }); + + describe('install', () => { + it('can run `git lfs install`', todo); + }); + + describe('logs', () => { + it('can run `git lfs logs`', todo); + }); + + describe('ls', () => { + it('can run `git lfs ls-files`', todo); + }); + + describe('pointer', () => { + it('can run `git lfs pointer`', todo); + }); + + describe('prune', () => { + it('can run `git lfs prune`', todo); + }); + + describe('pull', () => { + it('can run `git lfs pull`', todo); + }); + + describe('push', () => { + it('can run `git lfs push`', todo); + }); + + describe('status', () => { + it('can run `git lfs status`', todo); + }); + + describe('track', () => { + it('can run `git lfs track`', todo); + }); + + describe('untrack', () => { + it('can run `git lfs untrack`', todo); + }); + + describe('update', () => { + it('can run `git lfs update`', todo); + }); + + describe('version', () => { + it('can run `git lfs version`', todo); + }); + }); }); diff --git a/test/tests/commands/ls.spec.js b/test/tests/commands/ls.spec.js index 6e1cdf3..ed7cd69 100644 --- a/test/tests/commands/ls.spec.js +++ b/test/tests/commands/ls.spec.js @@ -2,10 +2,12 @@ import { todo } from '../../utils'; -describe('ls-files', () => { - it('builds args from the provided options', todo); +describe('ls', () => { + describe('the default export', () => { + it('builds args from the provided options', todo); - it('can list LFS-tracked files in the provided repo', todo); + it('lists LFS-tracked files in the provided repo', todo); - it('returns the correct response on error', todo); + it('handles errors', todo); + }); }); diff --git a/test/tests/commands/pointer.spec.js b/test/tests/commands/pointer.spec.js index 600ec0f..6e82f30 100644 --- a/test/tests/commands/pointer.spec.js +++ b/test/tests/commands/pointer.spec.js @@ -2,10 +2,12 @@ import { todo } from '../../utils'; -describe('Pointer', () => { - it('creates args from provided file and pointer paths', todo); +describe('pointer', () => { + describe('the default export', () => { + it('creates args from the provided file and pointer paths', todo); - it('can build a pointer', todo); + it('builds a pointer', todo); - it('responds appropriately on error', todo); + it('handles errors', todo); + }); }); diff --git a/test/tests/commands/prune.spec.js b/test/tests/commands/prune.spec.js index 08773d4..c05638e 100644 --- a/test/tests/commands/prune.spec.js +++ b/test/tests/commands/prune.spec.js @@ -2,8 +2,10 @@ import { todo } from '../../utils'; -describe('Prune', () => { - it('can prune the provided repository', todo); +describe('prune', () => { + describe('the default export', () => { + it('prunes the provided repository', todo); - it('responds appropriately on error', todo); + it('handles errors', todo); + }); }); diff --git a/test/tests/commands/push.spec.js b/test/tests/commands/push.spec.js index d2daab3..b067f86 100644 --- a/test/tests/commands/push.spec.js +++ b/test/tests/commands/push.spec.js @@ -2,8 +2,20 @@ import { todo } from '../../utils'; -describe('Push', () => { - it('defaults to the current branch and its upstream', todo); +describe('push', () => { + describe('the default export', () => { + describe('when not provided a remote', () => { + it('defaults to the current branch and its upstream', todo); + }); - it('responds appropriately on error', todo); + describe('when provided a remote', () => { + describe('when provided a branch', () => { + it('pushes', todo); + }); + + describe('when not provided a branch', () => { + it('pushes', todo); + }); + }); + }); }); diff --git a/test/tests/commands/track.spec.js b/test/tests/commands/track.spec.js index 99b5633..d997918 100644 --- a/test/tests/commands/track.spec.js +++ b/test/tests/commands/track.spec.js @@ -2,10 +2,12 @@ import { todo } from '../../utils'; -describe('Track', () => { - it('requires globs to be provided', todo); +describe('track', () => { + describe('the default export', () => { + it('tracks the provided globs', todo); - it('can track files', todo); + it('requires globs to be provided', todo); - it('responds appropriately on error', todo); + it('handles errors', todo); + }); }); diff --git a/test/tests/commands/untrack.spec.js b/test/tests/commands/untrack.spec.js index f265699..2b1fa52 100644 --- a/test/tests/commands/untrack.spec.js +++ b/test/tests/commands/untrack.spec.js @@ -2,10 +2,12 @@ import { todo } from '../../utils'; -describe('Untrack', () => { - it('requires globs to be provided', todo); +describe('untrack', () => { + describe('the default export', () => { + it('untracks the provided, currently-tracked globs', todo); - it('can untrack currently-tracked files', todo); + it('requires globs to be provided', todo); - it('responds appropriately on error', todo); + it('handles errors', todo); + }); }); diff --git a/test/tests/commands/version.spec.js b/test/tests/commands/version.spec.js deleted file mode 100644 index 1d25f27..0000000 --- a/test/tests/commands/version.spec.js +++ /dev/null @@ -1,21 +0,0 @@ -import { - lfsTestRepoPath -} from '../../constants'; - -import { - todo -} from '../../utils'; - -import version from '../../../build/src/commands/version'; - -describe('Version', () => { - it('does provide version number', function () { - const { - NodeGitLFS - } = this; - - return NodeGitLFS.Repository.open(lfsTestRepoPath) - .then(repo => version(repo)) - .then(() => todo()); - }); -}); diff --git a/test/tests/constants.spec.js b/test/tests/constants.spec.js index a3eead1..9ea9512 100644 --- a/test/tests/constants.spec.js +++ b/test/tests/constants.spec.js @@ -2,26 +2,42 @@ import { todo } from '../utils'; -describe('Constants', () => { - describe('Regexes', () => { - it('GIT', todo); - - it('LFS', todo); - - it('PASSWORD', todo); - - it('SKIPPED_BYTES', todo); - - it('SKIPPED_FILES', todo); - - it('TOTAL_BYTES', todo); - - it('TOTAL_FILES', todo); - - it('TRACK', todo); - - it('USERNAME', todo); - - it('VERSION', todo); +describe('constants', () => { + describe('regex', () => { + describe('GIT', () => { + it('parses `git` version output', todo); + }); + + describe('LFS', () => { + it('parses `git-lfs` version output', todo); + }); + + describe('PASSWORD', () => { + it('parses a password prompt', todo); + }); + + describe('SKIPPED_BYTES', () => { + it('matches the number of skipped bytes in `git-lfs` output', todo); + }); + + describe('SKIPPED_FILES', () => { + it('matches the number of skipped files in `git-lfs` output', todo); + }); + + describe('TOTAL_BYTES', () => { + it('matches the number of total bytes in `git-lfs` output', todo); + }); + + describe('TOTAL_FILES', () => { + it('matches the number of total files in `git-lfs` output', todo); + }); + + describe('TRACK', () => { + it('matches a glob in `git-lfs-track` or `git-lfs-untrack` output', todo); + }); + + it('USERNAME', () => { + it('parses a username prompt', todo); + }); }); }); diff --git a/test/tests/helpers.spec.js b/test/tests/helpers.spec.js index 7ebe5a2..cc96747 100644 --- a/test/tests/helpers.spec.js +++ b/test/tests/helpers.spec.js @@ -4,58 +4,33 @@ import { import path from 'path'; import { - emptyRepoPath, - lfsTestRepoPath -} from '../constants'; -import { - fail + fail, + todo } from '../utils'; import * as helpers from '../../build/src/helpers'; import track from '../../build/src/commands/track'; describe('helpers', () => { - beforeEach(function () { - const { - NodeGitLFS - } = this; - - return NodeGitLFS.Repository.open(lfsTestRepoPath) - .then((repo) => { - this.repo = repo; - }); - }); - describe('getGitattributesPathFromRepo', () => { - beforeEach(function () { - const { - NodeGitLFS - } = this; - - return NodeGitLFS.Repository.open(lfsTestRepoPath) - .then((repo) => { - this.repo = repo; - }); - }); - it("gets the location of a repository's `.gitattributes` file", function () { const { - repo + lfsTestRepo } = this; - expect(helpers.getGitattributesPathFromRepo(repo)) - .to.equal(path.join(lfsTestRepoPath, '.gitattributes')); + expect(helpers.getGitattributesPathFromRepo(lfsTestRepo)) + .to.equal(path.join(lfsTestRepo.workdir(), '.gitattributes')); }); }); describe('loadGitattributeFiltersFromRepo', () => { it('reads globs from `.gitattributes`', function () { const { - repo + lfsTestRepo } = this; - return track(repo, ['*.md', 'test.txt']) - .then(() => helpers.loadGitattributeFiltersFromRepo(repo)) + return track(lfsTestRepo, ['*.md', 'test.txt']) + .then(() => helpers.loadGitattributeFiltersFromRepo(lfsTestRepo)) .then((result) => { expect(result).to.have.members(['*.md', 'test.txt']); }); @@ -63,11 +38,10 @@ describe('helpers', () => { it('errors if `.gitattributes` does not exist', function () { const { - NodeGitLFS + emptyRepo } = this; - return NodeGitLFS.Repository.open(emptyRepoPath) - .then(repo => helpers.loadGitattributeFiltersFromRepo(repo)) + return helpers.loadGitattributeFiltersFromRepo(emptyRepo) .then(() => fail('Expected promise to fail!')) .catch((err) => { expect(err.message).to.equal('No .gitattributes found'); @@ -75,28 +49,33 @@ describe('helpers', () => { }); }); - describe('hasLfsFilters', () => { - it('returns `false` if the repo has no filters', function () { - const { - repo - } = this; + describe('repoHasLfsFilters', () => { + describe('when the provided repository has `.gitattributes` filters', () => { + it('returns `true`', todo); + }); - return helpers.hasLfsFilters(repo) - .then((result) => { - expect(result).to.be.false; - }); + describe('when the provided repository has no `.gitattributes` filters', () => { + it('returns `false`', todo); }); + }); - it('returns `true` if the repo has filters', function () { - const { - repo - } = this; + describe('repoHasLfsObjectBin', () => { + describe('when `.git/lfs` exists in the provided repository', () => { + it('returns `true`', todo); + }); - return track(repo, ['test.txt']) - .then(() => helpers.hasLfsFilters(repo)) - .then((result) => { - expect(result).to.be.true; - }); + describe('when `.git/lfs` does not exist in the provided repository', () => { + it('returns `false`', todo); + }); + }); + + describe('repoHasLfs', () => { + describe('when the provided repository does not have LFS support enabled', () => { + it('returns `true`', todo); + }); + + describe('when the provided repository has LFS support enabled', () => { + it('returns `false`', todo); }); }); }); diff --git a/test/tests/index.spec.js b/test/tests/index.spec.js index 08e7eb9..d9df918 100644 --- a/test/tests/index.spec.js +++ b/test/tests/index.spec.js @@ -22,35 +22,37 @@ import untrack from '../../build/src/commands/untrack'; import version from '../../build/src/commands/version'; import { loadGitattributeFiltersFromRepo, - hasLfsFilters + repoHasLfs } from '../../build/src/helpers'; import { dependencyCheck } from '../../build/src/utils/checkDependencies'; // NOTE These tests depend on `LFS(NodeGit)` being called in the global `beforeEach`. -describe('LFS', () => { - it('permanently adds itself to NodeGit', () => { - expect(NodeGit.LFS).to.eql({ - checkout, - clone, - core, - dependencyCheck, - fetch, - filters: loadGitattributeFiltersFromRepo, - hasLfsFilters, - initialize, - list, - NodeGit, - register, - testPointer, - track, - prune, - pull, - push, - version, - unregister, - untrack +describe('index', () => { + describe('the default export', () => { + it('adds LFS to NodeGit permanently', () => { + expect(NodeGit.LFS).to.eql({ + checkout, + clone, + core, + dependencyCheck, + fetch, + filters: loadGitattributeFiltersFromRepo, + initialize, + list, + NodeGit, + register, + repoHasLfs, + testPointer, + track, + prune, + pull, + push, + version, + unregister, + untrack + }); }); }); }); diff --git a/test/tests/initialize.spec.js b/test/tests/initialize.spec.js index 3fef37f..bff68d6 100644 --- a/test/tests/initialize.spec.js +++ b/test/tests/initialize.spec.js @@ -2,10 +2,16 @@ import { todo } from '../utils'; -describe('Initialize', () => { - it('correctly calculates arguments from options', todo); +describe('initialize', () => { + describe('the default export', () => { + it('correctly calculates arguments from options', todo); - it('initializes a non-LFS repo', todo); + describe('when provided a non-LFS repo', () => { + it('initializes the provided repo', todo); + }); - it('skips initializing on a repo that has already been initializing', todo); + describe('when provided an already-initialized repo', () => { + it('skips initialization', todo); + }); + }); }); diff --git a/test/tests/register.spec.js b/test/tests/register.spec.js index 9a1a2a8..343a256 100644 --- a/test/tests/register.spec.js +++ b/test/tests/register.spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -describe('Register', () => { +describe('register', () => { beforeEach(function () { const { NodeGitLFS @@ -11,33 +11,37 @@ describe('Register', () => { return NodeGitLFS.LFS.unregister(); }); - it('has register callback', function () { - const { - NodeGitLFS - } = this; + describe('the default export', () => { + it('registers the LFS filters', function () { + const { + NodeGitLFS + } = this; - return NodeGitLFS.LFS.register() - .then((result) => { - expect(result).to.be.a('number'); - expect(result).to.equal(0); - }); - }); + return NodeGitLFS.LFS.register() + .then((result) => { + expect(result).to.be.a('number'); + expect(result).to.equal(0); + }); + }); - it('cannot re-register LFS filter twice', function () { - const { - NodeGitLFS - } = this; + describe('when the LFS filters are already registered', () => { + it('errors', function () { + const { + NodeGitLFS + } = this; - return NodeGitLFS.LFS.register() - .then((result) => { - expect(result).to.be.a('number'); - expect(result).to.equal(0); - }) - .then(() => NodeGitLFS.LFS.register()) - .then(() => expect.fail('Failed to re-register')) - .catch((err) => { - expect(err.errno).to.be.a('number'); - expect(err.errno).to.equal(-4); + return NodeGitLFS.LFS.register() + .then((result) => { + expect(result).to.be.a('number'); + expect(result).to.equal(0); + }) + .then(() => NodeGitLFS.LFS.register()) + .then(() => expect.fail('Failed to re-register')) + .catch((err) => { + expect(err.errno).to.be.a('number'); + expect(err.errno).to.equal(-4); + }); }); + }); }); }); diff --git a/test/tests/unregister.spec.js b/test/tests/unregister.spec.js index 2a01da4..e3273cf 100644 --- a/test/tests/unregister.spec.js +++ b/test/tests/unregister.spec.js @@ -2,7 +2,7 @@ import { expect } from 'chai'; -describe('Unregister', () => { +describe('unregister', () => { afterEach(function () { const { NodeGitLFS @@ -12,30 +12,34 @@ describe('Unregister', () => { return NodeGitLFS.LFS.register(); }); - it('can unregister the LFS filter', function () { - const { + describe('the default export', () => { + it('unregisters the LFS filters', function () { + const { NodeGitLFS } = this; - return NodeGitLFS.LFS.unregister() - .then((result) => { - expect(result).to.equal(0); - }); - }); + return NodeGitLFS.LFS.unregister() + .then((result) => { + expect(result).to.equal(0); + }); + }); - it('cannot unregister the LFS filter twice', function () { - const { - NodeGitLFS - } = this; + describe('when the LFS filters are not registered', () => { + it('errors', function () { + const { + NodeGitLFS + } = this; - return NodeGitLFS.LFS.unregister() - .then((result) => { - expect(result).to.equal(0); - }) - .then(() => NodeGitLFS.LFS.unregister()) - .then(() => expect.fail('Failed to re-unregister!')) - .catch((err) => { - expect(err.errno).to.equal(-3); + return NodeGitLFS.LFS.unregister() + .then((result) => { + expect(result).to.equal(0); + }) + .then(() => NodeGitLFS.LFS.unregister()) + .then(() => expect.fail('Failed to re-unregister!')) + .catch((err) => { + expect(err.errno).to.equal(-3); + }); }); + }); }); }); diff --git a/test/tests/utils/checkDependencies.spec.js b/test/tests/utils/checkDependencies.spec.js deleted file mode 100644 index 09746e5..0000000 --- a/test/tests/utils/checkDependencies.spec.js +++ /dev/null @@ -1,73 +0,0 @@ -import { expect } from 'chai'; -import { todo } from '../../utils'; -import * as checker from '../../../src/utils/checkDependencies'; -import { regex, BAD_VERSION } from '../../../src/constants'; -import { core } from '../../../src/commands/lfsCommands'; - -describe('Depenendency Helpers', () => { - describe('parseVersion', () => { - it('parses the LFS version', () => { - const versionText = 'git-lfs/2.1.0 (GitHub; windows 386; go 1.8.1; git bd2c9987)'; - const version = checker.parseVersion(versionText, regex.LFS); - expect(version).to.equal('2.1.0'); - }); - - it('parses the Git version', () => { - const versionText = 'git version 2.13.0.windows.1'; - const version = checker.parseVersion(versionText, regex.GIT); - expect(version).to.equal('2.13.0'); - }); - - it('returns null when the regex matches nothing', () => { - const versionText = 'dsadsadas'; - const version = checker.parseVersion(versionText, regex.GIT); - expect(version).to.equal(BAD_VERSION); - }); - - it('returns null when the regex does not match numbers', () => { - const versionText = 'dsadsadas'; - const version = checker.parseVersion(versionText, /w+/); - expect(version).to.equal(BAD_VERSION); - }); - }); - - describe('isAtleastGitVersion', () => { - it('is at least version 2.0.0', () => { - expect(checker.isAtleastGitVersion('git version 2.13.0.windows.1')).to.be.true; - }); - - it('is not at least version 2.0.0', () => { - expect(checker.isAtleastGitVersion('git version 1.13.0.windows.1')).to.be.false; - }); - }); - - describe('isAtleastLfsVersion', () => { - it('is at least version 2.0.0', () => { - expect(checker.isAtleastLfsVersion('git-lfs/2.1.1')).to.be.true; - }); - - it('is not at least version 2.0.0', () => { - expect(checker.isAtleastLfsVersion('git-lfs/1.1.1')).to.be.false; - }); - }); - - describe('checkDependencies', () => { - it('check git version number is at least the minimum version', () => - core.git('--version') - .then(({ stdout }) => checker.isAtleastGitVersion(stdout)) - .then(result => expect(result).to.equal(true)) - .catch(() => expect.fail('sould not have done this'))); - - it('check LFS version number is at least the minimum version', () => - core.git('lfs version') - .then(({ stdout }) => checker.isAtleastLfsVersion(stdout)) - .then(result => expect(result).to.equal(true)) - .catch(() => expect.fail('sould not have done this'))); - }); - - describe('Dependency Check', () => { - it('generate valid response', () => - checker.dependencyCheck() - .then(() => todo())); - }); -}); diff --git a/test/tests/utils/execHelper.spec.js b/test/tests/utils/execHelper.spec.js index c2e5199..93c1716 100644 --- a/test/tests/utils/execHelper.spec.js +++ b/test/tests/utils/execHelper.spec.js @@ -11,7 +11,7 @@ import { import exec from '../../../src/utils/execHelper'; -describe('exec', () => { +describe('execHelper', () => { beforeEach(function () { this.sandbox = sinon.sandbox.create(); @@ -33,37 +33,51 @@ describe('exec', () => { sandbox.restore(); }); - it('resolves with the spawned process and its stdout and stderr on success', function () { - const { - execSpy, - mockProcess - } = this; + describe('the default export', () => { + it('resolves with the spawned process and its stdout and stderr on success', function () { + const { + execSpy, + mockProcess + } = this; - const promise = exec('test', { foo: 'bar' }); - execSpy.firstCall.args[2](null, 'some stdout', 'some stderr'); - return promise - .then((result) => { - expect(result).to.eql({ - proc: mockProcess, - stderr: 'some stderr', - stdout: 'some stdout' + const promise = exec('test', '', { foo: 'bar' }); + execSpy.firstCall.args[2](null, 'some stdout', 'some stderr'); + return promise + .then((result) => { + expect(result).to.eql({ + proc: mockProcess, + stderr: 'some stderr', + stdout: 'some stdout' + }); }); - }); - }); + }); - it('writes out provided input', todo); + it('allows the environment to be overwritten', todo); - it('rejects with the error on failure', function () { - const { - execSpy - } = this; + if (process.platform !== 'win32') { + describe('if `/usr/local/bin` is not on the `PATH`', () => { + it('adds `/usr/local/bin` to the `PATH`', todo); + }); - const promise = exec('test', { foo: 'bar' }); - execSpy.firstCall.args[2]('some error'); - return promise - .then(() => fail('Expected this promise to fail!')) - .catch((err) => { - expect(err).to.equal('some error'); + describe('if `/usr/local/bin` is already on the `PATH`', () => { + it('does not add `/usr/local/bin` twice', todo); }); + } + + it('writes out provided input', todo); + + it('rejects with the error on failure', function () { + const { + execSpy + } = this; + + const promise = exec('test', '', { foo: 'bar' }); + execSpy.firstCall.args[2]('some error'); + return promise + .then(() => fail('Expected this promise to fail!')) + .catch((err) => { + expect(err).to.equal('some error'); + }); + }); }); }); diff --git a/test/tests/utils/generateResponse.spec.js b/test/tests/utils/generateResponse.spec.js index f89795d..82bad4c 100644 --- a/test/tests/utils/generateResponse.spec.js +++ b/test/tests/utils/generateResponse.spec.js @@ -8,12 +8,14 @@ import { import generateResponse from '../../../build/src/utils/generateResponse'; describe('generateResponse', () => { - it('generates a default successful response', () => { - expect(generateResponse()).to.eql({ - success: true, - errno: Error.CODE.OK, - raw: '', - stderr: '' + describe('the default export', () => { + it('generates a default successful response', () => { + expect(generateResponse()).to.eql({ + success: true, + errno: Error.CODE.OK, + raw: '', + stderr: '' + }); }); }); }); diff --git a/test/tests/utils/spawnHelper.spec.js b/test/tests/utils/spawnHelper.spec.js index da2a1d6..f1cee88 100644 --- a/test/tests/utils/spawnHelper.spec.js +++ b/test/tests/utils/spawnHelper.spec.js @@ -5,7 +5,7 @@ import { todo } from '../../utils'; -describe('Spawn Helpers', () => { +describe('spawnHelper', () => { beforeEach(function () { this.sandbox = sinon.sandbox.create(); @@ -34,7 +34,7 @@ describe('Spawn Helpers', () => { sandbox.restore(); }); - describe('spawn', () => { + describe('the default export', () => { it('defaults `opts` to `{}`', todo); it("merges the calling process' env into the provided env", todo); From b89bdd05983ce949aef047e8d5183b136b5e8b96 Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Thu, 31 Aug 2017 10:29:02 -0700 Subject: [PATCH 35/42] Standardize error-handling logic --- src/commands/checkout.js | 3 +-- src/commands/clone.js | 11 +++++------ src/commands/fetch.js | 6 ++---- src/commands/ls.js | 7 ++++--- src/commands/pointer.js | 4 ++-- src/commands/prune.js | 9 +++------ src/commands/pull.js | 6 ++---- src/commands/push.js | 12 +++++------- src/commands/track.js | 4 ++-- src/commands/untrack.js | 4 ++-- src/commands/version.js | 9 ++++----- src/helpers.js | 13 ++++++++----- 12 files changed, 40 insertions(+), 48 deletions(-) diff --git a/src/commands/checkout.js b/src/commands/checkout.js index ed1f506..7194508 100644 --- a/src/commands/checkout.js +++ b/src/commands/checkout.js @@ -61,10 +61,9 @@ const generateCheckoutStats = (raw) => { }; function checkout(repo, callback) { - const response = generateResponse(); - return core.checkout('', { cwd: repo.workdir() }, callback) .then(({ stdout }) => { + const response = generateResponse(); response.raw = stdout; response.checkout = generateCheckoutStats(stdout); diff --git a/src/commands/clone.js b/src/commands/clone.js index 72fb81b..ba428ed 100644 --- a/src/commands/clone.js +++ b/src/commands/clone.js @@ -70,13 +70,12 @@ function clone(url, cwd, options) { } = (options || {}); const args = branch ? `-b ${branch}` : ''; - const response = generateResponse(); return core.clone(`${url} ${args}`, { cwd, env }, callback) - .then(({ stdout }) => { - response.raw = stdout; - response.clone = generateCloneStats(stdout); - return response; - }, errorCatchHandler(response)); + .then(({ stdout }) => ({ + ...generateResponse(), + raw: stdout, + clone: generateCloneStats(stdout) + }), errorCatchHandler); } export default clone; diff --git a/src/commands/fetch.js b/src/commands/fetch.js index 7954353..8a4429f 100644 --- a/src/commands/fetch.js +++ b/src/commands/fetch.js @@ -60,8 +60,6 @@ const generateFetchStats = (raw) => { }; function fetch(repo, options) { - const response = generateResponse(); - const args = []; const { remoteName, @@ -84,9 +82,9 @@ function fetch(repo, options) { response.fetch = generateFetchStats(stdout); if (response.fetch.fetch_error) { - response.success = false; - response.stderr = response.fetch.fetch_error; response.errno = BAD_CORE_RESPONSE; + response.stderr = response.fetch.fetch_error; + response.success = false; } return response; diff --git a/src/commands/ls.js b/src/commands/ls.js index e66ae0c..f8ed839 100644 --- a/src/commands/ls.js +++ b/src/commands/ls.js @@ -47,17 +47,18 @@ const buildArgs = (options) => { }; const ls = (repo, options) => { - const response = generateResponse(); const args = buildArgs(options); return core.ls(args, { cwd: repo.workdir() }) .then(({ stdout, stderr }) => { + const response = generateResponse(); response.raw = stdout; - if (stderr.length > 0) { + if (stderr) { + response.errno = BAD_CORE_RESPONSE; response.stderr = stderr; response.success = false; - response.errno = BAD_CORE_RESPONSE; + return response; } response.files = extractFileNames(stdout); diff --git a/src/commands/pointer.js b/src/commands/pointer.js index 28849d9..e75754d 100644 --- a/src/commands/pointer.js +++ b/src/commands/pointer.js @@ -13,16 +13,16 @@ const pointer = (repo, filePath, pointerPath) => { args += `--file=${pointerPath} `; } - const response = generateResponse(); return core.pointer(args, { cwd: repo.workdir() }) .then(({ stdout, stderr }) => { + const response = generateResponse(); response.raw = stdout; if (stderr) { - response.success = false; response.errno = BAD_CORE_RESPONSE; response.stderr = stderr; + response.success = false; return response; } diff --git a/src/commands/prune.js b/src/commands/prune.js index ad28e02..f7d772f 100644 --- a/src/commands/prune.js +++ b/src/commands/prune.js @@ -2,22 +2,19 @@ import { core } from './lfsCommands'; import generateResponse from '../utils/generateResponse'; import { BAD_CORE_RESPONSE } from '../constants'; -const prune = (repo, args) => { - const response = generateResponse(); - - return core.prune(args, { cwd: repo.workdir() }) +const prune = (repo, args) => + core.prune(args, { cwd: repo.workdir() }) .then(({ stdout, stderr }) => { + const response = generateResponse(); response.raw = stdout; if (stderr) { response.errno = BAD_CORE_RESPONSE; response.stderr = stderr; response.success = false; - return response; } return response; }); -}; export default prune; diff --git a/src/commands/pull.js b/src/commands/pull.js index 230f718..5002584 100644 --- a/src/commands/pull.js +++ b/src/commands/pull.js @@ -60,8 +60,6 @@ const generatePullStats = (raw) => { }; function pull(repo, options) { - const response = generateResponse(); - const args = []; const { remoteName, @@ -83,9 +81,9 @@ function pull(repo, options) { response.pull = generatePullStats(stdout); if (response.pull.pull_error) { - response.success = false; - response.stderr = response.pull.pull_error; response.errno = BAD_CORE_RESPONSE; + response.stderr = response.pull.pull_error; + response.success = false; } return response; diff --git a/src/commands/push.js b/src/commands/push.js index e3b75ce..26fceed 100644 --- a/src/commands/push.js +++ b/src/commands/push.js @@ -62,8 +62,6 @@ const generatePushStats = (raw) => { }; function push(repo, options) { - const response = generateResponse(); - const { remoteName, branchName, @@ -96,11 +94,11 @@ function push(repo, options) { return getRemoteAndBranchPromise .then(() => core.push(`${remote} ${branch}`, { cwd: repo.path() }, callback)) - .then(({ stdout }) => { - response.raw = stdout; - response.push = generatePushStats(stdout); - return response; - }, errorCatchHandler(response)); + .then(({ stdout }) => ({ + ...generateResponse(), + push: generatePushStats(stdout), + raw: stdout + }), errorCatchHandler); } export default push; diff --git a/src/commands/track.js b/src/commands/track.js index 36ae9c3..f4f0fc6 100644 --- a/src/commands/track.js +++ b/src/commands/track.js @@ -22,16 +22,16 @@ const track = (repo, globs) => { R.filter(isString), R.map(g => `${ticks}${g}${ticks}`) )(globs); - const response = generateResponse(); return core.track(R.join(' ', filteredGlobs), { cwd: repo.workdir() }) .then(({ stdout, stderr }) => { + const response = generateResponse(); response.raw = stdout; if (stderr) { - response.success = false; response.errno = BAD_CORE_RESPONSE; response.stderr = stderr; + response.success = false; return response; } diff --git a/src/commands/untrack.js b/src/commands/untrack.js index b4b4f04..a87b3b1 100644 --- a/src/commands/untrack.js +++ b/src/commands/untrack.js @@ -22,16 +22,16 @@ const untrack = (repo, globs) => { R.filter(isString), R.map(g => `${ticks}${g}${ticks}`) )(globs); - const response = generateResponse(); return core.untrack(R.join(' ', filteredGlobs), { cwd: repo.workdir() }) .then(({ stdout, stderr }) => { + const response = generateResponse(); response.raw = stdout; if (stderr) { - response.success = false; response.errno = BAD_CORE_RESPONSE; response.stderr = stderr; + response.success = false; return response; } diff --git a/src/commands/version.js b/src/commands/version.js index 7d487d8..78cb0a6 100644 --- a/src/commands/version.js +++ b/src/commands/version.js @@ -7,21 +7,20 @@ import { import generateResponse from '../utils/generateResponse'; const version = () => { - const response = generateResponse(); return core.version() .then(({ stdout, stderr }) => { + const response = generateResponse(); response.raw = stdout; if (stderr) { + response.errno = BAD_CORE_RESPONSE; response.stderr = stderr; response.success = false; - response.errno = BAD_CORE_RESPONSE; - } else { - response.version = parseVersion(stdout, regex.LFS); + return response; } + response.version = parseVersion(stdout, regex.LFS); return response; }); -}; export default version; diff --git a/src/helpers.js b/src/helpers.js index 2c4870f..123733b 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -8,6 +8,7 @@ import { BAD_REGEX_PARSE_RESULT, regex, } from './constants'; +import generateResponse from './utils/generateResponse'; export const getGitattributesPathFromRepo = repo => path.join(repo.workdir(), '.gitattributes'); @@ -74,13 +75,15 @@ export const verifyOutput = (stats, raw) => { } }; -export const errorCatchHandler = response => (code) => { +export const errorCatchHandler = (code) => { // This is a manually detected error we get from LFS if (code === BAD_CORE_RESPONSE) { - response.stderr = response.raw; - response.errno = BAD_CORE_RESPONSE; - response.success = false; - return response; + return { + ...generateResponse(), + errno: BAD_CORE_RESPONSE, + stderr: '', + success: false + }; } throw code; From db59e7a2003852fba29499d0ea9321fffa1bacdd Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Thu, 31 Aug 2017 14:28:37 -0700 Subject: [PATCH 36/42] Kill LFS test server on unhandled Promise rejection in specs --- test/runner.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/runner.js b/test/runner.js index d23514a..983f0cd 100644 --- a/test/runner.js +++ b/test/runner.js @@ -23,6 +23,13 @@ import * as testLFSServer from './server/server'; // http://eng.wealthfront.com/2016/11/03/handling-unhandledrejections-in-node-and-the-browser/ process.on('unhandledRejection', (err) => { console.error('CAUGHT ERROR:', err); // eslint-disable-line no-console + + try { + testLFSServer.stop(); + } catch (e) { + // The server may not have been started yet + } + process.exit(1); }); From f132bd71c639d544fcb0555a9c1f86746b167a2f Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Thu, 31 Aug 2017 15:03:20 -0700 Subject: [PATCH 37/42] Adjust for rebase-caused changes --- src/commands/fetch.js | 3 ++- src/commands/pull.js | 3 ++- src/commands/version.js | 4 ++-- src/utils/execHelper.js | 4 ++-- test/tests/helpers.spec.js | 30 ++++++++++++++++++++--------- test/tests/utils/execHelper.spec.js | 2 +- 6 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src/commands/fetch.js b/src/commands/fetch.js index 8a4429f..fceb039 100644 --- a/src/commands/fetch.js +++ b/src/commands/fetch.js @@ -78,6 +78,7 @@ function fetch(repo, options) { const argsString = R.join(' ', args); return core.fetch(argsString, { cwd: repo.workdir(), shell: true }, callback) .then(({ stdout }) => { + const response = generateResponse(); response.raw = stdout; response.fetch = generateFetchStats(stdout); @@ -88,7 +89,7 @@ function fetch(repo, options) { } return response; - }, errorCatchHandler(response)); + }, errorCatchHandler); } export default fetch; diff --git a/src/commands/pull.js b/src/commands/pull.js index 5002584..8b13d58 100644 --- a/src/commands/pull.js +++ b/src/commands/pull.js @@ -77,6 +77,7 @@ function pull(repo, options) { return core.pull(argsString, { cwd: repo.workdir(), shell: true }, callback) .then(({ stdout }) => { + const response = generateResponse(); response.raw = stdout; response.pull = generatePullStats(stdout); @@ -87,7 +88,7 @@ function pull(repo, options) { } return response; - }, errorCatchHandler(response)); + }, errorCatchHandler); } export default pull; diff --git a/src/commands/version.js b/src/commands/version.js index 78cb0a6..ba271ea 100644 --- a/src/commands/version.js +++ b/src/commands/version.js @@ -6,8 +6,8 @@ import { } from '../constants'; import generateResponse from '../utils/generateResponse'; -const version = () => { - return core.version() +const version = () => + core.version() .then(({ stdout, stderr }) => { const response = generateResponse(); response.raw = stdout; diff --git a/src/utils/execHelper.js b/src/utils/execHelper.js index 607cd1a..e6454d1 100644 --- a/src/utils/execHelper.js +++ b/src/utils/execHelper.js @@ -1,9 +1,9 @@ import child from 'child_process'; import R from 'ramda'; -const exec = (command, input, opts) => new Promise( +const exec = (command, input, opts = {}) => new Promise( (resolve, reject) => { - const options = R.mergeDeepRight((opts || {}), { env: process.env }); + const options = R.mergeDeepRight(opts, { env: process.env }); if (process.platform !== 'win32' && !R.contains('/usr/local/bin', options.env.PATH)) { options.env.PATH = `${options.env.PATH}${':/usr/local/bin'}`; diff --git a/test/tests/helpers.spec.js b/test/tests/helpers.spec.js index cc96747..0a47df3 100644 --- a/test/tests/helpers.spec.js +++ b/test/tests/helpers.spec.js @@ -36,16 +36,18 @@ describe('helpers', () => { }); }); - it('errors if `.gitattributes` does not exist', function () { - const { - emptyRepo - } = this; + describe('when `.gitattributes` does not exist', () => { + it('errors', function () { + const { + emptyRepo + } = this; - return helpers.loadGitattributeFiltersFromRepo(emptyRepo) - .then(() => fail('Expected promise to fail!')) - .catch((err) => { - expect(err.message).to.equal('No .gitattributes found'); - }); + return helpers.loadGitattributeFiltersFromRepo(emptyRepo) + .then(() => fail('Expected promise to fail!')) + .catch((err) => { + expect(err.message).to.equal('No .gitattributes found'); + }); + }); }); }); @@ -78,4 +80,14 @@ describe('helpers', () => { it('returns `false`', todo); }); }); + + describe('errorCatchHandler', () => { + describe('when the error is from LFS', () => { + it('returns a response object', todo); + }); + + describe('when the error is not from LFS', () => { + it('rethrows the error code', todo); + }); + }); }); diff --git a/test/tests/utils/execHelper.spec.js b/test/tests/utils/execHelper.spec.js index 93c1716..5656759 100644 --- a/test/tests/utils/execHelper.spec.js +++ b/test/tests/utils/execHelper.spec.js @@ -40,7 +40,7 @@ describe('execHelper', () => { mockProcess } = this; - const promise = exec('test', '', { foo: 'bar' }); + const promise = exec('test', ''); execSpy.firstCall.args[2](null, 'some stdout', 'some stderr'); return promise .then((result) => { From 8a70b3de4b807898da0db89d64ac9aee8a7dfb76 Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Fri, 1 Sep 2017 08:36:14 -0700 Subject: [PATCH 38/42] Remove unnecessary `branchName` option from the `pull` command `git-lfs-pull`'s manpage says "Download all Git LFS files for current ref & checkout", and I don't see any options to pull a specific branch's files. My guess is that this code was copy-and-pasted from the `fetch` command, explaining the extraneous argument. Also, this commit has test stubs for the `fetch` and `pull` commands. --- src/commands/pull.js | 4 ---- test/tests/commands/fetch.spec.js | 27 +++++++++++++++++++++++++++ test/tests/commands/pull.spec.js | 23 +++++++++++++++++++++++ 3 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 test/tests/commands/fetch.spec.js create mode 100644 test/tests/commands/pull.spec.js diff --git a/src/commands/pull.js b/src/commands/pull.js index 8b13d58..3a09d2e 100644 --- a/src/commands/pull.js +++ b/src/commands/pull.js @@ -63,16 +63,12 @@ function pull(repo, options) { const args = []; const { remoteName, - branchName, callback } = (options || {}); if (remoteName) { args.push(remoteName); } - if (branchName) { - args.push(branchName); - } const argsString = R.join(' ', args); return core.pull(argsString, { cwd: repo.workdir(), shell: true }, callback) diff --git a/test/tests/commands/fetch.spec.js b/test/tests/commands/fetch.spec.js new file mode 100644 index 0000000..83cee7a --- /dev/null +++ b/test/tests/commands/fetch.spec.js @@ -0,0 +1,27 @@ +import { + todo +} from '../../utils'; + +describe('fetch', () => { + describe('the default export', () => { + it('runs fetch in the provided repo', todo); + + describe('when a remote name is provided', () => { + it('adds the provided remote name to the arguments', todo); + }); + + describe('when a remote name and a branch name are provided', () => { + it('adds the provided remote name and branch name to the arguments', todo); + }); + + describe('when a callback is provided', () => { + it('passes the provided callback to `spawn`', todo); + }); + + describe('when fetch returns invalid output', () => { + it('returns an error response', todo); + }); + + it('handles errors', todo); + }); +}); diff --git a/test/tests/commands/pull.spec.js b/test/tests/commands/pull.spec.js new file mode 100644 index 0000000..66513b8 --- /dev/null +++ b/test/tests/commands/pull.spec.js @@ -0,0 +1,23 @@ +import { + todo +} from '../../utils'; + +describe('pull', () => { + describe('the default export', () => { + it('runs pull in the provided repo', todo); + + describe('when a remote name is provided', () => { + it('adds the provided remote name to the arguments', todo); + }); + + describe('when a callback is provided', () => { + it('passes the provided callback to `spawn`', todo); + }); + + describe('when fetch returns invalid output', () => { + it('returns an error response', todo); + }); + + it('handles errors', todo); + }); +}); From 81521018fd049872303d55d42d2904f71f0e2b39 Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Tue, 5 Sep 2017 14:39:28 -0700 Subject: [PATCH 39/42] Add `errorCatchHandler` spec stubs --- test/tests/helpers.spec.js | 98 ++++++++++++++++++++++++++++---------- 1 file changed, 73 insertions(+), 25 deletions(-) diff --git a/test/tests/helpers.spec.js b/test/tests/helpers.spec.js index 0a47df3..ee283d0 100644 --- a/test/tests/helpers.spec.js +++ b/test/tests/helpers.spec.js @@ -1,6 +1,7 @@ import { expect } from 'chai'; +import fse from 'fs-extra'; import path from 'path'; import { @@ -8,17 +9,32 @@ import { todo } from '../utils'; -import * as helpers from '../../build/src/helpers'; +import { + getGitattributesPathFromRepo, + loadGitattributeFiltersFromRepo, + repoHasLfsFilters, + repoHasLfsObjectBin +} from '../../build/src/helpers'; import track from '../../build/src/commands/track'; describe('helpers', () => { + describe.only('errorCatchHandler', () => { + describe('when the error is from LFS', () => { + it('returns a response object', todo); + }); + + describe('when the error is not from LFS', () => { + it('rethrows the error code', todo); + }); + }); + describe('getGitattributesPathFromRepo', () => { it("gets the location of a repository's `.gitattributes` file", function () { const { lfsTestRepo } = this; - expect(helpers.getGitattributesPathFromRepo(lfsTestRepo)) + expect(getGitattributesPathFromRepo(lfsTestRepo)) .to.equal(path.join(lfsTestRepo.workdir(), '.gitattributes')); }); }); @@ -30,7 +46,7 @@ describe('helpers', () => { } = this; return track(lfsTestRepo, ['*.md', 'test.txt']) - .then(() => helpers.loadGitattributeFiltersFromRepo(lfsTestRepo)) + .then(() => loadGitattributeFiltersFromRepo(lfsTestRepo)) .then((result) => { expect(result).to.have.members(['*.md', 'test.txt']); }); @@ -42,7 +58,7 @@ describe('helpers', () => { emptyRepo } = this; - return helpers.loadGitattributeFiltersFromRepo(emptyRepo) + return loadGitattributeFiltersFromRepo(emptyRepo) .then(() => fail('Expected promise to fail!')) .catch((err) => { expect(err.message).to.equal('No .gitattributes found'); @@ -51,43 +67,75 @@ describe('helpers', () => { }); }); - describe('repoHasLfsFilters', () => { - describe('when the provided repository has `.gitattributes` filters', () => { + describe('repoHasLfs', () => { + describe('when the provided repository does not have LFS support enabled', () => { it('returns `true`', todo); }); - describe('when the provided repository has no `.gitattributes` filters', () => { + describe('when the provided repository has LFS support enabled', () => { it('returns `false`', todo); }); }); - describe('repoHasLfsObjectBin', () => { - describe('when `.git/lfs` exists in the provided repository', () => { - it('returns `true`', todo); - }); + describe('repoHasLfsFilters', () => { + describe('when the provided repository has `.gitattributes` filters', () => { + it('returns `true`', function () { + const { + lfsTestRepo + } = this; - describe('when `.git/lfs` does not exist in the provided repository', () => { - it('returns `false`', todo); + return track(lfsTestRepo, ['*.md']) + .then(() => repoHasLfsFilters(lfsTestRepo)) + .then((result) => { + expect(result).to.be.true; + }); + }); }); - }); - describe('repoHasLfs', () => { - describe('when the provided repository does not have LFS support enabled', () => { - it('returns `true`', todo); - }); + describe('when the provided repository has no `.gitattributes` filters', () => { + it('returns `false`', function () { + const { + lfsTestRepo + } = this; - describe('when the provided repository has LFS support enabled', () => { - it('returns `false`', todo); + return repoHasLfsFilters(lfsTestRepo) + .then((result) => { + expect(result).to.be.false; + }); + }); }); }); - describe('errorCatchHandler', () => { - describe('when the error is from LFS', () => { - it('returns a response object', todo); + describe('repoHasLfsObjectBin', () => { + describe('when `.git/lfs` exists in the provided repository', () => { + it('returns `true`', function () { + const { + lfsTestRepo + } = this; + + return fse.mkdir(path.join(lfsTestRepo.path(), 'lfs')) + .then(() => repoHasLfsObjectBin(lfsTestRepo)) + .then((result) => { + expect(result).to.be.true; + }); + }); }); - describe('when the error is not from LFS', () => { - it('rethrows the error code', todo); + describe('when `.git/lfs` does not exist in the provided repository', () => { + it('returns `false`', function () { + const { + emptyRepo + } = this; + + return repoHasLfsObjectBin(emptyRepo) + .then((result) => { + expect(result).to.be.false; + }); + }); }); }); + + describe('verifyOutput', () => { + describe('when the provided stats ') + }); }); From 1aff4e50e5a84e6d3af589f67adb4fa2726e8fbd Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Tue, 5 Sep 2017 14:50:58 -0700 Subject: [PATCH 40/42] Update spec stubs (post-rebase) --- test/tests/constants.spec.js | 8 ++++++++ test/tests/helpers.spec.js | 12 +++++++++++- test/tests/utils/spawnHelper.spec.js | 18 +++++------------- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/test/tests/constants.spec.js b/test/tests/constants.spec.js index 9ea9512..5d3db00 100644 --- a/test/tests/constants.spec.js +++ b/test/tests/constants.spec.js @@ -12,10 +12,18 @@ describe('constants', () => { it('parses `git-lfs` version output', todo); }); + describe('PASSPHRASE', () => { + it('parses a passphrase prompt', todo); + }); + describe('PASSWORD', () => { it('parses a password prompt', todo); }); + describe('PERMISSION_DENIED', () => { + it('parses a permission denied error', todo); + }); + describe('SKIPPED_BYTES', () => { it('matches the number of skipped bytes in `git-lfs` output', todo); }); diff --git a/test/tests/helpers.spec.js b/test/tests/helpers.spec.js index ee283d0..5e0b608 100644 --- a/test/tests/helpers.spec.js +++ b/test/tests/helpers.spec.js @@ -136,6 +136,16 @@ describe('helpers', () => { }); describe('verifyOutput', () => { - describe('when the provided stats ') + describe('when no errors occurred', () => { + it('no-ops', todo); + }); + + describe('when all parses failed', () => { + it('throws', todo); + }); + + describe('when the provided input contains a permissions error', () => { + it('throws', todo); + }); }); }); diff --git a/test/tests/utils/spawnHelper.spec.js b/test/tests/utils/spawnHelper.spec.js index f1cee88..5a7395d 100644 --- a/test/tests/utils/spawnHelper.spec.js +++ b/test/tests/utils/spawnHelper.spec.js @@ -132,23 +132,15 @@ describe('spawnHelper', () => { describe('buildCredentialsCallbackProcess', () => { describe('when prompted for a username', () => { - describe('when a username has not been cached', () => { - it('calls the callback to obtain a username and password and writes the username out', todo); - }); - - describe('when the username has been cached', () => { - it('writes the cached username out', todo); - }); + it('calls the callback to obtain a username and writes it out', todo); }); describe('when prompted for a password', () => { - describe('when a password was provided by the callback', () => { - it('writes the password out', todo); - }); + it('calls the callback to obtain a password and writes it out', todo); + }); - describe('when a password was not provided by the callback', () => { - it('calls the callback to obtain a password only and writes the password out', todo); - }); + describe('when prompted for a passphrase', () => { + it('calls the callback to obtain a passphrase and writes it out', todo); }); it('allows the callback to cancel', todo); From deedc94e6de44eaef239adee5142cb7b3a23e6aa Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Tue, 5 Sep 2017 14:57:33 -0700 Subject: [PATCH 41/42] Remove unnecessary `nodegit` imports --- test/tests/callbacks/check.spec.js | 4 ++-- test/tests/callbacks/initialize.spec.js | 4 ++-- test/tests/utils/generateResponse.spec.js | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/tests/callbacks/check.spec.js b/test/tests/callbacks/check.spec.js index 1dc9057..c7e5100 100644 --- a/test/tests/callbacks/check.spec.js +++ b/test/tests/callbacks/check.spec.js @@ -1,10 +1,10 @@ import { expect } from 'chai'; + import { Error -} from 'nodegit'; - +} from '../../../build/src/constants'; import track from '../../../build/src/commands/track'; import checkCallback from '../../../build/src/callbacks/check'; diff --git a/test/tests/callbacks/initialize.spec.js b/test/tests/callbacks/initialize.spec.js index 913497d..893db65 100644 --- a/test/tests/callbacks/initialize.spec.js +++ b/test/tests/callbacks/initialize.spec.js @@ -1,10 +1,10 @@ import { expect } from 'chai'; + import { Error -} from 'nodegit'; - +} from '../../../build/src/constants'; import initialize from '../../../build/src/callbacks/initialize'; describe('initialize', () => { diff --git a/test/tests/utils/generateResponse.spec.js b/test/tests/utils/generateResponse.spec.js index 82bad4c..82a5d33 100644 --- a/test/tests/utils/generateResponse.spec.js +++ b/test/tests/utils/generateResponse.spec.js @@ -1,10 +1,10 @@ import { expect } from 'chai'; + import { Error -} from 'nodegit'; - +} from '../../../build/src/constants'; import generateResponse from '../../../build/src/utils/generateResponse'; describe('generateResponse', () => { From 2536e2bc8845e4e08ee5d1f9c4a0dce63e354f89 Mon Sep 17 00:00:00 2001 From: Joshua Grosso Date: Tue, 5 Sep 2017 15:06:54 -0700 Subject: [PATCH 42/42] Fix `spawnHelper` tests (post-rebase) --- src/commands/checkout.js | 2 +- src/constants.js | 4 ++-- src/helpers.js | 4 ++-- src/utils/spawnHelper.js | 8 ++++---- test/tests/utils/spawnHelper.spec.js | 4 ---- 5 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/commands/checkout.js b/src/commands/checkout.js index 7194508..0872bcd 100644 --- a/src/commands/checkout.js +++ b/src/commands/checkout.js @@ -74,7 +74,7 @@ function checkout(repo, callback) { } return response; - }, errorCatchHandler(response)); + }, errorCatchHandler); } export default checkout; diff --git a/src/constants.js b/src/constants.js index 2f26de5..6168201 100644 --- a/src/constants.js +++ b/src/constants.js @@ -13,13 +13,13 @@ export const regex = { USERNAME: /username/g, PASSWORD: /password/g, PASSPHRASE: /passphrase/g, - PERMISSION_DENIED: /permission\s+denied\s+\(.+\)\./g, + PERMISSION_DENIED: /permission\s+denied\s+\(.+\)\./g }; export const promptTypes = { USERNAME: 'username', PASSWORD: 'password', - PASSPHRASE: 'passphrase', + PASSPHRASE: 'passphrase' }; export const BAD_VERSION = '0'; diff --git a/src/helpers.js b/src/helpers.js index 123733b..8ace46c 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -3,10 +3,10 @@ import path from 'path'; import R from 'ramda'; import { - LFS_ATTRIBUTE, BAD_CORE_RESPONSE, BAD_REGEX_PARSE_RESULT, - regex, + LFS_ATTRIBUTE, + regex } from './constants'; import generateResponse from './utils/generateResponse'; diff --git a/src/utils/spawnHelper.js b/src/utils/spawnHelper.js index c0aaf80..c670601 100644 --- a/src/utils/spawnHelper.js +++ b/src/utils/spawnHelper.js @@ -31,11 +31,11 @@ const buildSocketPath = () => tmp.dir() * ( * spawnedProcess: ChildProcess, * callback: ( - * passwordOnly: boolean, - * callback: (usernamePrompt: boolean) => + * output: string, + * callback: (promptType: string) => * (username: string, password: ?string, cancel: boolean) => * void - * ) + * ) => void * ), * reject: Error => Promise * ) => @@ -220,7 +220,7 @@ const spawn = (command, opts = {}, callback) => new Promise( resolve({ code, - stdout, + stdout }); }); }); diff --git a/test/tests/utils/spawnHelper.spec.js b/test/tests/utils/spawnHelper.spec.js index 5a7395d..1ad2c52 100644 --- a/test/tests/utils/spawnHelper.spec.js +++ b/test/tests/utils/spawnHelper.spec.js @@ -58,8 +58,6 @@ describe('spawnHelper', () => { it('resolves with the correct data on a successful exit', todo); it('rejects on spawn error', todo); - - it('rejects on non-0 exit code', todo); }); describe('winSpawn', () => { @@ -111,8 +109,6 @@ describe('spawnHelper', () => { describe('buildSocket', () => { it('resolves the calling `Promise` with the correct data on a successful exit', todo); - it('only runs the successful close logic once', todo); - it('calls the close callback when the socket ends', todo); it('calls the close callback when the socket closes', todo);