diff --git a/.circleci/config.yml b/.circleci/config.yml index a73b4b67ac..2e08597b40 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -122,11 +122,21 @@ jobs: root: ~/project paths: - yarn + test-pkg-tests-linux-node10: + <<: *docker_defaults + docker: + - image: node:10 + <<: *pkg_tests test-pkg-tests-linux-node8: <<: *docker_defaults <<: *pkg_tests + test-linux-node10: + <<: *docker_defaults + <<: *test_steps test-linux-node8: <<: *docker_defaults + docker: + - image: node:8 <<: *test_steps test-linux-node6: <<: *docker_defaults @@ -138,6 +148,18 @@ jobs: docker: - image: node:4 <<: *test_steps + test-macos-node10: + <<: *macos_defaults + steps: + - run: + name: Install Node 10 + command: | + brew uninstall --ignore-dependencies node + brew update + HOMEBREW_NO_AUTO_UPDATE=1 brew install node@10 + - *attach_workspace + - *test_build + - *test_run test-macos-node8: <<: *macos_defaults steps: @@ -221,10 +243,18 @@ workflows: filters: *default_filters requires: - install + - test-pkg-tests-linux-node10: + filters: *default_filters + requires: + - install - test-pkg-tests-linux-node8: filters: *default_filters requires: - install + - test-linux-node10: + filters: *default_filters + requires: + - install - test-linux-node8: filters: *default_filters requires: @@ -237,7 +267,7 @@ workflows: filters: *default_filters requires: - install - - test-macos-node6: + - test-macos-node10: filters: *default_filters requires: - install @@ -245,6 +275,10 @@ workflows: filters: *default_filters requires: - install + - test-macos-node6: + filters: *default_filters + requires: + - install - build: filters: *default_filters requires: @@ -255,10 +289,13 @@ workflows: branches: ignore: /.*/ requires: + - test-pkg-tests-linux-node10 - test-pkg-tests-linux-node8 + - test-linux-node10 - test-linux-node8 - test-linux-node6 - test-linux-node4 + - test-macos-node10 - test-macos-node8 - test-macos-node6 - lint diff --git a/Dockerfile.dev b/Dockerfile.dev index 46168e024d..05e46ca64d 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -1,7 +1,7 @@ # Dockerfile for building Yarn. # docker build -t yarnpkg/dev -f Dockerfile.dev . -FROM node:8 +FROM node:10 # Debian packages RUN apt-get -y update && \ diff --git a/__tests__/commands/_helpers.js b/__tests__/commands/_helpers.js index 6b82806565..b26eb8a114 100644 --- a/__tests__/commands/_helpers.js +++ b/__tests__/commands/_helpers.js @@ -181,6 +181,7 @@ export async function run( } catch (err) { throw new Error(`${err && err.stack} \nConsole output:\n ${out}`); } finally { + reporter.close(); await fs.unlink(cwd); } } diff --git a/__tests__/commands/install/integration.js b/__tests__/commands/install/integration.js index dfade528d5..a35c10d87f 100644 --- a/__tests__/commands/install/integration.js +++ b/__tests__/commands/install/integration.js @@ -47,69 +47,60 @@ async function mockConstants(base: Config, mocks: Object, cb: (config: Config) = beforeEach(request.__resetAuthedRequests); afterEach(request.__resetAuthedRequests); -test.concurrent('install should not hoist packages above their peer dependencies', async () => { - await runInstall({}, 'install-should-not-hoist-through-peer-deps', async (config): Promise => { +test('install should not hoist packages above their peer dependencies', () => + runInstall({}, 'install-should-not-hoist-through-peer-deps', async (config): Promise => { expect(await fs.exists(`${config.cwd}/node_modules/a/node_modules/c`)).toEqual(true); - }); -}); + })); -test.concurrent('install should resolve peer dependencies from same subtrees', async () => { - await runInstall({}, 'peer-dep-same-subtree', async (config): Promise => { +test('install should resolve peer dependencies from same subtrees', () => + runInstall({}, 'peer-dep-same-subtree', async (config): Promise => { expect(JSON.parse(await fs.readFile(`${config.cwd}/node_modules/d/node_modules/a/package.json`)).version).toEqual( '1.0.0', ); expect(JSON.parse(await fs.readFile(`${config.cwd}/node_modules//a/package.json`)).version).toEqual('1.1.0'); expect(await fs.exists(`${config.cwd}/node_modules/c/node_modules/a`)).toEqual(false); - }); -}); + })); -test.concurrent('install optional subdependencies by default', async () => { - await runInstall({}, 'install-optional-dependencies', async (config): Promise => { +test('install optional subdependencies by default', () => + runInstall({}, 'install-optional-dependencies', async (config): Promise => { expect(await fs.exists(`${config.cwd}/node_modules/dep-b`)).toEqual(true); - }); -}); + })); -test.concurrent('installing with --ignore-optional should not install optional subdependencies', async () => { - await runInstall({ignoreOptional: true}, 'install-optional-dependencies', async (config): Promise => { +test('installing with --ignore-optional should not install optional subdependencies', () => + runInstall({ignoreOptional: true}, 'install-optional-dependencies', async (config): Promise => { expect(await fs.exists(`${config.cwd}/node_modules/dep-b`)).toEqual(false); expect(await fs.exists(`${config.cwd}/node_modules/dep-c`)).toEqual(true); expect(await fs.exists(`${config.cwd}/node_modules/dep-d`)).toEqual(true); expect(await fs.exists(`${config.cwd}/node_modules/dep-e`)).toEqual(true); - }); -}); + })); -test.concurrent( - 'running install inside a workspace should run the install from the root of the workspace', - async () => { - await runInstall({}, 'install-workspaces', async (config, reporter): Promise => { - const pkgJson = await fs.readJson(`${config.cwd}/workspace/package.json`); - pkgJson.dependencies['b'] = 'file:../b'; - await fs.writeFile(`${config.cwd}/workspace/package.json`, JSON.stringify(pkgJson)); +test('running install inside a workspace should run the install from the root of the workspace', () => + runInstall({}, 'install-workspaces', async (config, reporter): Promise => { + const pkgJson = await fs.readJson(`${config.cwd}/workspace/package.json`); + pkgJson.dependencies['b'] = 'file:../b'; + await fs.writeFile(`${config.cwd}/workspace/package.json`, JSON.stringify(pkgJson)); - const workspaceConfig = await Config.create({cwd: `${config.cwd}/workspace`}, reporter); + const workspaceConfig = await Config.create({cwd: `${config.cwd}/workspace`}, reporter); - const reInstall = new Install({}, workspaceConfig, reporter, await Lockfile.fromDirectory(config.cwd)); - await reInstall.init(); + const reInstall = new Install({}, workspaceConfig, reporter, await Lockfile.fromDirectory(config.cwd)); + await reInstall.init(); - const lockfileContent = await fs.readFile(`${config.cwd}/yarn.lock`); - expect(lockfileContent).toEqual(expect.stringContaining(`"b@file:b"`)); - expect(lockfileContent).toEqual(expect.stringContaining(`"a@file:./a"`)); - }); - }, -); + const lockfileContent = await fs.readFile(`${config.cwd}/yarn.lock`); + expect(lockfileContent).toEqual(expect.stringContaining(`"b@file:b"`)); + expect(lockfileContent).toEqual(expect.stringContaining(`"a@file:./a"`)); + })); -test.concurrent('packages installed through the link protocol should validate all peer dependencies', async () => { - await runInstall({checkFiles: true}, 'check-files-should-not-cross-symlinks', async (config): Promise => { +test('packages installed through the link protocol should validate all peer dependencies', () => + runInstall({checkFiles: true}, 'check-files-should-not-cross-symlinks', async (config): Promise => { expect( JSON.parse(await fs.readFile(`${config.cwd}/node_modules/.yarn-integrity`)).files.map(file => { return file.replace(/\\/g, '/'); }), ).toEqual(['some-missing-pkg', 'some-other-pkg', 'some-pkg/package.json']); - }); -}); + })); -test.concurrent('installing a package with a renamed file should not delete it', async () => { - await runInstall({}, 'case-sensitivity', async (config, reporter): Promise => { +test('installing a package with a renamed file should not delete it', () => + runInstall({}, 'case-sensitivity', async (config, reporter): Promise => { const pkgJson = await fs.readJson(`${config.cwd}/package.json`); pkgJson.dependencies['pkg'] = 'file:./pkg-b'; await fs.writeFile(`${config.cwd}/package.json`, JSON.stringify(pkgJson)); @@ -118,11 +109,10 @@ test.concurrent('installing a package with a renamed file should not delete it', await reInstall.init(); expect(await fs.exists(`${config.cwd}/node_modules/pkg/state.js`)).toEqual(true); - }); -}); + })); -test.concurrent('properly find and save build artifacts', async () => { - await runInstall({}, 'artifacts-finds-and-saves', async (config): Promise => { +test('properly find and save build artifacts', () => + runInstall({}, 'artifacts-finds-and-saves', async (config): Promise => { const integrity = await fs.readJson(path.join(config.cwd, 'node_modules', constants.INTEGRITY_FILENAME)); expect(integrity.artifacts['dummy@0.0.0']).toEqual(['dummy', path.join('dummy', 'dummy.txt'), 'dummy.txt']); @@ -131,20 +121,18 @@ test.concurrent('properly find and save build artifacts', async () => { const moduleFolder = path.join(config.cwd, 'node_modules', 'dummy'); expect(await fs.readFile(path.join(moduleFolder, 'dummy.txt'))).toEqual('foobar'); expect(await fs.readFile(path.join(moduleFolder, 'dummy', 'dummy.txt'))).toEqual('foobar'); - }); -}); + })); -test('reading a lockfile should not optimize it', async () => { - await runInstall({}, 'lockfile-optimization', async (config, reporter): Promise => { +test('reading a lockfile should not optimize it', () => + runInstall({}, 'lockfile-optimization', async (config, reporter): Promise => { const was = await fs.readFile(`${__dirname}/../../fixtures/install/lockfile-optimization/yarn.lock`); const is = await fs.readFile(`${config.cwd}/yarn.lock`); expect(is).toEqual(was); - }); -}); + })); -test.concurrent('creates a symlink to a directory when using the link: protocol', async () => { - await runInstall({}, 'install-link', async (config): Promise => { +test('creates a symlink to a directory when using the link: protocol', () => + runInstall({}, 'install-link', async (config): Promise => { const expectPath = path.join(config.cwd, 'node_modules', 'test-absolute'); const stat = await fs.lstat(expectPath); @@ -152,11 +140,10 @@ test.concurrent('creates a symlink to a directory when using the link: protocol' const target = await fs.readlink(expectPath); expect(path.resolve(config.cwd, target)).toMatch(/[\\\/]bar$/); - }); -}); + })); -test.concurrent('creates a symlink to a non-existing directory when using the link: protocol', async () => { - await runInstall({}, 'install-link', async (config): Promise => { +test('creates a symlink to a non-existing directory when using the link: protocol', () => + runInstall({}, 'install-link', async (config): Promise => { const expectPath = path.join(config.cwd, 'node_modules', 'test-missing'); const stat = await fs.lstat(expectPath); @@ -168,49 +155,40 @@ test.concurrent('creates a symlink to a non-existing directory when using the li } else { expect(target).toMatch(/[\\\/]baz[\\\/]$/); } - }); -}); + })); -test.concurrent( - 'resolves the symlinks relative to the package path when using the link: protocol; not the node_modules', - async () => { - await runInstall({}, 'install-link', async (config): Promise => { - const expectPath = path.join(config.cwd, 'node_modules', 'test-relative'); - - const stat = await fs.lstat(expectPath); - expect(stat.isSymbolicLink()).toEqual(true); - - const target = await fs.readlink(expectPath); - if (process.platform !== 'win32') { - expect(target).toEqual('../bar'); - } else { - expect(target).toMatch(/[\\\/]bar[\\\/]$/); - } - }); - }, -); - -test.concurrent( - 'resolves the symlinks of other symlinked packages relative to the package using the link: protocol', - async () => { - await runInstall({}, 'install-link-nested', async (config): Promise => { - const expectPath = path.join(config.cwd, 'node_modules', 'b'); - - const stat = await fs.lstat(expectPath); - expect(stat.isSymbolicLink()).toEqual(true); - - const target = await fs.readlink(expectPath); - if (process.platform !== 'win32') { - expect(target).toEqual('../a/b'); - } else { - expect(target).toMatch(/[\\\/]b[\\\/]$/); - } - }); - }, -); +test('resolves the symlinks relative to the package path when using the link: protocol; not the node_modules', () => + runInstall({}, 'install-link', async (config): Promise => { + const expectPath = path.join(config.cwd, 'node_modules', 'test-relative'); + + const stat = await fs.lstat(expectPath); + expect(stat.isSymbolicLink()).toEqual(true); + + const target = await fs.readlink(expectPath); + if (process.platform !== 'win32') { + expect(target).toEqual('../bar'); + } else { + expect(target).toMatch(/[\\\/]bar[\\\/]$/); + } + })); -test.concurrent('replace the symlink when it changes, when using the link: protocol', async () => { - await runInstall({}, 'install-link', async (config, reporter): Promise => { +test('resolves the symlinks of other symlinked packages relative to the package using the link: protocol', () => + runInstall({}, 'install-link-nested', async (config): Promise => { + const expectPath = path.join(config.cwd, 'node_modules', 'b'); + + const stat = await fs.lstat(expectPath); + expect(stat.isSymbolicLink()).toEqual(true); + + const target = await fs.readlink(expectPath); + if (process.platform !== 'win32') { + expect(target).toEqual('../a/b'); + } else { + expect(target).toMatch(/[\\\/]b[\\\/]$/); + } + })); + +test('replace the symlink when it changes, when using the link: protocol', () => + runInstall({}, 'install-link', async (config, reporter): Promise => { const lockfile = await Lockfile.fromDirectory(config.cwd); const pkgJson = await fs.readJson(`${config.cwd}/package.json`); @@ -231,11 +209,10 @@ test.concurrent('replace the symlink when it changes, when using the link: proto } else { expect(target).toMatch(/[\\\/]barbaz[\\\/]$/); } - }); -}); + })); -test('changes the cache path when bumping the cache version', async () => { - await runInstall({}, 'install-github', async (config): Promise => { +test('changes the cache path when bumping the cache version', () => + runInstall({}, 'install-github', async (config): Promise => { const inOut = new stream.PassThrough(); const reporter = new reporters.JSONReporter({stdout: inOut}); @@ -246,11 +223,10 @@ test('changes the cache path when bumping the cache version', async () => { await cache(config, reporter, {}, ['dir']); expect((JSON.parse(String(inOut.read())): any).data).toMatch(/[\\\/]v42[\\\/]?$/); }); - }); -}); + })); -test('changes the cache directory when bumping the cache version', async () => { - await runInstall({}, 'install-production', async (config, reporter): Promise => { +test('changes the cache directory when bumping the cache version', () => + runInstall({}, 'install-production', async (config, reporter): Promise => { const lockfile = await Lockfile.fromDirectory(config.cwd); const resolver = new PackageResolver(config, lockfile); @@ -273,10 +249,9 @@ test('changes the cache directory when bumping the cache version', async () => { expect(await fs.exists(path.join(config.cwd, 'node_modules', 'is-array', 'yarn.test'))).toEqual(false); }); - }); -}); + })); -test.concurrent("removes extraneous files that aren't in module or artifacts", async () => { +test("removes extraneous files that aren't in module or artifacts", () => { async function check(cwd: string): Promise { // retains artifact const moduleFolder = path.join(cwd, 'node_modules', 'dummy'); @@ -294,7 +269,7 @@ test.concurrent("removes extraneous files that aren't in module or artifacts", a await fs.writeFile(path.join(moduleFolder, 'dummy2.txt'), 'foobar'); } - await runInstall( + return runInstall( {}, 'artifacts-finds-and-saves', async (config): Promise => { @@ -312,27 +287,25 @@ test.concurrent("removes extraneous files that aren't in module or artifacts", a ); }); -test.concurrent("production mode with deduped dev dep shouldn't be removed", async () => { - await runInstall({production: true}, 'install-prod-deduped-dev-dep', async config => { +test("production mode with deduped dev dep shouldn't be removed", () => + runInstall({production: true}, 'install-prod-deduped-dev-dep', async config => { expect((await fs.readJson(path.join(config.cwd, 'node_modules', 'a', 'package.json'))).version).toEqual('1.0.0'); expect((await fs.readJson(path.join(config.cwd, 'node_modules', 'c', 'package.json'))).version).toEqual('1.0.0'); expect(await fs.exists(path.join(config.cwd, 'node_modules', 'b'))).toEqual(false); - }); -}); + })); -test.concurrent("production mode dep on package in dev deps shouldn't be removed", async () => { - await runInstall({production: true}, 'install-prod-deduped-direct-dev-dep', async config => { +test("production mode dep on package in dev deps shouldn't be removed", () => + runInstall({production: true}, 'install-prod-deduped-direct-dev-dep', async config => { expect((await fs.readJson(path.join(config.cwd, 'node_modules', 'a', 'package.json'))).version).toEqual('1.0.0'); expect((await fs.readJson(path.join(config.cwd, 'node_modules', 'b', 'package.json'))).version).toEqual('1.0.0'); expect((await fs.readJson(path.join(config.cwd, 'node_modules', 'c', 'package.json'))).version).toEqual('1.0.0'); - }); -}); + })); -test.concurrent('hoisting should factor ignored dependencies', async () => { +test('hoisting should factor ignored dependencies', async () => { // you should only modify this test if you know what you're doing // when we calculate hoisting we need to factor in ignored dependencies in it // so we get deterministic hoisting across environments, for example in production mode @@ -365,38 +338,27 @@ test.concurrent('hoisting should factor ignored dependencies', async () => { }); }); -test.concurrent('--production flag ignores dev dependencies', () => { - return runInstall({production: true}, 'install-production', async config => { +test('--production flag ignores dev dependencies', () => + runInstall({production: true}, 'install-production', async config => { expect(await fs.exists(path.join(config.cwd, 'node_modules', 'left-pad'))).toEqual(false); - expect(await fs.exists(path.join(config.cwd, 'node_modules', 'is-array'))).toEqual(true); - }); -}); + })); -test.concurrent('--production flag does not link dev dependency bin scripts', () => { - return runInstall({production: true, binLinks: true}, 'install-production-bin', async config => { +test('--production flag does not link dev dependency bin scripts', () => + runInstall({production: true, binLinks: true}, 'install-production-bin', async config => { expect(await fs.exists(path.join(config.cwd, 'node_modules', '.bin', 'touch'))).toEqual(false); - expect(await fs.exists(path.join(config.cwd, 'node_modules', '.bin', 'rimraf'))).toEqual(true); - }); -}); + })); -test.concurrent('root install with optional deps', (): Promise => { - return runInstall({}, 'root-install-with-optional-dependency'); -}); +test('root install with optional deps', (): Promise => runInstall({}, 'root-install-with-optional-dependency')); -test.concurrent('install file: protocol with relative paths', (): Promise => { - return runInstall({}, 'install-file-relative', async config => { +test('install file: protocol with relative paths', (): Promise => + runInstall({}, 'install-file-relative', async config => { expect(await fs.readFile(path.join(config.cwd, 'node_modules', 'root-a', 'index.js'))).toEqual('foobar;\n'); - }); -}); + })); -test.concurrent('install file: protocol without force retains installed package', async (): Promise => { - const fixturesLoc = path.join(__dirname, '..', '..', 'fixtures', 'install'); - const compLoc = path.join(fixturesLoc, 'install-file-without-cache', 'comp', 'index.js'); - - await fs.writeFile(compLoc, 'foo\n'); - await runInstall({}, 'install-file-without-cache', async (config, reporter) => { +test('install file: protocol without force retains installed package', (): Promise => + runInstall({}, 'install-file-without-cache', async (config, reporter) => { expect(await fs.readFile(path.join(config.cwd, 'node_modules', 'comp', 'index.js'))).toEqual('foo\n'); await fs.writeFile(path.join(config.cwd, 'comp', 'index.js'), 'bar\n'); @@ -405,15 +367,10 @@ test.concurrent('install file: protocol without force retains installed package' await reinstall.init(); expect(await fs.readFile(path.join(config.cwd, 'node_modules', 'comp', 'index.js'))).not.toEqual('bar\n'); - }); -}); - -test.concurrent('install file: protocol with force re-installs local package', async (): Promise => { - const fixturesLoc = path.join(__dirname, '..', '..', 'fixtures', 'install'); - const compLoc = path.join(fixturesLoc, 'install-file-without-cache', 'comp', 'index.js'); + })); - await fs.writeFile(compLoc, 'foo\n'); - await runInstall({}, 'install-file-without-cache', async (config, reporter) => { +test('install file: protocol with force re-installs local package', (): Promise => + runInstall({}, 'install-file-without-cache', async (config, reporter) => { expect(await fs.readFile(path.join(config.cwd, 'node_modules', 'comp', 'index.js'))).toEqual('foo\n'); await fs.writeFile(path.join(config.cwd, 'comp', 'index.js'), 'bar\n'); @@ -422,28 +379,25 @@ test.concurrent('install file: protocol with force re-installs local package', a await reinstall.init(); expect(await fs.readFile(path.join(config.cwd, 'node_modules', 'comp', 'index.js'))).toEqual('bar\n'); - }); -}); + })); -test.concurrent('install file: local packages with local dependencies', async (): Promise => { - await runInstall({}, 'install-file-local-dependency', async (config, reporter) => { +test('install file: local packages with local dependencies', (): Promise => + runInstall({}, 'install-file-local-dependency', async (config, reporter) => { const reinstall = new Install({}, config, reporter, await Lockfile.fromDirectory(config.cwd)); await reinstall.init(); expect(await fs.readFile(path.join(config.cwd, 'node_modules', 'a', 'index.js'))).toEqual('foo;\n'); expect(await fs.readFile(path.join(config.cwd, 'node_modules', 'b', 'index.js'))).toEqual('bar;\n'); - }); -}); + })); -test.concurrent('install file: install without manifest of dependency', async (): Promise => { - await runInstall({}, 'install-file-without-manifest', async config => { +test('install file: install without manifest of dependency', (): Promise => + runInstall({}, 'install-file-without-manifest', async config => { expect(await fs.readFile(path.join(config.cwd, 'node_modules', 'foo', 'index.js'))).toEqual('bar\n'); - }); -}); + })); -test.concurrent('install file: link file dependencies', async (): Promise => { - await runInstall({}, 'install-file-link-dependencies', async config => { +test('install file: link file dependencies', (): Promise => + runInstall({}, 'install-file-link-dependencies', async config => { const statA = await fs.lstat(path.join(config.cwd, 'node_modules', 'a')); expect(statA.isSymbolicLink()).toEqual(true); @@ -456,98 +410,86 @@ test.concurrent('install file: link file dependencies', async (): Promise expect(await fs.readFile(path.join(config.cwd, 'node_modules', 'a', 'index.js'))).toEqual('foo;\n'); expect(await fs.readFile(path.join(config.cwd, 'node_modules', 'b', 'index.js'))).toEqual('bar;\n'); - }); -}); + })); -test.concurrent('install file: protocol', (): Promise => { - return runInstall({lockfile: false}, 'install-file', async config => { +test('install file: protocol', (): Promise => + runInstall({lockfile: false}, 'install-file', async config => { expect(await fs.readFile(path.join(config.cwd, 'node_modules', 'foo', 'index.js'))).toEqual('foobar;\n'); - }); -}); + })); -test.concurrent('install with file: protocol as default', (): Promise => { - return runInstall({}, 'install-file-as-default', async (config, reporter, install, getOutput) => { +test('install with file: protocol as default', (): Promise => + runInstall({}, 'install-file-as-default', async (config, reporter, install, getOutput) => { expect(await fs.readFile(path.join(config.cwd, 'node_modules', 'foo', 'index.js'))).toEqual('foobar;\n'); expect(getOutput()).toContain(reporter.lang('implicitFileDeprecated', 'bar')); - }); -}); + })); -test.concurrent("don't install with file: protocol as default if target is a file", (): Promise => { +test("don't install with file: protocol as default if target is a file", (): Promise => { // $FlowFixMe return expect(runInstall({lockfile: false}, 'install-file-as-default-no-file')).rejects.toBeDefined(); }); -test.concurrent("don't install with implicit file: protocol if target does not have package.json", (): Promise< - void, -> => { +test("don't install with implicit file: protocol if target does not have package.json", (): Promise => { // $FlowFixMe return expect(runInstall({lockfile: false}, 'install-file-as-default-no-package')).rejects.toBeDefined(); }); -test.concurrent('install with explicit file: protocol if target does not have package.json', (): Promise => { - return runInstall({}, 'install-file-no-package', async config => { +test('install with explicit file: protocol if target does not have package.json', (): Promise => + runInstall({}, 'install-file-no-package', async config => { expect(await fs.exists(path.join(config.cwd, 'node_modules', 'foo', 'bar.js'))).toEqual(true); expect(await fs.exists(path.join(config.cwd, 'node_modules', 'bar', 'bar.js'))).toEqual(true); - }); -}); + })); -test("don't install with file: protocol as default if target is valid semver", (): Promise => { - return runInstall({}, 'install-file-as-default-no-semver', async config => { +test("don't install with file: protocol as default if target is valid semver", (): Promise => + runInstall({}, 'install-file-as-default-no-semver', async config => { expect(await fs.readFile(path.join(config.cwd, 'node_modules', 'foo', 'package.json'))).toMatchSnapshot( 'install-file-as-default-no-semver', ); - }); -}); + })); -test.concurrent("don't hang when an install script tries to read from stdin", (): Promise => +test("don't hang when an install script tries to read from stdin", (): Promise => runInstall({}, 'install-blocking-script', (_config, _reporter, _install, getStdout) => expect(getStdout()).toMatch(/Building fresh packages/), - ), -); + )); // When local packages are installed, dependencies with different forms of the same relative path // should be deduped e.g. 'file:b' and 'file:./b' -test.concurrent('install file: dedupe dependencies 1', (): Promise => { - return runInstall({}, 'install-file-dedupe-dependencies-1', async config => { +test('install file: dedupe dependencies 1', (): Promise => + runInstall({}, 'install-file-dedupe-dependencies-1', async config => { // Check that b is not added as a sub-dependency of a expect(await fs.exists(path.join(config.cwd, 'node_modules', 'a', 'node_modules'))).toEqual(false); - }); -}); + })); // When local packages are installed, dependencies with relative and absolute paths should be // deduped e.g. 'file:b' and 'file:/absolute/path/to/b' -test.concurrent('install file: dedupe dependencies 2', (): Promise => { - return runInstall({}, 'install-file-dedupe-dependencies-2', async (config, reporter) => { +test('install file: dedupe dependencies 2', (): Promise => + runInstall({}, 'install-file-dedupe-dependencies-2', async (config, reporter) => { // Add b as a dependency, using an absolute path await add(config, reporter, {}, [`b@file:${path.resolve(config.cwd, 'b')}`]); // Check that b is not added as a sub-dependency of a expect(await fs.exists(path.join(config.cwd, 'node_modules', 'a', 'node_modules'))).toEqual(false); - }); -}); + })); // When local packages are installed from a repo with a lockfile, the multiple packages // unpacking in the same location warning should not occur -test.concurrent('install file: dedupe dependencies 3', (): Promise => { - return runInstall({}, 'install-file-dedupe-dependencies-3', (config, reporter, install, getStdout) => { +test('install file: dedupe dependencies 3', (): Promise => + runInstall({}, 'install-file-dedupe-dependencies-3', (config, reporter, install, getStdout) => { const stdout = getStdout(); // Need to check if message is logged, but don't need to check for any specific parameters // so splitting on undefined and testing if all message parts are in stdout const messageParts = reporter.lang('multiplePackagesCantUnpackInSameDestination').split('undefined'); const warningMessage = messageParts.every(part => stdout.includes(part)); expect(warningMessage).toBe(false); - }); -}); + })); -test.concurrent('install everything when flat is enabled', (): Promise => { - return runInstall({lockfile: false, flat: true}, 'install-file', async config => { +test('install everything when flat is enabled', (): Promise => + runInstall({lockfile: false, flat: true}, 'install-file', async config => { expect(await fs.readFile(path.join(config.cwd, 'node_modules', 'foo', 'index.js'))).toEqual('foobar;\n'); - }); -}); + })); -test.concurrent('install renamed packages', (): Promise => { - return runInstall({}, 'install-renamed-packages', async (config): Promise => { +test('install renamed packages', (): Promise => + runInstall({}, 'install-renamed-packages', async (config): Promise => { const dir = path.join(config.cwd, 'node_modules'); const json = await fs.readJson(path.join(dir, 'left-pad', 'package.json')); @@ -555,28 +497,23 @@ test.concurrent('install renamed packages', (): Promise => { const json2 = await fs.readJson(path.join(dir, 'left-pad2', 'package.json')); expect(json2.version).toEqual('1.1.0'); - }); -}); + })); -test.concurrent('install from git cache', (): Promise => { - return runInstall({}, 'install-from-git-cache', async (config): Promise => { +test('install from git cache', (): Promise => + runInstall({}, 'install-from-git-cache', async (config): Promise => { expect(await getPackageVersion(config, 'dep-a')).toEqual('0.0.1'); - }); -}); + })); -test.concurrent('install from github', (): Promise => { - return runInstall({}, 'install-github'); -}); +test('install from github', (): Promise => runInstall({}, 'install-github')); -test.concurrent('check and install should verify integrity in the same way when flat', (): Promise => { - return runInstall({flat: true}, 'install-should-dedupe-avoiding-conflicts-1', async (config, reporter) => { +test('check and install should verify integrity in the same way when flat', (): Promise => + runInstall({flat: true}, 'install-should-dedupe-avoiding-conflicts-1', async (config, reporter) => { // Will raise if check doesn't flatten the patterns await check(config, reporter, {flat: true, integrity: true}, []); - }); -}); + })); -test.concurrent('check should verify that top level dependencies are installed correctly', (): Promise => { - return runInstall({}, 'check-top-correct', async (config, reporter) => { +test('check should verify that top level dependencies are installed correctly', (): Promise => + runInstall({}, 'check-top-correct', async (config, reporter) => { const pkgDep = JSON.parse( await fs.readFile(path.join(config.cwd, 'node_modules/fake-yarn-dependency/package.json')), ); @@ -593,24 +530,21 @@ test.concurrent('check should verify that top level dependencies are installed c allCorrect = true; } expect(allCorrect).toBe(true); - }); -}); + })); -test.concurrent('install should run install scripts in the order of dependencies', (): Promise => { - return runInstall({}, 'scripts-order', async (config, reporter) => { +test('install should run install scripts in the order of dependencies', (): Promise => + runInstall({}, 'scripts-order', async (config, reporter) => { expect(await fs.exists(path.join(config.cwd, 'node_modules/dep-a/dep-a-built'))).toBe(true); expect(await fs.exists(path.join(config.cwd, 'node_modules/dep-b/dep-b-built'))).toBe(true); expect(await fs.exists(path.join(config.cwd, 'node_modules/dep-c/dep-c-built'))).toBe(true); - }); -}); + })); -test.concurrent('install with comments in manifest', (): Promise => { - return runInstall({lockfile: false}, 'install-with-comments', async config => { +test('install with comments in manifest', (): Promise => + runInstall({lockfile: false}, 'install-with-comments', async config => { expect(await fs.readFile(path.join(config.cwd, 'node_modules', 'foo', 'index.js'))).toEqual('foobar;\n'); - }); -}); + })); -test.concurrent('install with comments in manifest resolutions does not result in warning', (): Promise => { +test('install with comments in manifest resolutions does not result in warning', (): Promise => { const fixturesLoc = path.join(__dirname, '..', '..', 'fixtures', 'install'); return buildRun( @@ -634,58 +568,50 @@ test.concurrent('install with comments in manifest resolutions does not result i ); }); -test.concurrent('install with null versions in manifest', (): Promise => { - return runInstall({}, 'install-with-null-version', async config => { +test('install with null versions in manifest', (): Promise => + runInstall({}, 'install-with-null-version', async config => { expect(await fs.exists(path.join(config.cwd, 'node_modules', 'left-pad'))).toEqual(true); - }); -}); + })); -test.concurrent('run install scripts in the order when one dependency does not have install script', (): Promise< - void, -> => { - return runInstall({}, 'scripts-order-with-one-package-missing-install-script', async (config, reporter) => { +test('run install scripts in the order when one dependency does not have install script', (): Promise => + runInstall({}, 'scripts-order-with-one-package-missing-install-script', async (config, reporter) => { expect(await fs.exists(path.join(config.cwd, 'node_modules/dep-a/dep-a-built'))).toBe(true); expect(await fs.exists(path.join(config.cwd, 'node_modules/dep-b/dep-b-built'))).toBe(true); expect(await fs.exists(path.join(config.cwd, 'node_modules/dep-d/dep-d-built'))).toBe(true); - }); -}); + })); -test.concurrent('install should circumvent circular dependencies', (): Promise => { - return runInstall({}, 'install-should-circumvent-circular-dependencies', async (config, reporter) => { +test('install should circumvent circular dependencies', (): Promise => + runInstall({}, 'install-should-circumvent-circular-dependencies', async (config, reporter) => { expect(await getPackageVersion(config, 'dep-a')).toEqual('1.0.0'); expect(await getPackageVersion(config, 'dep-b')).toEqual('1.0.0'); expect(await getPackageVersion(config, 'dep-c')).toEqual('1.0.0'); - }); -}); + })); -test.concurrent('install should resolve circular dependencies 2', (): Promise => { - return runInstall({}, 'install-should-circumvent-circular-dependencies-2', async (config, reporter) => { +test('install should resolve circular dependencies 2', (): Promise => + runInstall({}, 'install-should-circumvent-circular-dependencies-2', async (config, reporter) => { expect(await getPackageVersion(config, 'es5-ext')).toEqual('0.10.12'); - }); -}); + })); -test.concurrent('install should be idempotent', (): Promise => { - // Install a package twice +// Install a package twice +test('install should be idempotent', (): Promise => runInstall( {}, 'install-should-be-idempotent', async (config, reporter) => { expect(await getPackageVersion(config, 'dep-a')).toEqual('1.0.0'); + await runInstall({}, 'install-should-be-idempotent', async (config, reporter) => { + expect(await getPackageVersion(config, 'dep-a')).toEqual('1.0.0'); + }); }, null, - ); - - return runInstall({}, 'install-should-be-idempotent', async (config, reporter) => { - expect(await getPackageVersion(config, 'dep-a')).toEqual('1.0.0'); - }); -}); + )); -test.concurrent('install should update checksums in yarn.lock (--update-checksums)', (): Promise => { - const packageRealHash = '5faad9c2c07f60dd76770f71cf025b62a63cfd4e'; - const packageCacheName = `npm-abab-1.0.4-${packageRealHash}`; - return runInstall({updateChecksums: true}, 'install-update-checksums', async config => { +test('install should update checksums in yarn.lock (--update-checksums)', (): Promise => + runInstall({updateChecksums: true}, 'install-update-checksums', async config => { + const packageRealHash = '5faad9c2c07f60dd76770f71cf025b62a63cfd4e'; + const packageCacheName = `npm-abab-1.0.4-${packageRealHash}`; const lockFileContent = await fs.readFile(path.join(config.cwd, 'yarn.lock')); const lockFileLines = explodeLockfile(lockFileContent); const packageHashInLockfile = lockFileLines[2].replace(/(^.*#)|("$)/g, ''); @@ -694,13 +620,12 @@ test.concurrent('install should update checksums in yarn.lock (--update-checksum expect(packageHashInLockfile).toEqual(packageRealHash); expect(await fs.exists(installedPackageJson)).toBe(true); expect(await fs.exists(cachePackageJson)).toBe(true); - }); -}); + })); if (process.platform !== 'win32') { // TODO: This seems like a real issue, not just a config issue - test.concurrent('install cache symlinks properly', (): Promise => { - return runInstall({}, 'cache-symlinks', async (config, reporter) => { + test('install cache symlinks properly', (): Promise => + runInstall({}, 'cache-symlinks', async (config, reporter) => { const symlink = path.resolve(config.cwd, 'node_modules', 'dep-a', 'link-index.js'); expect(await fs.exists(symlink)).toBe(true); await fs.unlink(path.join(config.cwd, 'node_modules')); @@ -710,13 +635,11 @@ if (process.platform !== 'win32') { await install.init(); expect(await fs.exists(symlink)).toBe(true); - }); - }); + })); } -// sync test because we need to get all the requests to confirm their validity -test('install a scoped module from authed private registry', (): Promise => { - return runInstall({}, 'install-from-authed-private-registry', async config => { +test('install a scoped module from authed private registry', (): Promise => + runInstall({}, 'install-from-authed-private-registry', async config => { const authedRequests = request.__getAuthedRequests(); expect(authedRequests[0].url).toEqual('https://registry.yarnpkg.com/@types%2flodash'); @@ -727,11 +650,10 @@ test('install a scoped module from authed private registry', (): Promise = expect( (await fs.readFile(path.join(config.cwd, 'node_modules', '@types', 'lodash', 'index.d.ts'))).split('\n')[0], ).toEqual('// Type definitions for Lo-Dash 4.14'); - }); -}); + })); -test('install a scoped module from authed private registry with a missing trailing slash', (): Promise => { - return runInstall({}, 'install-from-authed-private-registry-no-slash', async config => { +test('install a scoped module from authed private registry with a missing trailing slash', (): Promise => + runInstall({}, 'install-from-authed-private-registry-no-slash', async config => { const authedRequests = request.__getAuthedRequests(); expect(authedRequests[0].url).toEqual('https://registry.yarnpkg.com/@types%2flodash'); @@ -742,11 +664,10 @@ test('install a scoped module from authed private registry with a missing traili expect( (await fs.readFile(path.join(config.cwd, 'node_modules', '@types', 'lodash', 'index.d.ts'))).split('\n')[0], ).toEqual('// Type definitions for Lo-Dash 4.14'); - }); -}); + })); -test.concurrent('install of scoped package with subdependency conflict should pass check', (): Promise => { - return runInstall({}, 'install-scoped-package-with-subdependency-conflict', async (config, reporter) => { +test('install of scoped package with subdependency conflict should pass check', (): Promise => + runInstall({}, 'install-scoped-package-with-subdependency-conflict', async (config, reporter) => { let allCorrect = true; try { await check(config, reporter, {integrity: false}, []); @@ -754,108 +675,83 @@ test.concurrent('install of scoped package with subdependency conflict should pa allCorrect = false; } expect(allCorrect).toBe(true); - }); -}); + })); -test.concurrent('install a module with incompatible optional dependency should skip dependency', (): Promise => { - return runInstall({}, 'install-should-skip-incompatible-optional-dep', async config => { +test('install a module with incompatible optional dependency should skip dependency', (): Promise => + runInstall({}, 'install-should-skip-incompatible-optional-dep', async config => { expect(await fs.exists(path.join(config.cwd, 'node_modules', 'dep-incompatible'))).toEqual(false); - }); -}); + })); -test.concurrent( - 'install a module with incompatible optional dependency should skip transient dependencies', - (): Promise => { - return runInstall({}, 'install-should-skip-incompatible-optional-dep', async config => { - expect(await fs.exists(path.join(config.cwd, 'node_modules', 'dep-a'))).toEqual(false); - }); - }, -); +test('install a module with incompatible optional dependency should skip transient dependencies', (): Promise => + runInstall({}, 'install-should-skip-incompatible-optional-dep', async config => { + expect(await fs.exists(path.join(config.cwd, 'node_modules', 'dep-a'))).toEqual(false); + })); -test.concurrent('install a module with optional dependency should skip incompatible transient dependency', (): Promise< - void, -> => { - return runInstall({}, 'install-should-skip-incompatible-optional-sub-dep', async config => { +test('install a module with optional dependency should skip incompatible transient dependency', (): Promise => + runInstall({}, 'install-should-skip-incompatible-optional-sub-dep', async config => { expect(await fs.exists(path.join(config.cwd, 'node_modules', 'dep-optional'))).toEqual(true); expect(await fs.exists(path.join(config.cwd, 'node_modules', 'dep-incompatible'))).toEqual(false); - }); -}); + })); // this tests for a problem occurring due to optional dependency incompatible with os, in this case fsevents // this would fail on os's incompatible with fsevents, which is everything except osx. if (process.platform !== 'darwin') { - test.concurrent( - 'install incompatible optional dependency should still install shared child dependencies', - (): Promise => { - return runInstall({}, 'install-should-not-skip-required-shared-deps', async config => { - expect(await fs.exists(path.join(config.cwd, 'node_modules', 'deep-extend'))).toEqual(true); - expect(await fs.exists(path.join(config.cwd, 'node_modules', 'ini'))).toEqual(true); - expect(await fs.exists(path.join(config.cwd, 'node_modules', 'strip-json-comments'))).toEqual(true); - }); - }, - ); + test('install incompatible optional dependency should still install shared child dependencies', (): Promise => + runInstall({}, 'install-should-not-skip-required-shared-deps', async config => { + expect(await fs.exists(path.join(config.cwd, 'node_modules', 'deep-extend'))).toEqual(true); + expect(await fs.exists(path.join(config.cwd, 'node_modules', 'ini'))).toEqual(true); + expect(await fs.exists(path.join(config.cwd, 'node_modules', 'strip-json-comments'))).toEqual(true); + })); } -test.concurrent('optional dependency that fails to build should not be installed', (): Promise => { - return runInstall({}, 'should-not-install-failing-optional-deps', async config => { +test('optional dependency that fails to build should not be installed', (): Promise => + runInstall({}, 'should-not-install-failing-optional-deps', async config => { expect(await fs.exists(path.join(config.cwd, 'node_modules', 'optional-failing'))).toEqual(false); - }); -}); + })); -test.concurrent('failing dependency of optional dependency should not be installed', (): Promise => { - return runInstall({}, 'should-not-install-failing-deps-of-optional-deps', async config => { +test('failing dependency of optional dependency should not be installed', (): Promise => + runInstall({}, 'should-not-install-failing-deps-of-optional-deps', async config => { expect(await fs.exists(path.join(config.cwd, 'node_modules', 'optional-dep'))).toEqual(true); expect(await fs.exists(path.join(config.cwd, 'node_modules', 'sub-failing'))).toEqual(false); - }); -}); + })); // Covers current behavior, issue opened whether this should be changed https://github.com/yarnpkg/yarn/issues/2274 -test.concurrent('a subdependency of an optional dependency that fails should be installed', (): Promise => { - return runInstall({}, 'should-install-failing-optional-sub-deps', async config => { +test('a subdependency of an optional dependency that fails should be installed', (): Promise => + runInstall({}, 'should-install-failing-optional-sub-deps', async config => { expect(await fs.exists(path.join(config.cwd, 'node_modules', 'optional-failing'))).toEqual(false); expect(await fs.exists(path.join(config.cwd, 'node_modules', 'sub-dep'))).toEqual(true); - }); -}); - -test.concurrent('a sub-dependency should be non-optional if any parents mark it non-optional', (): Promise => { - return runInstall( - {ignoreOptional: true}, - 'install-sub-dependency-if-any-parents-mark-it-non-optional', - async config => { - const deps = await fs.readdir(path.join(config.cwd, 'node_modules')); - - expect(deps).toEqual([ - '.yarn-integrity', - 'normal-dep', - 'normal-sub-dep', - 'normal-sub-sub-dep', - 'sub-dep', - 'sub-dep-2', - 'sub-sub-dep', - ]); - }, - ); -}); - -test.concurrent('should not loose dependencies when installing with --production', (): Promise => { - // revealed https://github.com/yarnpkg/yarn/issues/2263 - return runInstall({production: true}, 'prod-should-keep-subdeps', async config => { + })); + +test('a sub-dependency should be non-optional if any parents mark it non-optional', (): Promise => + runInstall({ignoreOptional: true}, 'install-sub-dependency-if-any-parents-mark-it-non-optional', async config => { + const deps = await fs.readdir(path.join(config.cwd, 'node_modules')); + + expect(deps).toEqual([ + '.yarn-integrity', + 'normal-dep', + 'normal-sub-dep', + 'normal-sub-sub-dep', + 'sub-dep', + 'sub-dep-2', + 'sub-sub-dep', + ]); + })); + +// revealed https://github.com/yarnpkg/yarn/issues/2263 +test('should not loose dependencies when installing with --production', (): Promise => + runInstall({production: true}, 'prod-should-keep-subdeps', async config => { // would be hoisted from gulp/vinyl-fs/glob-stream/minimatch/brace-expansion/balanced-match expect(await getPackageVersion(config, 'balanced-match')).toEqual('0.4.2'); - }); -}); + })); // https://github.com/yarnpkg/yarn/issues/2470 -test.concurrent('a allows dependency with [] in os cpu requirements', (): Promise => { - return runInstall({}, 'empty-os', async config => { +test('a allows dependency with [] in os cpu requirements', (): Promise => + runInstall({}, 'empty-os', async config => { expect(await fs.exists(path.join(config.cwd, 'node_modules', 'feed'))).toEqual(true); - }); -}); + })); -test.concurrent('should skip integrity check and do install when --skip-integrity-check flag is passed', (): Promise< - void, -> => { - return runInstall({}, 'skip-integrity-check', async (config, reporter) => { +test('should skip integrity check and do install when --skip-integrity-check flag is passed', (): Promise => + runInstall({}, 'skip-integrity-check', async (config, reporter) => { expect(await fs.exists(path.join(config.cwd, 'node_modules', 'sub-dep'))).toEqual(true); await fs.unlink(path.join(config.cwd, 'node_modules', 'sub-dep')); @@ -886,15 +782,10 @@ test.concurrent('should skip integrity check and do install when --skip-integrit // force rewrites lockfile newLockContent = await fs.readFile(path.join(config.cwd, 'yarn.lock')); expect(lockContent).not.toEqual(newLockContent); - }); -}); - -test.concurrent('should install if symlink source does not exist', async (): Promise => { - await runInstall({}, 'relative-symlinks-work', () => {}); -}); + })); -test.concurrent('bailout should work with --production flag too', (): Promise => { - return runInstall({production: true}, 'bailout-prod', async (config, reporter): Promise => { +test('bailout should work with --production flag too', (): Promise => + runInstall({production: true}, 'bailout-prod', async (config, reporter): Promise => { // remove file await fs.unlink(path.join(config.cwd, 'node_modules', 'left-pad', 'index.js')); // run install again @@ -902,42 +793,37 @@ test.concurrent('bailout should work with --production flag too', (): Promise => { - // Scenario: - // graceful-fs will install two versions, from @4.1.10 and @^4.1.11. The pattern @^4.1.2 would sometimes resolve - // to 4.1.10, if @^4.1.11 hadn't been processed before. Otherwise it would resolve to the result of @^4.1.11. - // Run an independent install and check, and see they have different results for @^4.1.2 - won't always see - // the bug, but its the best we can do without creating mock registry with controlled timing of responses. - return runInstall({}, 'install-deterministic-versions', async (config, reporter) => { + })); + +// Scenario: +// graceful-fs will install two versions, from @4.1.10 and @^4.1.11. The pattern @^4.1.2 would sometimes resolve +// to 4.1.10, if @^4.1.11 hadn't been processed before. Otherwise it would resolve to the result of @^4.1.11. +// Run an independent install and check, and see they have different results for @^4.1.2 - won't always see +// the bug, but its the best we can do without creating mock registry with controlled timing of responses. +test('package version resolve should be deterministic', (): Promise => + runInstall({}, 'install-deterministic-versions', async (config, reporter) => { await check(config, reporter, {integrity: true}, []); - }); -}); + })); -test.concurrent('transitive file: dependencies should work', (): Promise => { - return runInstall({}, 'transitive-file', async (config, reporter) => { +test('transitive file: dependencies should work', (): Promise => + runInstall({}, 'transitive-file', async (config, reporter) => { expect(await fs.exists(path.join(config.cwd, 'node_modules', 'b'))).toBe(true); - }); -}); + })); -test('unbound transitive dependencies should not conflict with top level dependency', async () => { - await runInstall({flat: true}, 'install-conflicts', async config => { +test('unbound transitive dependencies should not conflict with top level dependency', () => + runInstall({flat: true}, 'install-conflicts', async config => { expect((await fs.readJson(path.join(config.cwd, 'node_modules', 'left-pad', 'package.json'))).version).toEqual( '1.0.0', ); - }); -}); + })); -test('manifest optimization respects versions with alternation', async () => { - await runInstall({flat: true}, 'optimize-version-with-alternation', async config => { +test('manifest optimization respects versions with alternation', () => + runInstall({flat: true}, 'optimize-version-with-alternation', async config => { expect(await getPackageVersion(config, 'lodash')).toEqual('2.4.2'); - }); -}); + })); -test.concurrent('top level patterns should match after install', (): Promise => { - return runInstall({}, 'top-level-pattern-check', async (config, reporter) => { +test('top level patterns should match after install', (): Promise => + runInstall({}, 'top-level-pattern-check', async (config, reporter) => { let integrityError = false; try { await check(config, reporter, {integrity: true}, []); @@ -945,15 +831,12 @@ test.concurrent('top level patterns should match after install', (): Promise => { - const fixturesLoc = path.join(__dirname, '..', '..', 'fixtures', 'install'); - - return buildRun( +test('warns for missing bundledDependencies', (): Promise => + buildRun( reporters.BufferReporter, - fixturesLoc, + path.join(__dirname, '..', '..', 'fixtures', 'install'), async (args, flags, config, reporter): Promise => { await install(config, reporter, flags, args); @@ -971,12 +854,10 @@ test.concurrent('warns for missing bundledDependencies', (): Promise => { [], {}, 'missing-bundled-dep', - ); -}); + )); -test.concurrent('install will not overwrite linked scoped dependencies', async (): Promise => { - // install only dependencies - await runInstall({production: true}, 'install-dont-overwrite-linked', async (installConfig): Promise => { +test('install will not overwrite linked scoped dependencies', (): Promise => + runInstall({production: true}, 'install-dont-overwrite-linked', async (installConfig): Promise => { // link our fake dep to the registry await runLink([], {}, 'package-with-name-scoped', async (linkConfig): Promise => { // link our fake dependency in our node_modules @@ -998,12 +879,10 @@ test.concurrent('install will not overwrite linked scoped dependencies', async ( }, ); }); - }); -}); + })); -test.concurrent('install will not overwrite linked dependencies', async (): Promise => { - // install only dependencies - await runInstall({production: true}, 'install-dont-overwrite-linked', async (installConfig): Promise => { +test('install will not overwrite linked dependencies', (): Promise => + runInstall({production: true}, 'install-dont-overwrite-linked', async (installConfig): Promise => { // link our fake dep to the registry await runLink([], {}, 'package-with-name', async (linkConfig): Promise => { // link our fake dependency in our node_modules @@ -1022,17 +901,15 @@ test.concurrent('install will not overwrite linked dependencies', async (): Prom }); }); }); - }); -}); + })); // There was an issue where anything ending with `.git` would be sent to GitResolver, even if it was a file: dep. // This caused an error if you had a directory named "myModule.git" and tried to use it with "file:../myModule.git" // See https://github.com/yarnpkg/yarn/issues/3670 -test.concurrent('file: dependency ending with `.git` should work', (): Promise => { - return runInstall({}, 'local-named-git', async (config, reporter) => { +test('file: dependency ending with `.git` should work', (): Promise => + runInstall({}, 'local-named-git', async (config, reporter) => { expect(await fs.exists(path.join(config.cwd, 'node_modules', 'a'))).toBe(true); - }); -}); + })); // There was a warning being generated when a peerDep existed at a deeper level, and at the top level. // See https://github.com/yarnpkg/yarn/issues/4743 @@ -1044,11 +921,10 @@ test.concurrent('file: dependency ending with `.git` should work', (): Promise => { - return runInstall({}, 'peer-dep-included-at-2-levels', (config, reporter, install, getStdout) => { +test('install will not warn for missing peerDep when both shallower and deeper', (): Promise => + runInstall({}, 'peer-dep-included-at-2-levels', (config, reporter, install, getStdout) => { const stdout = getStdout(); const messageParts = reporter.lang('unmetPeer').split('undefined'); const warningMessage = messageParts.every(part => stdout.includes(part)); expect(warningMessage).toBe(false); - }); -}); + })); diff --git a/__tests__/commands/licenses.js b/__tests__/commands/licenses.js index 2cb3422bdb..0c8839dd2b 100644 --- a/__tests__/commands/licenses.js +++ b/__tests__/commands/licenses.js @@ -5,6 +5,8 @@ import {run as buildRun} from './_helpers.js'; import {run as licenses} from '../../src/cli/commands/licenses.js'; import Config from '../../src/config.js'; +jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; + const path = require('path'); const fixturesLoc = path.join(__dirname, '..', 'fixtures', 'licenses'); diff --git a/__tests__/fixtures/install/install-file-without-cache/comp/.gitignore b/__tests__/fixtures/install/install-file-without-cache/comp/.gitignore deleted file mode 100644 index 9d8a81a138..0000000000 --- a/__tests__/fixtures/install/install-file-without-cache/comp/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# this file will be generated -index.js diff --git a/__tests__/fixtures/install/install-file-without-cache/comp/index.js b/__tests__/fixtures/install/install-file-without-cache/comp/index.js new file mode 100644 index 0000000000..257cc5642c --- /dev/null +++ b/__tests__/fixtures/install/install-file-without-cache/comp/index.js @@ -0,0 +1 @@ +foo diff --git a/__tests__/fixtures/install/relative-symlinks-work/package.json b/__tests__/fixtures/install/relative-symlinks-work/package.json deleted file mode 100644 index a1807a8363..0000000000 --- a/__tests__/fixtures/install/relative-symlinks-work/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "dependencies": { - "ref": "https://github.com/icenium/ref/tarball/v1.3.2.3" - } -} diff --git a/__tests__/fixtures/install/relative-symlinks-work/yarn.lock b/__tests__/fixtures/install/relative-symlinks-work/yarn.lock deleted file mode 100644 index 64b236bf60..0000000000 --- a/__tests__/fixtures/install/relative-symlinks-work/yarn.lock +++ /dev/null @@ -1,34 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -bindings@1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.2.1.tgz#14ad6113812d2d37d72e67b4cacb4bb726505f11" - -debug@2: - version "2.6.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.1.tgz#79855090ba2c4e3115cc7d8769491d58f0491351" - dependencies: - ms "0.7.2" - -ms@0.7.2: - version "0.7.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765" - -nan@2: - version "2.5.1" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.5.1.tgz#d5b01691253326a97a2bbee9e61c55d8d60351e2" - -"prebuilt@https://github.com/tailsu/node-prebuilt/tarball/master": - version "0.1.0" - resolved "https://github.com/tailsu/node-prebuilt/tarball/master#be63229eaccee9c55bb67bc87eac527bdd640aa7" - -"ref@https://github.com/icenium/ref/tarball/v1.3.2.3": - version "1.3.2" - resolved "https://github.com/icenium/ref/tarball/v1.3.2.3#a38db0780c37c66453f3f096dc3ade802cc8ce77" - dependencies: - bindings "1" - debug "2" - nan "2" - prebuilt "https://github.com/tailsu/node-prebuilt/tarball/master" diff --git a/__tests__/util/request-manager.js b/__tests__/util/request-manager.js index 6d0ba848a9..1c4cc9fad0 100644 --- a/__tests__/util/request-manager.js +++ b/__tests__/util/request-manager.js @@ -8,6 +8,7 @@ import * as fs from '../../src/util/fs.js'; jasmine.DEFAULT_TIMEOUT_INTERVAL = 60000; const net = require('net'); +const http = require('http'); const https = require('https'); const path = require('path'); @@ -155,21 +156,17 @@ test('RequestManager.execute timeout error with maxRetryAttempts=1', async () => test('RequestManager.execute timeout error with default maxRetryAttempts', async () => { jest.useFakeTimers(); - const LIMIT = 5; let counter = 0; - const server = net.createServer(c => { + const server = http.createServer(req => { counter += 1; - // Trigger our offline retry queue which has a fixed 3 sec delay if (counter < LIMIT) { - c.on('close', jest.runOnlyPendingTimers.bind(jest)); + req.on('aborted', jest.runOnlyPendingTimers.bind(jest)); } - - // emulate TCP server that never closes the connection by not + // emulate HTTP server that never closes the connection by not // doing anything }); - try { server.listen(0); const config = await Config.create({networkTimeout: 50}); diff --git a/appveyor.yml b/appveyor.yml index 22f8f93556..eea5e60f9d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,6 +1,7 @@ environment: matrix: - node_version: '8' + - node_version: '10' branches: only: - master diff --git a/package.json b/package.json index e591166e1c..be787943dd 100644 --- a/package.json +++ b/package.json @@ -86,7 +86,7 @@ "gulp-sourcemaps": "^2.2.0", "gulp-util": "^3.0.7", "gulp-watch": "^5.0.0", - "jest": "^22.4.3", + "jest": "^22.4.4", "jsinspect": "^0.12.6", "minimatch": "^3.0.4", "mock-stdin": "^0.3.0", diff --git a/src/util/fs.js b/src/util/fs.js index 6935be628b..5016f8cca5 100644 --- a/src/util/fs.js +++ b/src/util/fs.js @@ -27,6 +27,7 @@ export const constants = export const lockQueue = new BlockingQueue('fs lock'); export const readFileBuffer = promisify(fs.readFile); +export const open: (path: string, flags: string, mode?: number) => Promise> = promisify(fs.open); export const writeFile: (path: string, data: string, options?: Object) => Promise = promisify(fs.writeFile); export const readlink: (path: string, opts: void) => Promise = promisify(fs.readlink); export const realpath: (path: string, opts: void) => Promise = promisify(fs.realpath); @@ -676,44 +677,37 @@ export async function find(filename: string, dir: string): Promise { try { const stats = await lstat(dest); - - if (stats.isSymbolicLink() && (await exists(dest))) { + if (stats.isSymbolicLink()) { const resolved = await realpath(dest); if (resolved === src) { return; } } - - await unlink(dest); } catch (err) { if (err.code !== 'ENOENT') { throw err; } } - - try { - if (process.platform === 'win32') { - // use directory junctions if possible on win32, this requires absolute paths - await fsSymlink(src, dest, 'junction'); - } else { - // use relative paths otherwise which will be retained if the directory is moved - let relative; - if (await exists(src)) { - relative = path.relative(fs.realpathSync(path.dirname(dest)), fs.realpathSync(src)); - } else { - relative = path.relative(path.dirname(dest), src); + // We use rimraf for unlink which never throws an ENOENT on missing target + await unlink(dest); + + if (process.platform === 'win32') { + // use directory junctions if possible on win32, this requires absolute paths + await fsSymlink(src, dest, 'junction'); + } else { + // use relative paths otherwise which will be retained if the directory is moved + let relative; + try { + relative = path.relative(fs.realpathSync(path.dirname(dest)), fs.realpathSync(src)); + } catch (err) { + if (err.code !== 'ENOENT') { + throw err; } - // When path.relative returns an empty string for the current directory, we should instead use - // '.', which is a valid fs.symlink target. - await fsSymlink(relative || '.', dest); - } - } catch (err) { - if (err.code === 'EEXIST') { - // race condition - await symlink(src, dest); - } else { - throw err; + relative = path.relative(path.dirname(dest), src); } + // When path.relative returns an empty string for the current directory, we should instead use + // '.', which is a valid fs.symlink target. + await fsSymlink(relative || '.', dest); } } @@ -828,15 +822,8 @@ export async function readFirstAvailableStream( for (const tarballPath of paths) { if (tarballPath) { try { - // We need the weird `await new Promise()` construct for `createReadStream` because - // it always returns a ReadStream object but immediately triggers an `error` event - // on it if it fails to open the file, instead of throwing an exception. If this event - // is not handled, it crashes node. A saner way to handle this with multiple tries is - // the following construct. - stream = await new Promise((resolve, reject) => { - const maybeStream = fs.createReadStream(tarballPath); - maybeStream.on('error', reject).on('readable', resolve.bind(this, maybeStream)); - }); + const fd = await open(tarballPath, 'r'); + stream = fs.createReadStream('', {fd}); break; } catch (err) { // Try the next one @@ -844,7 +831,6 @@ export async function readFirstAvailableStream( } } } - return {stream, triedPaths}; } diff --git a/yarn.lock b/yarn.lock index 87129823ef..d7e58bc700 100644 --- a/yarn.lock +++ b/yarn.lock @@ -541,12 +541,12 @@ babel-helpers@^6.24.1: babel-runtime "^6.22.0" babel-template "^6.24.1" -babel-jest@^22.4.3: - version "22.4.3" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-22.4.3.tgz#4b7a0b6041691bbd422ab49b3b73654a49a6627a" +babel-jest@^22.4.4: + version "22.4.4" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-22.4.4.tgz#977259240420e227444ebe49e226a61e49ea659d" dependencies: babel-plugin-istanbul "^4.1.5" - babel-preset-jest "^22.4.3" + babel-preset-jest "^22.4.4" babel-loader@^6.2.5: version "6.4.1" @@ -581,9 +581,9 @@ babel-plugin-istanbul@^4.1.5: istanbul-lib-instrument "^1.7.5" test-exclude "^4.1.1" -babel-plugin-jest-hoist@^22.4.3: - version "22.4.3" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-22.4.3.tgz#7d8bcccadc2667f96a0dcc6afe1891875ee6c14a" +babel-plugin-jest-hoist@^22.4.4: + version "22.4.4" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-22.4.4.tgz#b9851906eab34c7bf6f8c895a2b08bea1a844c0b" babel-plugin-syntax-async-functions@^6.8.0: version "6.13.0" @@ -965,11 +965,11 @@ babel-preset-flow@^6.23.0: dependencies: babel-plugin-transform-flow-strip-types "^6.22.0" -babel-preset-jest@^22.4.3: - version "22.4.3" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-22.4.3.tgz#e92eef9813b7026ab4ca675799f37419b5a44156" +babel-preset-jest@^22.4.4: + version "22.4.4" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-22.4.4.tgz#ec9fbd8bcd7dfd24b8b5320e0e688013235b7c39" dependencies: - babel-plugin-jest-hoist "^22.4.3" + babel-plugin-jest-hoist "^22.4.4" babel-plugin-syntax-object-rest-spread "^6.13.0" babel-preset-stage-0@^6.0.0: @@ -2421,7 +2421,7 @@ expand-tilde@^1.2.1, expand-tilde@^1.2.2: dependencies: os-homedir "^1.0.1" -expect@^22.4.3: +expect@^22.4.0: version "22.4.3" resolved "https://registry.yarnpkg.com/expect/-/expect-22.4.3.tgz#d5a29d0a0e1fb2153557caef2674d4547e914674" dependencies: @@ -3782,15 +3782,15 @@ iterall@^1.2.0: version "1.2.1" resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.1.tgz#59a347ae8001d2d4bc546b8487ca755d61849965" -jest-changed-files@^22.4.3: +jest-changed-files@^22.2.0: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-22.4.3.tgz#8882181e022c38bd46a2e4d18d44d19d90a90fb2" dependencies: throat "^4.0.0" -jest-cli@^22.4.3: - version "22.4.3" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-22.4.3.tgz#bf16c4a5fb7edc3fa5b9bb7819e34139e88a72c7" +jest-cli@^22.4.4: + version "22.4.4" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-22.4.4.tgz#68cd2a2aae983adb1e6638248ca21082fd6d9e90" dependencies: ansi-escapes "^3.0.0" chalk "^2.0.1" @@ -3803,20 +3803,20 @@ jest-cli@^22.4.3: istanbul-lib-coverage "^1.1.1" istanbul-lib-instrument "^1.8.0" istanbul-lib-source-maps "^1.2.1" - jest-changed-files "^22.4.3" - jest-config "^22.4.3" - jest-environment-jsdom "^22.4.3" - jest-get-type "^22.4.3" - jest-haste-map "^22.4.3" - jest-message-util "^22.4.3" - jest-regex-util "^22.4.3" - jest-resolve-dependencies "^22.4.3" - jest-runner "^22.4.3" - jest-runtime "^22.4.3" - jest-snapshot "^22.4.3" - jest-util "^22.4.3" - jest-validate "^22.4.3" - jest-worker "^22.4.3" + jest-changed-files "^22.2.0" + jest-config "^22.4.4" + jest-environment-jsdom "^22.4.1" + jest-get-type "^22.1.0" + jest-haste-map "^22.4.2" + jest-message-util "^22.4.0" + jest-regex-util "^22.1.0" + jest-resolve-dependencies "^22.1.0" + jest-runner "^22.4.4" + jest-runtime "^22.4.4" + jest-snapshot "^22.4.0" + jest-util "^22.4.1" + jest-validate "^22.4.4" + jest-worker "^22.2.2" micromatch "^2.3.11" node-notifier "^5.2.1" realpath-native "^1.0.0" @@ -3827,23 +3827,23 @@ jest-cli@^22.4.3: which "^1.2.12" yargs "^10.0.3" -jest-config@^22.4.3: - version "22.4.3" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-22.4.3.tgz#0e9d57db267839ea31309119b41dc2fa31b76403" +jest-config@^22.4.4: + version "22.4.4" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-22.4.4.tgz#72a521188720597169cd8b4ff86934ef5752d86a" dependencies: chalk "^2.0.1" glob "^7.1.1" - jest-environment-jsdom "^22.4.3" - jest-environment-node "^22.4.3" - jest-get-type "^22.4.3" - jest-jasmine2 "^22.4.3" - jest-regex-util "^22.4.3" - jest-resolve "^22.4.3" - jest-util "^22.4.3" - jest-validate "^22.4.3" - pretty-format "^22.4.3" - -jest-diff@^22.4.3: + jest-environment-jsdom "^22.4.1" + jest-environment-node "^22.4.1" + jest-get-type "^22.1.0" + jest-jasmine2 "^22.4.4" + jest-regex-util "^22.1.0" + jest-resolve "^22.4.2" + jest-util "^22.4.1" + jest-validate "^22.4.4" + pretty-format "^22.4.0" + +jest-diff@^22.4.0, jest-diff@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-22.4.3.tgz#e18cc3feff0aeef159d02310f2686d4065378030" dependencies: @@ -3856,13 +3856,13 @@ jest-docblock@^20.0.1: version "20.0.3" resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-20.0.3.tgz#17bea984342cc33d83c50fbe1545ea0efaa44712" -jest-docblock@^22.4.3: +jest-docblock@^22.4.0, jest-docblock@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-22.4.3.tgz#50886f132b42b280c903c592373bb6e93bb68b19" dependencies: detect-newline "^2.1.0" -jest-environment-jsdom@^22.4.3: +jest-environment-jsdom@^22.4.1: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-22.4.3.tgz#d67daa4155e33516aecdd35afd82d4abf0fa8a1e" dependencies: @@ -3870,18 +3870,18 @@ jest-environment-jsdom@^22.4.3: jest-util "^22.4.3" jsdom "^11.5.1" -jest-environment-node@^22.4.3: +jest-environment-node@^22.4.1: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-22.4.3.tgz#54c4eaa374c83dd52a9da8759be14ebe1d0b9129" dependencies: jest-mock "^22.4.3" jest-util "^22.4.3" -jest-get-type@^22.4.3: +jest-get-type@^22.1.0, jest-get-type@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.4.3.tgz#e3a8504d8479342dd4420236b322869f18900ce4" -jest-haste-map@^22.4.3: +jest-haste-map@^22.4.2: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-22.4.3.tgz#25842fa2ba350200767ac27f658d58b9d5c2e20b" dependencies: @@ -3893,29 +3893,29 @@ jest-haste-map@^22.4.3: micromatch "^2.3.11" sane "^2.0.0" -jest-jasmine2@^22.4.3: - version "22.4.3" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-22.4.3.tgz#4daf64cd14c793da9db34a7c7b8dcfe52a745965" +jest-jasmine2@^22.4.4: + version "22.4.4" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-22.4.4.tgz#c55f92c961a141f693f869f5f081a79a10d24e23" dependencies: chalk "^2.0.1" co "^4.6.0" - expect "^22.4.3" + expect "^22.4.0" graceful-fs "^4.1.11" is-generator-fn "^1.0.0" - jest-diff "^22.4.3" - jest-matcher-utils "^22.4.3" - jest-message-util "^22.4.3" - jest-snapshot "^22.4.3" - jest-util "^22.4.3" + jest-diff "^22.4.0" + jest-matcher-utils "^22.4.0" + jest-message-util "^22.4.0" + jest-snapshot "^22.4.0" + jest-util "^22.4.1" source-map-support "^0.5.0" -jest-leak-detector@^22.4.3: +jest-leak-detector@^22.4.0: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-22.4.3.tgz#2b7b263103afae8c52b6b91241a2de40117e5b35" dependencies: pretty-format "^22.4.3" -jest-matcher-utils@^22.4.3: +jest-matcher-utils@^22.4.0, jest-matcher-utils@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-22.4.3.tgz#4632fe428ebc73ebc194d3c7b65d37b161f710ff" dependencies: @@ -3923,7 +3923,7 @@ jest-matcher-utils@^22.4.3: jest-get-type "^22.4.3" pretty-format "^22.4.3" -jest-message-util@^22.4.3: +jest-message-util@^22.4.0, jest-message-util@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-22.4.3.tgz#cf3d38aafe4befddbfc455e57d65d5239e399eb7" dependencies: @@ -3937,56 +3937,56 @@ jest-mock@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-22.4.3.tgz#f63ba2f07a1511772cdc7979733397df770aabc7" -jest-regex-util@^22.4.3: +jest-regex-util@^22.1.0, jest-regex-util@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-22.4.3.tgz#a826eb191cdf22502198c5401a1fc04de9cef5af" -jest-resolve-dependencies@^22.4.3: +jest-resolve-dependencies@^22.1.0: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-22.4.3.tgz#e2256a5a846732dc3969cb72f3c9ad7725a8195e" dependencies: jest-regex-util "^22.4.3" -jest-resolve@^22.4.3: +jest-resolve@^22.4.2: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-22.4.3.tgz#0ce9d438c8438229aa9b916968ec6b05c1abb4ea" dependencies: browser-resolve "^1.11.2" chalk "^2.0.1" -jest-runner@^22.4.3: - version "22.4.3" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-22.4.3.tgz#298ddd6a22b992c64401b4667702b325e50610c3" +jest-runner@^22.4.4: + version "22.4.4" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-22.4.4.tgz#dfca7b7553e0fa617e7b1291aeb7ce83e540a907" dependencies: exit "^0.1.2" - jest-config "^22.4.3" - jest-docblock "^22.4.3" - jest-haste-map "^22.4.3" - jest-jasmine2 "^22.4.3" - jest-leak-detector "^22.4.3" - jest-message-util "^22.4.3" - jest-runtime "^22.4.3" - jest-util "^22.4.3" - jest-worker "^22.4.3" + jest-config "^22.4.4" + jest-docblock "^22.4.0" + jest-haste-map "^22.4.2" + jest-jasmine2 "^22.4.4" + jest-leak-detector "^22.4.0" + jest-message-util "^22.4.0" + jest-runtime "^22.4.4" + jest-util "^22.4.1" + jest-worker "^22.2.2" throat "^4.0.0" -jest-runtime@^22.4.3: - version "22.4.3" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-22.4.3.tgz#b69926c34b851b920f666c93e86ba2912087e3d0" +jest-runtime@^22.4.4: + version "22.4.4" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-22.4.4.tgz#9ba7792fc75582a5be0f79af6f8fe8adea314048" dependencies: babel-core "^6.0.0" - babel-jest "^22.4.3" + babel-jest "^22.4.4" babel-plugin-istanbul "^4.1.5" chalk "^2.0.1" convert-source-map "^1.4.0" exit "^0.1.2" graceful-fs "^4.1.11" - jest-config "^22.4.3" - jest-haste-map "^22.4.3" - jest-regex-util "^22.4.3" - jest-resolve "^22.4.3" - jest-util "^22.4.3" - jest-validate "^22.4.3" + jest-config "^22.4.4" + jest-haste-map "^22.4.2" + jest-regex-util "^22.1.0" + jest-resolve "^22.4.2" + jest-util "^22.4.1" + jest-validate "^22.4.4" json-stable-stringify "^1.0.1" micromatch "^2.3.11" realpath-native "^1.0.0" @@ -3999,7 +3999,7 @@ jest-serializer@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-22.4.3.tgz#a679b81a7f111e4766235f4f0c46d230ee0f7436" -jest-snapshot@^22.4.3: +jest-snapshot@^22.4.0: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-22.4.3.tgz#b5c9b42846ffb9faccb76b841315ba67887362d2" dependencies: @@ -4010,7 +4010,7 @@ jest-snapshot@^22.4.3: natural-compare "^1.4.0" pretty-format "^22.4.3" -jest-util@^22.4.3: +jest-util@^22.4.1, jest-util@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-22.4.3.tgz#c70fec8eec487c37b10b0809dc064a7ecf6aafac" dependencies: @@ -4022,28 +4022,28 @@ jest-util@^22.4.3: mkdirp "^0.5.1" source-map "^0.6.0" -jest-validate@^22.4.3: - version "22.4.3" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-22.4.3.tgz#0780954a5a7daaeec8d3c10834b9280865976b30" +jest-validate@^22.4.4: + version "22.4.4" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-22.4.4.tgz#1dd0b616ef46c995de61810d85f57119dbbcec4d" dependencies: chalk "^2.0.1" - jest-config "^22.4.3" - jest-get-type "^22.4.3" + jest-config "^22.4.4" + jest-get-type "^22.1.0" leven "^2.1.0" - pretty-format "^22.4.3" + pretty-format "^22.4.0" -jest-worker@^22.4.3: +jest-worker@^22.2.2, jest-worker@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-22.4.3.tgz#5c421417cba1c0abf64bf56bd5fb7968d79dd40b" dependencies: merge-stream "^1.0.1" -jest@^22.4.3: - version "22.4.3" - resolved "https://registry.yarnpkg.com/jest/-/jest-22.4.3.tgz#2261f4b117dc46d9a4a1a673d2150958dee92f16" +jest@^22.4.4: + version "22.4.4" + resolved "https://registry.yarnpkg.com/jest/-/jest-22.4.4.tgz#ffb36c9654b339a13e10b3d4b338eb3e9d49f6eb" dependencies: import-local "^1.0.0" - jest-cli "^22.4.3" + jest-cli "^22.4.4" jodid25519@^1.0.0: version "1.0.2" @@ -4325,10 +4325,6 @@ lodash.clone@~4.3.2: dependencies: lodash._baseclone "~4.5.0" -lodash.endswith@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/lodash.endswith/-/lodash.endswith-4.2.1.tgz#fed59ac1738ed3e236edd7064ec456448b37bc09" - lodash.escape@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-3.2.0.tgz#995ee0dc18c1b48cc92effae71a10aab5b487698" @@ -4347,10 +4343,6 @@ lodash.isempty@^4.2.1: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.isempty/-/lodash.isempty-4.4.0.tgz#6f86cbedd8be4ec987be9aaf33c9684db1b31e7e" -lodash.isfunction@^3.0.8: - version "3.0.9" - resolved "https://registry.yarnpkg.com/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz#06de25df4db327ac931981d1bdb067e5af68d051" - lodash.isplainobject@^4.0.4: version "4.0.6" resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" @@ -4387,10 +4379,6 @@ lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" -lodash.startswith@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/lodash.startswith/-/lodash.startswith-4.2.1.tgz#c598c4adce188a27e53145731cdc6c0e7177600c" - lodash.template@^3.0.0: version "3.6.2" resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-3.6.2.tgz#f8cdecc6169a255be9098ae8b0c53d378931d14f" @@ -5146,7 +5134,7 @@ prettier@^1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.5.2.tgz#7ea0751da27b93bfb6cecfcec509994f52d83bb3" -pretty-format@^22.4.3: +pretty-format@^22.4.0, pretty-format@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-22.4.3.tgz#f873d780839a9c02e9664c8a082e9ee79eaac16f" dependencies: @@ -5577,13 +5565,13 @@ right-pad@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/right-pad/-/right-pad-1.0.1.tgz#8ca08c2cbb5b55e74dafa96bf7fd1a27d568c8d0" -rimraf@2, rimraf@^2.2.8, rimraf@^2.5.0, rimraf@^2.5.1, rimraf@^2.6.1: +rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1, 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" -rimraf@^2.5.4: +rimraf@^2.5.0, rimraf@^2.5.4: version "2.6.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" dependencies: @@ -6355,13 +6343,8 @@ unset-value@^1.0.0: isobject "^3.0.0" upath@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/upath/-/upath-1.0.2.tgz#80aaae5395abc5fd402933ae2f58694f0860204c" - dependencies: - lodash.endswith "^4.2.1" - lodash.isfunction "^3.0.8" - lodash.isstring "^4.0.1" - lodash.startswith "^4.2.1" + version "1.1.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd" urix@^0.1.0, urix@~0.1.0: version "0.1.0"