Best JavaScript code snippet using cypress
integration.js
Source:integration.js
...37}38beforeEach(request.__resetAuthedRequests);39afterEach(request.__resetAuthedRequests);40test('install should not copy the .bin folders from the cache', () =>41 runInstall({}, 'install-no-bin', async config => {42 expect(await fs.exists(`${config.cwd}/node_modules/is-pnp/.bin`)).toEqual(false);43 }));44test('install should not hoist packages above their peer dependencies', () =>45 runInstall({}, 'install-should-not-hoist-through-peer-deps', async config => {46 expect(await fs.exists(`${config.cwd}/node_modules/a/node_modules/c`)).toEqual(true);47 }));48test('install should resolve peer dependencies from same subtrees', () =>49 runInstall({}, 'peer-dep-same-subtree', async config => {50 expect(JSON.parse(await fs.readFile(`${config.cwd}/node_modules/d/node_modules/a/package.json`)).version).toEqual(51 '1.0.0',52 );53 expect(JSON.parse(await fs.readFile(`${config.cwd}/node_modules//a/package.json`)).version).toEqual('1.1.0');54 expect(fs.exists(`${config.cwd}/node_modules/c/node_modules/a`)).resolves.toEqual(false);55 }));56test('install optional subdependencies by default', () =>57 runInstall({}, 'install-optional-dependencies', config => {58 expect(fs.exists(`${config.cwd}/node_modules/dep-b`)).resolves.toEqual(true);59 }));60test('installing with --ignore-optional should not install optional subdependencies', () =>61 runInstall({ignoreOptional: true}, 'install-optional-dependencies', config => {62 expect(fs.exists(`${config.cwd}/node_modules/dep-b`)).resolves.toEqual(false);63 expect(fs.exists(`${config.cwd}/node_modules/dep-c`)).resolves.toEqual(true);64 expect(fs.exists(`${config.cwd}/node_modules/dep-d`)).resolves.toEqual(true);65 expect(fs.exists(`${config.cwd}/node_modules/dep-e`)).resolves.toEqual(true);66 }));67test('running install inside a workspace should run the install from the root of the workspace', () =>68 runInstall({}, 'install-workspaces', async (config, reporter): Promise<void> => {69 const pkgJson = await fs.readJson(`${config.cwd}/workspace/package.json`);70 pkgJson.dependencies['b'] = 'file:../b';71 await fs.writeFile(`${config.cwd}/workspace/package.json`, JSON.stringify(pkgJson));72 const workspaceConfig = await Config.create({cwd: `${config.cwd}/workspace`}, reporter);73 const reInstall = new Install({}, workspaceConfig, reporter, await Lockfile.fromDirectory(config.cwd));74 await reInstall.init();75 const lockfileContent = await fs.readFile(`${config.cwd}/yarn.lock`);76 expect(lockfileContent).toEqual(expect.stringContaining(`"b@file:b"`));77 expect(lockfileContent).toEqual(expect.stringContaining(`"a@file:./a"`));78 }));79test('packages installed through the link protocol should validate all peer dependencies', () =>80 runInstall({checkFiles: true}, 'check-files-should-not-cross-symlinks', async config => {81 expect(82 JSON.parse(await fs.readFile(`${config.cwd}/node_modules/.yarn-integrity`)).files.map(file =>83 file.replace(/\\/g, '/'),84 ),85 ).toEqual(['some-missing-pkg', 'some-other-pkg', 'some-pkg/package.json']);86 }));87test('installing a package with a renamed file should not delete it', () =>88 runInstall({}, 'case-sensitivity', async (config, reporter): Promise<void> => {89 const pkgJson = await fs.readJson(`${config.cwd}/package.json`);90 pkgJson.dependencies['pkg'] = 'file:./pkg-b';91 await fs.writeFile(`${config.cwd}/package.json`, JSON.stringify(pkgJson));92 const reInstall = new Install({}, config, reporter, await Lockfile.fromDirectory(config.cwd));93 await reInstall.init();94 expect(await fs.exists(`${config.cwd}/node_modules/pkg/state.js`)).toEqual(true);95 }));96test("installing a tree shouldn't remove preexisting cache directories", () =>97 runInstall({}, 'cache-folder-nm', async (config, reporter): Promise<void> => {98 expect(await fs.exists(`${config.cwd}/node_modules/.cache/hello.txt`)).toEqual(true);99 const reInstall = new Install({}, config, reporter, await Lockfile.fromDirectory(config.cwd));100 await reInstall.init();101 expect(await fs.exists(`${config.cwd}/node_modules/.cache/hello.txt`)).toEqual(true);102 }));103test("installing a new package should correctly update it, even if the files mtime didn't change", () =>104 runInstall({}, 'mtime-same', async (config, reporter): Promise<void> => {105 await misc.sleep(2000);106 const pkgJson = await fs.readJson(`${config.cwd}/package.json`);107 pkgJson.dependencies['pkg'] = 'file:./pkg-b.tgz';108 await fs.writeFile(`${config.cwd}/package.json`, JSON.stringify(pkgJson));109 const reInstall = new Install({}, config, reporter, await Lockfile.fromDirectory(config.cwd));110 await reInstall.init();111 expect(await fs.readJson(`${config.cwd}/node_modules/pkg/package.json`)).toMatchObject({version: '2.0.0'});112 }));113test('properly find and save build artifacts', () =>114 runInstall({}, 'artifacts-finds-and-saves', async config => {115 const integrity = await fs.readJson(path.join(config.cwd, 'node_modules', constants.INTEGRITY_FILENAME));116 expect(integrity.artifacts['dummy@0.0.0']).toEqual(['dummy', path.join('dummy', 'dummy.txt'), 'dummy.txt']);117 // retains artifact118 const moduleFolder = path.join(config.cwd, 'node_modules', 'dummy');119 expect(fs.readFile(path.join(moduleFolder, 'dummy.txt'))).resolves.toEqual('foobar');120 expect(fs.readFile(path.join(moduleFolder, 'dummy', 'dummy.txt'))).resolves.toEqual('foobar');121 }));122test('reading a lockfile should not optimize it', () =>123 runInstall({}, 'lockfile-optimization', async (config, reporter): Promise<void> => {124 const was = await fs.readFile(`${__dirname}/../../fixtures/install/lockfile-optimization/yarn.lock`);125 const is = await fs.readFile(`${config.cwd}/yarn.lock`);126 expect(is).toEqual(was);127 }));128test('creates a symlink to a directory when using the link: protocol', () =>129 runInstall({}, 'install-link', async config => {130 const expectPath = path.join(config.cwd, 'node_modules', 'test-absolute');131 const stat = await fs.lstat(expectPath);132 expect(stat.isSymbolicLink()).toEqual(true);133 const target = await fs.readlink(expectPath);134 expect(path.resolve(config.cwd, target)).toMatch(/[\\\/]bar$/);135 }));136test('creates a symlink to a non-existing directory when using the link: protocol', () =>137 runInstall({}, 'install-link', async config => {138 const expectPath = path.join(config.cwd, 'node_modules', 'test-missing');139 const stat = await fs.lstat(expectPath);140 expect(stat.isSymbolicLink()).toEqual(true);141 const target = await fs.readlink(expectPath);142 if (process.platform !== 'win32') {143 expect(target).toEqual('../baz');144 } else {145 expect(target).toMatch(/[\\\/]baz[\\\/]$/);146 }147 }));148test('resolves the symlinks relative to the package path when using the link: protocol; not the node_modules', () =>149 runInstall({}, 'install-link', async config => {150 const expectPath = path.join(config.cwd, 'node_modules', 'test-relative');151 const stat = await fs.lstat(expectPath);152 expect(stat.isSymbolicLink()).toEqual(true);153 const target = await fs.readlink(expectPath);154 if (process.platform !== 'win32') {155 expect(target).toEqual('../bar');156 } else {157 expect(target).toMatch(/[\\\/]bar[\\\/]$/);158 }159 }));160test('resolves the symlinks of other symlinked packages relative to the package using the link: protocol', () =>161 runInstall({}, 'install-link-nested', async config => {162 const expectPath = path.join(config.cwd, 'node_modules', 'b');163 const stat = await fs.lstat(expectPath);164 expect(stat.isSymbolicLink()).toEqual(true);165 const target = await fs.readlink(expectPath);166 if (process.platform !== 'win32') {167 expect(target).toEqual('../a/b');168 } else {169 expect(target).toMatch(/[\\\/]b[\\\/]$/);170 }171 }));172test('replace the symlink when it changes, when using the link: protocol', () =>173 runInstall({}, 'install-link', async (config, reporter): Promise<void> => {174 const lockfile = await Lockfile.fromDirectory(config.cwd);175 const pkgJson = await fs.readJson(`${config.cwd}/package.json`);176 pkgJson.dependencies['test-missing'] = 'link:barbaz';177 await fs.writeFile(`${config.cwd}/package.json`, JSON.stringify(pkgJson));178 const reInstall = new Install({}, config, reporter, lockfile);179 await reInstall.init();180 const expectPath = path.join(config.cwd, 'node_modules', 'test-missing');181 const stat = await fs.lstat(expectPath);182 expect(stat.isSymbolicLink()).toEqual(true);183 const target = await fs.readlink(expectPath);184 if (process.platform !== 'win32') {185 expect(target).toEqual('../barbaz');186 } else {187 expect(target).toMatch(/[\\\/]barbaz[\\\/]$/);188 }189 }));190test('changes the cache path when bumping the cache version', () =>191 runInstall({}, 'install-github', async config => {192 const inOut = new stream.PassThrough();193 const reporter = new reporters.JSONReporter({stdout: inOut});194 await cache(config, reporter, {}, ['dir']);195 expect((JSON.parse(String(inOut.read())): any).data).toMatch(/[\\\/]v(?!42[\\\/]?$)[0-9]+[\\\/]?$/);196 await mockConstants(config, {CACHE_VERSION: 42}, async config => {197 await cache(config, reporter, {}, ['dir']);198 expect((JSON.parse(String(inOut.read())): any).data).toMatch(/[\\\/]v42([\\\/].*)?$/);199 });200 }));201test('changes the cache directory when bumping the cache version', () =>202 runInstall({}, 'install-production', async (config, reporter): Promise<void> => {203 const lockfile = await Lockfile.fromDirectory(config.cwd);204 const resolver = new PackageResolver(config, lockfile);205 await resolver.init([{pattern: 'is-array', registry: 'npm'}]);206 const ref = resolver.getManifests()[0]._reference;207 const cachePath = config.generateModuleCachePath(ref);208 await fs.writeFile(path.join(cachePath, 'yarn.test'), 'YARN TEST');209 await fs.unlink(path.join(config.cwd, 'node_modules'));210 const firstReinstall = new Install({skipIntegrityCheck: true}, config, reporter, lockfile);211 await firstReinstall.init();212 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'is-array', 'yarn.test'))).toEqual(true);213 await mockConstants(config, {CACHE_VERSION: 42}, async config => {214 const secondReinstall = new Install({skipIntegrityCheck: true}, config, reporter, lockfile);215 await secondReinstall.init();216 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'is-array', 'yarn.test'))).toEqual(false);217 });218 }));219test("removes extraneous files that aren't in module or artifacts", () => {220 async function check(cwd: string): Promise<void> {221 // retains artifact222 const moduleFolder = path.join(cwd, 'node_modules', 'dummy');223 expect(await fs.readFile(path.join(moduleFolder, 'dummy.txt'))).toEqual('foobar');224 expect(await fs.readFile(path.join(moduleFolder, 'dummy', 'dummy.txt'))).toEqual('foobar');225 // removes extraneous226 expect(await fs.exists(path.join(moduleFolder, 'dummy2.txt'))).toEqual(false);227 }228 async function create(cwd: string): Promise<void> {229 // create an extraneous file230 const moduleFolder = path.join(cwd, 'node_modules', 'dummy');231 await fs.mkdirp(moduleFolder);232 await fs.writeFile(path.join(moduleFolder, 'dummy2.txt'), 'foobar');233 }234 return runInstall(235 {},236 'artifacts-finds-and-saves',237 async config => {238 await check(config.cwd);239 await create(config.cwd);240 // run install again241 const install = new Install({force: true}, config, config.reporter, new Lockfile());242 await install.init();243 await check(config.cwd);244 },245 create,246 );247});248test("production mode with deduped dev dep shouldn't be removed", () =>249 runInstall({production: true}, 'install-prod-deduped-dev-dep', async config => {250 expect((await fs.readJson(path.join(config.cwd, 'node_modules', 'a', 'package.json'))).version).toEqual('1.0.0');251 expect((await fs.readJson(path.join(config.cwd, 'node_modules', 'c', 'package.json'))).version).toEqual('1.0.0');252 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'b'))).toEqual(false);253 }));254test("production mode dep on package in dev deps shouldn't be removed", () =>255 runInstall({production: true}, 'install-prod-deduped-direct-dev-dep', async config => {256 expect((await fs.readJson(path.join(config.cwd, 'node_modules', 'a', 'package.json'))).version).toEqual('1.0.0');257 expect((await fs.readJson(path.join(config.cwd, 'node_modules', 'b', 'package.json'))).version).toEqual('1.0.0');258 expect((await fs.readJson(path.join(config.cwd, 'node_modules', 'c', 'package.json'))).version).toEqual('1.0.0');259 }));260test('hoisting should factor ignored dependencies', async () => {261 // you should only modify this test if you know what you're doing262 // when we calculate hoisting we need to factor in ignored dependencies in it263 // so we get deterministic hoisting across environments, for example in production mode264 // we should still be taking dev dependencies into consideration265 async function checkNormal(config): Promise<void> {266 expect((await fs.readJson(path.join(config.cwd, 'node_modules', 'a', 'package.json'))).version).toEqual('1.0.0');267 expect((await fs.readJson(path.join(config.cwd, 'node_modules', 'd', 'package.json'))).version).toEqual('1.0.0');268 expect(269 (await fs.readJson(path.join(config.cwd, 'node_modules', 'd', 'node_modules', 'c', 'package.json'))).version,270 ).toEqual('2.0.0');271 }272 await runInstall({}, 'install-ignored-retains-hoisting-structure', async config => {273 await checkNormal(config);274 expect((await fs.readJson(path.join(config.cwd, 'node_modules', 'b', 'package.json'))).version).toEqual('3.0.0');275 expect((await fs.readJson(path.join(config.cwd, 'node_modules', 'c', 'package.json'))).version).toEqual('5.0.0');276 });277 await runInstall({production: true}, 'install-ignored-retains-hoisting-structure', async config => {278 await checkNormal(config);279 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'b'))).toEqual(false);280 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'c'))).toEqual(false);281 });282});283test('--production flag ignores dev dependencies', () =>284 runInstall({production: true}, 'install-production', async config => {285 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'left-pad'))).toEqual(false);286 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'is-array'))).toEqual(true);287 }));288test('--production flag does not link dev dependency bin scripts', () =>289 runInstall({production: true, binLinks: true}, 'install-production-bin', async config => {290 expect(await fs.exists(path.join(config.cwd, 'node_modules', '.bin', 'touch'))).toEqual(false);291 expect(await fs.exists(path.join(config.cwd, 'node_modules', '.bin', 'rimraf'))).toEqual(true);292 }));293test('root install with optional deps', () => runInstall({}, 'root-install-with-optional-dependency'));294test('install file: protocol with relative paths', () =>295 runInstall({}, 'install-file-relative', async config => {296 expect(await fs.readFile(path.join(config.cwd, 'node_modules', 'root-a', 'index.js'))).toEqual('foobar;\n');297 }));298test('install file: protocol without force retains installed package', () =>299 runInstall({}, 'install-file-without-cache', async (config, reporter) => {300 expect(await fs.readFile(path.join(config.cwd, 'node_modules', 'comp', 'index.js'))).toEqual('foo\n');301 await fs.writeFile(path.join(config.cwd, 'comp', 'index.js'), 'bar\n');302 const reinstall = new Install({}, config, reporter, await Lockfile.fromDirectory(config.cwd));303 await reinstall.init();304 expect(await fs.readFile(path.join(config.cwd, 'node_modules', 'comp', 'index.js'))).not.toEqual('bar\n');305 }));306test('install file: protocol with force re-installs local package', () =>307 runInstall({}, 'install-file-without-cache', async (config, reporter) => {308 expect(await fs.readFile(path.join(config.cwd, 'node_modules', 'comp', 'index.js'))).toEqual('foo\n');309 await fs.writeFile(path.join(config.cwd, 'comp', 'index.js'), 'bar\n');310 const reinstall = new Install({force: true}, config, reporter, await Lockfile.fromDirectory(config.cwd));311 await reinstall.init();312 expect(await fs.readFile(path.join(config.cwd, 'node_modules', 'comp', 'index.js'))).toEqual('bar\n');313 }));314test('install file: local packages with local dependencies', () =>315 runInstall({}, 'install-file-local-dependency', async (config, reporter) => {316 const reinstall = new Install({}, config, reporter, await Lockfile.fromDirectory(config.cwd));317 await reinstall.init();318 expect(await fs.readFile(path.join(config.cwd, 'node_modules', 'a', 'index.js'))).toEqual('foo;\n');319 expect(await fs.readFile(path.join(config.cwd, 'node_modules', 'b', 'index.js'))).toEqual('bar;\n');320 }));321test('install file: install without manifest of dependency', () =>322 runInstall({}, 'install-file-without-manifest', async config => {323 expect(await fs.readFile(path.join(config.cwd, 'node_modules', 'foo', 'index.js'))).toEqual('bar\n');324 }));325test('install file: link file dependencies', () =>326 runInstall({}, 'install-file-link-dependencies', async config => {327 const statA = await fs.lstat(path.join(config.cwd, 'node_modules', 'a'));328 expect(statA.isSymbolicLink()).toEqual(true);329 const statB = await fs.lstat(path.join(config.cwd, 'node_modules', 'b'));330 expect(statB.isSymbolicLink()).toEqual(true);331 const statC = await fs.lstat(path.join(config.cwd, 'node_modules', 'c'));332 expect(statC.isSymbolicLink()).toEqual(true);333 expect(await fs.readFile(path.join(config.cwd, 'node_modules', 'a', 'index.js'))).toEqual('foo;\n');334 expect(await fs.readFile(path.join(config.cwd, 'node_modules', 'b', 'index.js'))).toEqual('bar;\n');335 }));336test('install file: protocol', () =>337 runInstall({lockfile: false}, 'install-file', async config => {338 expect(await fs.readFile(path.join(config.cwd, 'node_modules', 'foo', 'index.js'))).toEqual('foobar;\n');339 }));340test('install with file: protocol as default', () =>341 runInstall({}, 'install-file-as-default', async (config, reporter, install, getOutput) => {342 expect(await fs.readFile(path.join(config.cwd, 'node_modules', 'foo', 'index.js'))).toEqual('foobar;\n');343 expect(getOutput()).toContain(reporter.lang('implicitFileDeprecated', 'bar'));344 }));345test("don't install with file: protocol as default if target is a file", () =>346 expect(runInstall({lockfile: false}, 'install-file-as-default-no-file')).rejects.toMatchObject({347 message: expect.stringContaining('Couldn\'t find any versions for "foo" that matches "bar"'),348 }));349test("don't install with implicit file: protocol if target does not have package.json", () =>350 expect(runInstall({lockfile: false}, 'install-file-as-default-no-package')).rejects.toMatchObject({351 message: expect.stringContaining('Couldn\'t find any versions for "foo" that matches "bar"'),352 }));353test('install with explicit file: protocol if target does not have package.json', () =>354 runInstall({}, 'install-file-no-package', async config => {355 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'foo', 'bar.js'))).toEqual(true);356 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'bar', 'bar.js'))).toEqual(true);357 }));358test("don't install with file: protocol as default if target is valid semver", () =>359 runInstall({}, 'install-file-as-default-no-semver', async config => {360 expect(JSON.parse(await fs.readFile(path.join(config.cwd, 'node_modules', 'foo', 'package.json')))).toMatchObject({361 name: 'foo',362 });363 }));364test("don't hang when an install script tries to read from stdin", () =>365 runInstall({}, 'install-blocking-script', (_config, _reporter, _install, getStdout) =>366 expect(getStdout()).toMatch(/Building fresh packages/),367 ));368// When local packages are installed, dependencies with different forms of the same relative path369// should be deduped e.g. 'file:b' and 'file:./b'370test('install file: dedupe dependencies 1', () =>371 runInstall({}, 'install-file-dedupe-dependencies-1', async config => {372 // Check that b is not added as a sub-dependency of a373 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'a', 'node_modules'))).toEqual(false);374 }));375// When local packages are installed, dependencies with relative and absolute paths should be376// deduped e.g. 'file:b' and 'file:/absolute/path/to/b'377test('install file: dedupe dependencies 2', () =>378 runInstall({}, 'install-file-dedupe-dependencies-2', async (config, reporter) => {379 // Add b as a dependency, using an absolute path380 await add(config, reporter, {}, [`b@file:${path.resolve(config.cwd, 'b')}`]);381 // Check that b is not added as a sub-dependency of a382 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'a', 'node_modules'))).toEqual(false);383 }));384// When local packages are installed from a repo with a lockfile, the multiple packages385// unpacking in the same location warning should not occur386test('install file: dedupe dependencies 3', () =>387 runInstall({}, 'install-file-dedupe-dependencies-3', (config, reporter, install, getStdout) => {388 const stdout = getStdout();389 // Need to check if message is logged, but don't need to check for any specific parameters390 // so splitting on undefined and testing if all message parts are in stdout391 const messageParts = reporter.lang('multiplePackagesCantUnpackInSameDestination').split('undefined');392 const warningMessage = messageParts.every(part => stdout.includes(part));393 expect(warningMessage).toBe(false);394 }));395test('install everything when flat is enabled', () =>396 runInstall({lockfile: false, flat: true}, 'install-file', async config => {397 expect(await fs.readFile(path.join(config.cwd, 'node_modules', 'foo', 'index.js'))).toEqual('foobar;\n');398 }));399test('install renamed packages', () =>400 runInstall({}, 'install-renamed-packages', async config => {401 const dir = path.join(config.cwd, 'node_modules');402 const json = await fs.readJson(path.join(dir, 'left-pad', 'package.json'));403 expect(json.version).toEqual('1.0.0');404 const json2 = await fs.readJson(path.join(dir, 'left-pad2', 'package.json'));405 expect(json2.version).toEqual('1.1.0');406 const json3 = await fs.readJson(path.join(dir, 'unscoped-turf-helpers', 'package.json'));407 expect(json3.version).toEqual('3.0.16');408 expect(json3.name).toEqual('@turf/helpers');409 }));410test('install from git cache', () =>411 runInstall({}, 'install-from-git-cache', async config => {412 expect(await getPackageVersion(config, 'dep-a')).toEqual('0.0.1');413 }));414test('install from github', () => runInstall({}, 'install-github'));415test('check and install should verify integrity in the same way when flat', () =>416 runInstall({flat: true}, 'install-should-dedupe-avoiding-conflicts-1', async (config, reporter) => {417 // Will raise if check doesn't flatten the patterns418 await check(config, reporter, {flat: true, integrity: true}, []);419 }));420test('check should verify that top level dependencies are installed correctly', () =>421 runInstall({}, 'check-top-correct', async (config, reporter) => {422 const pkgDep = JSON.parse(423 await fs.readFile(path.join(config.cwd, 'node_modules/fake-yarn-dependency/package.json')),424 );425 pkgDep.version = '2.0.0';426 await fs.writeFile(427 path.join(config.cwd, 'node_modules/fake-yarn-dependency/package.json'),428 JSON.stringify(pkgDep, null, 4),429 );430 let allCorrect = false;431 try {432 await check(config, reporter, {}, []);433 } catch (err) {434 allCorrect = true;435 }436 expect(allCorrect).toBe(true);437 }));438test('install should run install scripts in the order of dependencies', () =>439 runInstall({}, 'scripts-order', async (config, reporter) => {440 expect(await fs.exists(path.join(config.cwd, 'node_modules/dep-a/dep-a-built'))).toBe(true);441 expect(await fs.exists(path.join(config.cwd, 'node_modules/dep-b/dep-b-built'))).toBe(true);442 expect(await fs.exists(path.join(config.cwd, 'node_modules/dep-c/dep-c-built'))).toBe(true);443 }));444test('install with comments in manifest', () =>445 runInstall({lockfile: false}, 'install-with-comments', async config => {446 expect(await fs.readFile(path.join(config.cwd, 'node_modules', 'foo', 'index.js'))).toEqual('foobar;\n');447 }));448test('install with comments in manifest resolutions does not result in warning', () => {449 const fixturesLoc = path.join(__dirname, '..', '..', 'fixtures', 'install');450 return buildRun(451 reporters.BufferReporter,452 fixturesLoc,453 async (args, flags, config, reporter): Promise<void> => {454 await install(config, reporter, flags, args);455 const output = reporter.getBuffer();456 const warnings = output.filter(entry => entry.type === 'warning');457 expect(458 warnings.some(warning => {459 return warning.data.toString().indexOf(reporter.lang('invalidResolutionName', '//')) > -1;460 }),461 ).toEqual(false);462 },463 [],464 {lockfile: false},465 'install-with-comments',466 );467});468test('install with null versions in manifest', () =>469 runInstall({}, 'install-with-null-version', async config => {470 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'left-pad'))).toEqual(true);471 }));472test('run install scripts in the order when one dependency does not have install script', () =>473 runInstall({}, 'scripts-order-with-one-package-missing-install-script', async (config, reporter) => {474 expect(await fs.exists(path.join(config.cwd, 'node_modules/dep-a/dep-a-built'))).toBe(true);475 expect(await fs.exists(path.join(config.cwd, 'node_modules/dep-b/dep-b-built'))).toBe(true);476 expect(await fs.exists(path.join(config.cwd, 'node_modules/dep-d/dep-d-built'))).toBe(true);477 }));478test('install should circumvent circular dependencies', () =>479 runInstall({}, 'install-should-circumvent-circular-dependencies', async (config, reporter) => {480 expect(await getPackageVersion(config, 'dep-a')).toEqual('1.0.0');481 expect(await getPackageVersion(config, 'dep-b')).toEqual('1.0.0');482 expect(await getPackageVersion(config, 'dep-c')).toEqual('1.0.0');483 }));484test('install should resolve circular dependencies 2', () =>485 runInstall({}, 'install-should-circumvent-circular-dependencies-2', async (config, reporter) => {486 expect(await getPackageVersion(config, 'es5-ext')).toEqual('0.10.12');487 }));488// Install a package twice489test('install should be idempotent', () =>490 runInstall(491 {},492 'install-should-be-idempotent',493 async (config, reporter) => {494 expect(await getPackageVersion(config, 'dep-a')).toEqual('1.0.0');495 await runInstall({}, 'install-should-be-idempotent', async (config, reporter) => {496 expect(await getPackageVersion(config, 'dep-a')).toEqual('1.0.0');497 });498 },499 null,500 ));501test('install should fail to authenticate integrity with incorrect hash and correct sha512', () =>502 expect(runInstall({}, 'invalid-checksum-good-integrity')).rejects.toMatchObject({503 message: expect.stringContaining("computed integrity doesn't match our records"),504 }));505test('install should authenticate integrity field with sha1 checksums', () =>506 runInstall({}, 'install-update-auth-sha1', async config => {507 const lockFileContent = await fs.readFile(path.join(config.cwd, 'yarn.lock'));508 const lockFileLines = explodeLockfile(lockFileContent);509 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'abab'))).toEqual(true);510 expect(lockFileLines[3].indexOf('integrity sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4=')).toEqual(2);511 }));512test('install should authenticate integrity field with sha512 checksums', () =>513 runInstall({}, 'install-update-auth-sha512', async config => {514 const lockFileContent = await fs.readFile(path.join(config.cwd, 'yarn.lock'));515 const lockFileLines = explodeLockfile(lockFileContent);516 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'safe-buffer'))).toEqual(true);517 expect(518 lockFileLines[3].indexOf(519 'integrity sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==',520 ),521 ).toEqual(2);522 }));523test('install should authenticate integrity field with sha384 checksums', () =>524 runInstall({}, 'install-update-auth-sha384', async config => {525 const lockFileContent = await fs.readFile(path.join(config.cwd, 'yarn.lock'));526 const lockFileLines = explodeLockfile(lockFileContent);527 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'safe-buffer'))).toEqual(true);528 expect(529 lockFileLines[3].indexOf('integrity sha384-waRmooJr/yhkTilj4++XOO8GFMGUq0RhoiKo7GymDwFU/Ij8vRNGoI7RwAKzyXSM'),530 ).toEqual(2);531 }));532test('install should authenticate integrity field with options', () =>533 runInstall({}, 'install-update-auth-sha512-options', async config => {534 const lockFileContent = await fs.readFile(path.join(config.cwd, 'yarn.lock'));535 const lockFileLines = explodeLockfile(lockFileContent);536 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'safe-buffer'))).toEqual(true);537 expect(538 lockFileLines[3].indexOf(539 'integrity ' +540 'sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==?foo=bar',541 ),542 ).toEqual(2);543 }));544test('install should authenticate integrity field with combined sha1 and sha512 checksums', () =>545 runInstall({}, 'install-update-auth-combined-sha1-sha512', async config => {546 const lockFileContent = await fs.readFile(path.join(config.cwd, 'yarn.lock'));547 const lockFileLines = explodeLockfile(lockFileContent);548 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'safe-buffer'))).toEqual(true);549 // if this fails on a newer version of node or the ssri module,550 // it (might) mean the sorting algorithm within the sri string changed551 expect(lockFileLines[3]).toMatchSnapshot('integrity stable');552 }));553test('install should authenticate integrity with multiple differing sha1 checksums', () =>554 runInstall({}, 'install-update-auth-multiple-sha1', async config => {555 const lockFileContent = await fs.readFile(path.join(config.cwd, 'yarn.lock'));556 const lockFileLines = explodeLockfile(lockFileContent);557 expect(lockFileLines[3].indexOf('integrity "sha1-foo sha1-iTMSr2myEj3vcfV4iQAWce6yyFM=')).toEqual(2);558 }));559test('install should authenticate integrity with multiple differing sha512 checksums', () =>560 runInstall({}, 'install-update-auth-multiple-sha512', async config => {561 const lockFileContent = await fs.readFile(path.join(config.cwd, 'yarn.lock'));562 const lockFileLines = explodeLockfile(lockFileContent);563 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'safe-buffer'))).toEqual(true);564 expect(565 lockFileLines[3].indexOf(566 'integrity "sha512-foo ' +567 'sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="',568 ),569 ).toEqual(2);570 }));571test('install should authenticate integrity with wrong sha1 and right sha512 checksums', () =>572 runInstall({}, 'install-update-auth-multiple-wrong-sha1-right-sha512', async config => {573 const lockFileContent = await fs.readFile(path.join(config.cwd, 'yarn.lock'));574 const lockFileLines = explodeLockfile(lockFileContent);575 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'safe-buffer'))).toEqual(true);576 expect(577 lockFileLines[3].indexOf(578 'integrity "sha1-foo ' +579 'sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="',580 ),581 ).toEqual(2);582 }));583test('install should fail to authenticate integrity with correct sha1 and incorrect sha512', () =>584 expect(runInstall({}, 'install-update-auth-right-sha1-wrong-sha512')).rejects.toMatchObject({585 message: expect.stringContaining("computed integrity doesn't match our records"),586 }));587test('install should fail to authenticate on sha512 integrity mismatch', () =>588 expect(runInstall({}, 'install-update-auth-wrong-sha512')).rejects.toMatchObject({589 message: expect.stringContaining("computed integrity doesn't match our records"),590 }));591test('install should fail to authenticate on sha1 integrity mismatch', () =>592 expect(runInstall({}, 'install-update-auth-wrong-sha1')).rejects.toMatchObject({593 message: expect.stringContaining("computed integrity doesn't match our records"),594 }));595test.skip('install should create integrity field if not present', () =>596 runInstall({}, 'install-update-auth-no-integrity-field', async config => {597 const lockFileContent = await fs.readFile(path.join(config.cwd, 'yarn.lock'));598 const lockFileLines = explodeLockfile(lockFileContent);599 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'safe-buffer'))).toEqual(true);600 expect(601 lockFileLines[3].indexOf(602 'integrity sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==',603 ),604 ).toEqual(2);605 expect(lockFileLines[2].indexOf('#893312af69b2123def71f57889001671eeb2c853')).toBeGreaterThan(0);606 // backwards-compatibility607 }),608);609test('install should not create the integrity field if missing and auto-add-integrity is false', () =>610 runInstall({}, 'install-update-auth-no-integrity-field-no-auto-add', async config => {611 const lockFileContent = await fs.readFile(path.join(config.cwd, 'yarn.lock'));612 const lockFileLines = explodeLockfile(lockFileContent);613 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'safe-buffer'))).toEqual(true);614 expect(lockFileLines[2].indexOf('#893312af69b2123def71f57889001671eeb2c853')).toBeGreaterThan(0);615 expect(lockFileLines.length).toEqual(3);616 }));617test('install should not create integrity field if not present and in offline mode', () =>618 runInstall({offline: true}, 'install-update-auth-no-offline-integrity', async config => {619 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'abab'))).toEqual(true);620 }));621test('install should ignore existing hash if integrity is present even if it fails to authenticate it', () =>622 expect(runInstall({}, 'install-update-auth-bad-sha512-good-hash')).rejects.toMatchObject({623 message: expect.stringContaining("computed integrity doesn't match our records"),624 }));625test('install should ignore unknown integrity algorithms if it has other options in the sri', () =>626 runInstall({}, 'install-update-auth-madeup-right-sha512', async config => {627 const lockFileContent = await fs.readFile(path.join(config.cwd, 'yarn.lock'));628 const lockFileLines = explodeLockfile(lockFileContent);629 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'safe-buffer'))).toEqual(true);630 expect(631 lockFileLines[3].indexOf(632 'integrity "madeupalgorithm-abad1dea ' +633 'sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="',634 ),635 ).toEqual(2);636 }));637test('install should fail if the only algorithms in the sri are unknown', () =>638 expect(runInstall({}, 'install-update-auth-madeup')).rejects.toMatchObject({639 message: expect.stringContaining('none of the specified algorithms are supported'),640 }));641test('install should fail if the sri is malformed', () =>642 expect(runInstall({}, 'install-update-auth-malformed')).rejects.toMatchObject({643 message: expect.stringContaining('none of the specified algorithms are supported'),644 }));645test('install should fail with unsupported algorithms', () =>646 expect(runInstall({}, 'install-update-auth-sha3')).rejects.toMatchObject({647 message: expect.stringContaining('none of the specified algorithms are supported'),648 }));649test.concurrent('install should update integrity in yarn.lock (--update-checksums)', () =>650 runInstall({updateChecksums: true}, 'install-update-checksums', async config => {651 const lockFileLines = explodeLockfile(await fs.readFile(path.join(config.cwd, 'yarn.lock')));652 expect(lockFileLines[3]).toEqual(653 expect.stringContaining(654 'sha512-I+Wi+qiE2kUXyrRhNsWv6XsjUTBJjSoVSctKNBfLG5zG/Xe7Rjbxf13+vqYHNTwHaFU+FtSlVxOCTiMEVtPv0A==',655 ),656 );657 }),658);659test.concurrent('install should update malformed integrity string in yarn.lock (--update-checksums)', () =>660 runInstall({updateChecksums: true}, 'install-update-checksums-malformed', async config => {661 const lockFileLines = explodeLockfile(await fs.readFile(path.join(config.cwd, 'yarn.lock')));662 expect(lockFileLines[3]).toEqual(663 expect.stringContaining(664 'sha512-I+Wi+qiE2kUXyrRhNsWv6XsjUTBJjSoVSctKNBfLG5zG/Xe7Rjbxf13+vqYHNTwHaFU+FtSlVxOCTiMEVtPv0A==',665 ),666 );667 }),668);669if (process.platform !== 'win32') {670 // TODO: This seems like a real issue, not just a config issue671 test('install cache symlinks properly', () =>672 runInstall({}, 'cache-symlinks', async (config, reporter) => {673 const symlink = path.resolve(config.cwd, 'node_modules', 'dep-a', 'link-index.js');674 expect(await fs.exists(symlink)).toBe(true);675 await fs.unlink(path.join(config.cwd, 'node_modules'));676 const lockfile = await createLockfile(config.cwd);677 const install = new Install({}, config, reporter, lockfile);678 await install.init();679 expect(await fs.exists(symlink)).toBe(true);680 }));681}682test('install a scoped module from authed private registry', () =>683 runInstall({}, 'install-from-authed-private-registry', async config => {684 const authedRequests = request.__getAuthedRequests();685 expect(authedRequests[0].url).toEqual('https://registry.yarnpkg.com/@types%2flodash');686 expect(authedRequests[0].headers.authorization).toEqual('Bearer abc123');687 expect(authedRequests[1].url).toEqual('https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.37.tgz');688 expect(authedRequests[1].headers.authorization).toEqual('Bearer abc123');689 expect(690 (await fs.readFile(path.join(config.cwd, 'node_modules', '@types', 'lodash', 'index.d.ts'))).split('\n')[0],691 ).toEqual('// Type definitions for Lo-Dash 4.14');692 }));693test('install a scoped module from authed private registry with a missing trailing slash', () =>694 runInstall({}, 'install-from-authed-private-registry-no-slash', async config => {695 const authedRequests = request.__getAuthedRequests();696 expect(authedRequests[0].url).toEqual('https://registry.yarnpkg.com/@types%2flodash');697 expect(authedRequests[0].headers.authorization).toEqual('Bearer abc123');698 expect(authedRequests[1].url).toEqual('https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.37.tgz');699 expect(authedRequests[1].headers.authorization).toEqual('Bearer abc123');700 expect(701 (await fs.readFile(path.join(config.cwd, 'node_modules', '@types', 'lodash', 'index.d.ts'))).split('\n')[0],702 ).toEqual('// Type definitions for Lo-Dash 4.14');703 }));704test('install of scoped package with subdependency conflict should pass check', () =>705 runInstall({}, 'install-scoped-package-with-subdependency-conflict', async (config, reporter) => {706 let allCorrect = true;707 try {708 await check(config, reporter, {integrity: false}, []);709 } catch (err) {710 allCorrect = false;711 }712 expect(allCorrect).toBe(true);713 }));714test('install a module with incompatible optional dependency should skip dependency', () =>715 runInstall({}, 'install-should-skip-incompatible-optional-dep', async config => {716 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'dep-incompatible'))).toEqual(false);717 }));718test('install a module with incompatible optional dependency should skip transient dependencies', () =>719 runInstall({}, 'install-should-skip-incompatible-optional-dep', async config => {720 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'dep-a'))).toEqual(false);721 }));722test('install a module with optional dependency should skip incompatible transient dependency', () =>723 runInstall({}, 'install-should-skip-incompatible-optional-sub-dep', async config => {724 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'dep-optional'))).toEqual(true);725 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'dep-incompatible'))).toEqual(false);726 }));727// this tests for a problem occurring due to optional dependency incompatible with os, in this case fsevents728// this would fail on os's incompatible with fsevents, which is everything except osx.729if (process.platform !== 'darwin') {730 test('install incompatible optional dependency should still install shared child dependencies', () =>731 runInstall({}, 'install-should-not-skip-required-shared-deps', async config => {732 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'deep-extend'))).toEqual(true);733 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'ini'))).toEqual(true);734 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'strip-json-comments'))).toEqual(true);735 }));736}737test('optional dependency that fails to build should not be installed', () =>738 runInstall({}, 'should-not-install-failing-optional-deps', async config => {739 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'optional-failing'))).toEqual(false);740 }));741test('failing dependency of optional dependency should not be installed', () =>742 runInstall({}, 'should-not-install-failing-deps-of-optional-deps', async config => {743 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'optional-dep'))).toEqual(true);744 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'sub-failing'))).toEqual(false);745 }));746// Covers current behavior, issue opened whether this should be changed https://github.com/yarnpkg/yarn/issues/2274747test('a subdependency of an optional dependency that fails should be installed', () =>748 runInstall({}, 'should-install-failing-optional-sub-deps', async config => {749 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'optional-failing'))).toEqual(false);750 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'sub-dep'))).toEqual(true);751 }));752test('a sub-dependency should be non-optional if any parents mark it non-optional', () =>753 runInstall({ignoreOptional: true}, 'install-sub-dependency-if-any-parents-mark-it-non-optional', async config => {754 const deps = await fs.readdir(path.join(config.cwd, 'node_modules'));755 expect(deps).toEqual([756 '.yarn-integrity',757 'normal-dep',758 'normal-sub-dep',759 'normal-sub-sub-dep',760 'sub-dep',761 'sub-dep-2',762 'sub-sub-dep',763 ]);764 }));765// revealed https://github.com/yarnpkg/yarn/issues/2263766test('should not loose dependencies when installing with --production', () =>767 runInstall({production: true}, 'prod-should-keep-subdeps', async config => {768 // would be hoisted from gulp/vinyl-fs/glob-stream/minimatch/brace-expansion/balanced-match769 expect(await getPackageVersion(config, 'balanced-match')).toEqual('0.4.2');770 }));771// https://github.com/yarnpkg/yarn/issues/2470772test('a allows dependency with [] in os cpu requirements', () =>773 runInstall({}, 'empty-os', async config => {774 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'feed'))).toEqual(true);775 }));776test('should skip integrity check and do install when --skip-integrity-check flag is passed', () =>777 runInstall({}, 'skip-integrity-check', async (config, reporter) => {778 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'sub-dep'))).toEqual(true);779 await fs.unlink(path.join(config.cwd, 'node_modules', 'sub-dep'));780 let lockContent = await fs.readFile(path.join(config.cwd, 'yarn.lock'));781 lockContent += `782# changed the file, integrity should be fine783 `;784 await fs.writeFile(path.join(config.cwd, 'yarn.lock'), lockContent);785 let reinstall = new Install({}, config, reporter, await Lockfile.fromDirectory(config.cwd));786 await reinstall.init();787 // reinstall will be successful but it won't reinstall anything788 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'sub-dep'))).toEqual(false);789 reinstall = new Install({skipIntegrityCheck: true}, config, reporter, await Lockfile.fromDirectory(config.cwd));790 await reinstall.init();791 // reinstall will reinstall deps792 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'sub-dep'))).toEqual(true);793 let newLockContent = await fs.readFile(path.join(config.cwd, 'yarn.lock'));794 expect(lockContent).toEqual(newLockContent);795 reinstall = new Install({force: true}, config, reporter, await Lockfile.fromDirectory(config.cwd));796 await reinstall.init();797 // force rewrites lockfile798 newLockContent = await fs.readFile(path.join(config.cwd, 'yarn.lock'));799 expect(lockContent).not.toEqual(newLockContent);800 }));801test('bailout should work with --production flag too', () =>802 runInstall({production: true}, 'bailout-prod', async (config, reporter): Promise<void> => {803 // remove file804 await fs.unlink(path.join(config.cwd, 'node_modules', 'left-pad', 'index.js'));805 // run install again806 const reinstall = new Install({production: true}, config, reporter, await Lockfile.fromDirectory(config.cwd));807 await reinstall.init();808 // don't expect file being recreated because install should have bailed out809 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'left-pad', 'index.js'))).toBe(false);810 }));811// Scenario:812// graceful-fs will install two versions, from @4.1.10 and @^4.1.11. The pattern @^4.1.2 would sometimes resolve813// to 4.1.10, if @^4.1.11 hadn't been processed before. Otherwise it would resolve to the result of @^4.1.11.814// Run an independent install and check, and see they have different results for @^4.1.2 - won't always see815// the bug, but its the best we can do without creating mock registry with controlled timing of responses.816test('package version resolve should be deterministic', () =>817 runInstall({}, 'install-deterministic-versions', async (config, reporter) => {818 await check(config, reporter, {integrity: true}, []);819 }));820test('transitive file: dependencies should work', () =>821 runInstall({}, 'transitive-file', async (config, reporter) => {822 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'b'))).toBe(true);823 }));824test('unbound transitive dependencies should not conflict with top level dependency', () =>825 runInstall({flat: true}, 'install-conflicts', async config => {826 expect((await fs.readJson(path.join(config.cwd, 'node_modules', 'left-pad', 'package.json'))).version).toEqual(827 '1.0.0',828 );829 }));830test('manifest optimization respects versions with alternation', () =>831 runInstall({flat: true}, 'optimize-version-with-alternation', async config => {832 expect(await getPackageVersion(config, 'lodash')).toEqual('2.4.2');833 }));834test('top level patterns should match after install', () =>835 runInstall({}, 'top-level-pattern-check', async (config, reporter) => {836 let integrityError = false;837 try {838 await check(config, reporter, {integrity: true}, []);839 } catch (err) {840 integrityError = true;841 }842 expect(integrityError).toBe(false);843 }));844test('warns for missing bundledDependencies', () =>845 buildRun(846 reporters.BufferReporter,847 path.join(__dirname, '..', '..', 'fixtures', 'install'),848 async (args, flags, config, reporter): Promise<void> => {849 await install(config, reporter, flags, args);850 const output = reporter.getBuffer();851 const warnings = output.filter(entry => entry.type === 'warning');852 expect(853 warnings.some(warning => {854 return (855 warning.data.toString().indexOf(reporter.lang('missingBundledDependency', 'tap@0.3.1', 'tap-consumer')) > -1856 );857 }),858 ).toEqual(true);859 },860 [],861 {},862 'missing-bundled-dep',863 ));864test('install will not overwrite linked scoped dependencies', () =>865 runInstall({production: true}, 'install-dont-overwrite-linked', async (installConfig): Promise<void> => {866 // link our fake dep to the registry867 await runLink([], {}, 'package-with-name-scoped', async (linkConfig): Promise<void> => {868 // link our fake dependency in our node_modules869 await runLink(870 ['@fakescope/a-package'],871 {linkFolder: linkConfig.linkFolder},872 {cwd: installConfig.cwd},873 async () => {874 // check that it exists (just in case)875 const existed = await fs.exists(path.join(installConfig.cwd, 'node_modules', '@fakescope', 'a-package'));876 expect(existed).toEqual(true);877 // run install to install dev deps which would remove the linked dep if the bug was present878 await runInstall({linkFolder: linkConfig.linkFolder}, {cwd: installConfig.cwd}, async () => {879 // if the linked dep is still there is a win :)880 const existed = await fs.exists(path.join(installConfig.cwd, 'node_modules', '@fakescope', 'a-package'));881 expect(existed).toEqual(true);882 });883 },884 );885 });886 }));887test('install will not overwrite linked dependencies', () =>888 runInstall({production: true}, 'install-dont-overwrite-linked', async (installConfig): Promise<void> => {889 // link our fake dep to the registry890 await runLink([], {}, 'package-with-name', async (linkConfig): Promise<void> => {891 // link our fake dependency in our node_modules892 await runLink(['a-package'], {linkFolder: linkConfig.linkFolder}, {cwd: installConfig.cwd}, async (): Promise<893 void,894 > => {895 // check that it exists (just in case)896 const existed = await fs.exists(path.join(installConfig.cwd, 'node_modules', 'a-package'));897 expect(existed).toEqual(true);898 // run install to install dev deps which would remove the linked dep if the bug was present899 await runInstall({linkFolder: linkConfig.linkFolder}, {cwd: installConfig.cwd}, async () => {900 // if the linked dep is still there is a win :)901 const existed = await fs.exists(path.join(installConfig.cwd, 'node_modules', 'a-package'));902 expect(existed).toEqual(true);903 });904 });905 });906 }));907// There was an issue where anything ending with `.git` would be sent to GitResolver, even if it was a file: dep.908// This caused an error if you had a directory named "myModule.git" and tried to use it with "file:../myModule.git"909// See https://github.com/yarnpkg/yarn/issues/3670910test('file: dependency ending with `.git` should work', () =>911 runInstall({}, 'local-named-git', async (config, reporter) => {912 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'a'))).toBe(true);913 }));914// There was a warning being generated when a peerDep existed at a deeper level, and at the top level.915// See https://github.com/yarnpkg/yarn/issues/4743916//917// package.json918// |- b919// | |- caniuse-api920// | |- caniuse-lite921// |- caniuse-lite922//923// When `b` also has a peerDep on `caniuse-lite` then Yarn was issuing a warning that the dep was missing.924test('install will not warn for missing peerDep when both shallower and deeper', () =>925 runInstall({}, 'peer-dep-included-at-2-levels', (config, reporter, install, getStdout) => {926 const stdout = getStdout();927 const messageParts = reporter.lang('unmetPeer').split('undefined');928 const warningMessage = messageParts.every(part => stdout.includes(part));929 expect(warningMessage).toBe(false);930 }));931test('install will warn for missing peer dependencies', () =>932 runInstall({}, 'missing-peer-dep', (config, reporter, install, getStdout) => {933 const stdout = getStdout();934 const messageParts = reporter.lang('unmetPeer', 'undefined').split('undefined');935 const warningMessage = messageParts.every(part => stdout.includes(part));936 expect(warningMessage).toBe(true);937 }));938test('install will not warn for missing optional peer dependencies', () =>939 runInstall({}, 'missing-opt-peer-dep', (config, reporter, install, getStdout) => {940 const stdout = getStdout();941 const messageParts = reporter.lang('unmetPeer', 'undefined').split('undefined');942 const warningMessage = messageParts.every(part => stdout.includes(part));943 expect(warningMessage).toBe(false);944 }));945test('does not check node_modules for extraneous files when --modules-folder used', async () => {946 // Scenario: https://github.com/yarnpkg/yarn/issues/5419947 // When `--modules-foler` is passed, yarn should check that directory for extraneous files.948 // Also, the default node_modules dir, if it exists, should not be cleaned out (marked as extraneous).949 await runInstall({modulesFolder: './some_modules'}, 'extraneous-node-modules', async (config): Promise<void> => {950 expect(await fs.exists(`${config.cwd}/some_modules/feed`)).toEqual(true);951 // Extraneous files in node_modules should not have been cleaned.952 expect(await fs.exists(`${config.cwd}/node_modules/extra.js`)).toEqual(true);953 // Extraneous files in some_modules should have been cleaned.954 expect(await fs.exists(`${config.cwd}/some_modules/extra.js`)).toEqual(false);955 });956});957test('install skips the scripts if the yarnrc specifies skip-scripts true', () =>958 runInstall({}, 'ignore-scripts-by-yarnrc', (config, reporter, install, getStdout) => {959 const stdout = getStdout();960 const ignoredScriptsMessage = reporter.lang('ignoredScripts');961 expect(stdout).toMatch(ignoredScriptsMessage);962 }));963describe('Cache', () => {964 test('install should cache package without integrity prefix if no integrity field present', () =>965 runInstall({}, 'install-update-auth-no-integrity-field', async config => {966 const pkgCacheDir = path.join(967 config.cwd,968 '.yarn-cache',969 `v${constants.CACHE_VERSION}`,970 'npm-safe-buffer-5.1.1-893312af69b2123def71f57889001671eeb2c853',971 );972 expect(await fs.exists(pkgCacheDir)).toEqual(true);973 }));974 test('install should cache package with integrity suffix if integrity field present', () =>975 runInstall({}, 'install-update-auth-sha512', async config => {976 const pkgCacheDir = path.join(977 config.cwd,978 '.yarn-cache',979 `v${constants.CACHE_VERSION}`,980 'npm-safe-buffer-5.1.1-893312af69b2123def71f57889001671eeb2c853-integrity',981 );982 expect(await fs.exists(pkgCacheDir)).toEqual(true);983 }));984 test('install should store cached sha1 + sha512 integrity when lockfile has sha1 integrity field', () =>985 runInstall({}, 'install-update-auth-sha1-safebuffer', async config => {986 const pkgCacheDir = path.join(987 config.cwd,988 '.yarn-cache',989 `v${constants.CACHE_VERSION}`,990 'npm-safe-buffer-5.1.1-893312af69b2123def71f57889001671eeb2c853-integrity',991 );992 const pkgCacheMetaData = JSON.parse(993 await fs.readFile(path.join(pkgCacheDir, 'node_modules', 'safe-buffer', constants.METADATA_FILENAME)),994 );995 expect(pkgCacheMetaData.remote.cacheIntegrity).toBe(996 // eslint-disable-next-line max-len997 'sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg== sha1-iTMSr2myEj3vcfV4iQAWce6yyFM=',998 );999 }));1000 test('install should store cached sha1 + sha512 integrity when lockfile has sha512 integrity field', () =>1001 runInstall({}, 'install-update-auth-sha512', async config => {1002 const pkgCacheDir = path.join(1003 config.cwd,1004 '.yarn-cache',1005 `v${constants.CACHE_VERSION}`,1006 'npm-safe-buffer-5.1.1-893312af69b2123def71f57889001671eeb2c853-integrity',1007 );1008 const pkgCacheMetaData = JSON.parse(1009 await fs.readFile(path.join(pkgCacheDir, 'node_modules', 'safe-buffer', constants.METADATA_FILENAME)),1010 );1011 expect(pkgCacheMetaData.remote.cacheIntegrity).toBe(1012 // eslint-disable-next-line max-len1013 'sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg== sha1-iTMSr2myEj3vcfV4iQAWce6yyFM=',1014 );1015 }));1016 test('install should store cached sha1 + sha512 integrity when lockfile has no integrity field', () =>1017 runInstall({}, 'install-update-auth-no-integrity-field', async config => {1018 const pkgCacheDir = path.join(1019 config.cwd,1020 '.yarn-cache',1021 `v${constants.CACHE_VERSION}`,1022 'npm-safe-buffer-5.1.1-893312af69b2123def71f57889001671eeb2c853',1023 );1024 const pkgCacheMetaData = JSON.parse(1025 await fs.readFile(path.join(pkgCacheDir, 'node_modules', 'safe-buffer', constants.METADATA_FILENAME)),1026 );1027 expect(pkgCacheMetaData.remote.cacheIntegrity).toBe(1028 // eslint-disable-next-line max-len1029 'sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg== sha1-iTMSr2myEj3vcfV4iQAWce6yyFM=',1030 );1031 }));1032 test('install should fail when cached package integrity does not match lockfile integrity field', () =>1033 expect(runInstall({}, 'install-update-auth-invalid-cache-integrity')).rejects.toThrow(1034 // eslint-disable-next-line max-len1035 'Incorrect integrity when fetching from the cache for "safe-buffer". Cache has "sha512-foo sha1-bar" and remote has "sha1-iTMSr2myEj3vcfV4iQAWce6yyFM="',1036 ));1037 test('install should fail when cached package hash does not match remote hash', () =>1038 expect(runInstall({}, 'install-update-auth-invalid-cache-hash')).rejects.toThrow(1039 // eslint-disable-next-line max-len1040 'Incorrect hash when fetching from the cache for "safe-buffer". Cache has "bad-hash" and remote has "893312af69b2123def71f57889001671eeb2c853"',1041 ));1042 test('install should not fail cache integrity validation when lockfile has sha1 integrity field', () =>1043 expect(runInstall({}, 'install-update-auth-sha1-with-cache')).resolves.toBeUndefined());1044 test('install should not fail cache integrity validation when lockfile has sha512 integrity field', () =>1045 expect(runInstall({}, 'install-update-auth-sha512-with-cache')).resolves.toBeUndefined());1046 test('install should not fail cache integrity validation when lockfile has no integrity field', () =>1047 expect(runInstall({}, 'install-update-auth-no-integrity-field-with-cache')).resolves.toBeUndefined());...
workspaces-install.js
Source:workspaces-install.js
...10test.concurrent("workspaces don't work with disabled configuration in .yarnrc", async (): Promise<void> => {11 let error = '';12 const reporter = new reporters.ConsoleReporter({});13 try {14 await runInstall({}, 'workspaces-install-enabled');15 } catch (e) {16 error = e.message;17 }18 expect(error).toContain(reporter.lang('workspacesDisabled'));19});20test.concurrent("workspaces don't work on non private projects", async (): Promise<void> => {21 let error = '';22 const reporter = new reporters.ConsoleReporter({});23 try {24 await runInstall({}, 'workspaces-install-private');25 } catch (e) {26 error = e.message;27 }28 expect(error).toContain(reporter.lang('workspacesRequirePrivateProjects'));29});30test.concurrent("workspaces don't work with duplicate names", async (): Promise<void> => {31 let error = '';32 const reporter = new reporters.ConsoleReporter({});33 try {34 await runInstall({}, 'workspaces-install-duplicate');35 } catch (e) {36 error = e.message;37 }38 expect(error).toContain(reporter.lang('workspaceNameDuplicate', 'workspace-1'));39});40test.concurrent("workspaces warn and get ignored if they don't have a name and a version", (): Promise<void> => {41 return buildRun(42 reporters.BufferReporter,43 path.join(__dirname, '..', '..', 'fixtures', 'install'),44 async (args, flags, config, reporter, lockfile): Promise<void> => {45 const install = new Install(flags, config, reporter, lockfile);46 await install.init();47 const warnings = reporter.getBuffer();48 expect(49 warnings.some(warning => {50 return warning.data.toString().toLowerCase().indexOf('missing version in workspace') > -1;51 }),52 ).toEqual(true);53 expect(54 warnings.some(warning => {55 return warning.data.toString().toLowerCase().indexOf('missing name in workspace') > -1;56 }),57 ).toEqual(true);58 },59 [],60 {},61 'workspaces-install-mandatory-fields',62 );63});64test.concurrent('installs workspaces dependencies into root folder', (): Promise<void> => {65 return runInstall({}, 'workspaces-install-basic', async (config): Promise<void> => {66 const lockfile = await fs.readFile(path.join(config.cwd, 'yarn.lock'));67 expect(lockfile.indexOf('isarray')).toBeGreaterThanOrEqual(0);68 expect(lockfile.indexOf('repeat-string')).toBeGreaterThanOrEqual(0);69 expect(lockfile.indexOf('left-pad')).toBeGreaterThanOrEqual(0);70 expect(lockfile.indexOf('right-pad')).toBeGreaterThanOrEqual(0);71 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'isarray'))).toBe(true);72 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'repeat-string'))).toBe(true);73 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'left-pad'))).toBe(true);74 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'right-pad'))).toBe(true);75 expect(await fs.exists(path.join(config.cwd, 'workspace-child', 'node_modules'))).toBe(false);76 expect(await fs.exists(path.join(config.cwd, 'workspace-child', 'yarn.lock'))).toBe(false);77 expect(await fs.exists(path.join(config.cwd, 'packages', 'workspace-child-2', 'node_modules'))).toBe(false);78 expect(await fs.exists(path.join(config.cwd, 'packages', 'workspace-child-2', 'yarn.lock'))).toBe(false);79 expect(await fs.exists(path.join(config.cwd, 'packages', 'workspace-child-3', 'node_modules'))).toBe(false);80 expect(await fs.exists(path.join(config.cwd, 'packages', 'workspace-child-3', 'yarn.lock'))).toBe(false);81 });82});83test.concurrent('install should install unhoistable dependencies in workspace node_modules', (): Promise<void> => {84 return runInstall({}, 'workspaces-install-conflict', async (config): Promise<void> => {85 // node_modules/left-pad@1.1.386 let packageFile = await fs.readFile(path.join(config.cwd, 'node_modules', 'left-pad', 'package.json'));87 expect(JSON.parse(packageFile).version).toEqual('1.1.3');88 // node_modules/workspace-child/left-pad@1.1.189 packageFile = await fs.readFile(90 path.join(config.cwd, 'workspace-child', 'node_modules', 'left-pad', 'package.json'),91 );92 expect(JSON.parse(packageFile).version).toEqual('1.1.1');93 });94});95test.concurrent(96 'install should install unhoistable dependencies in workspace node_modules even when no symlink exists',97 (): Promise<void> => {98 return runInstall({}, 'workspaces-install-conflict-without-symlink', async (config): Promise<void> => {99 // node_modules/isarray@1.0.0100 let packageFile = await fs.readFile(path.join(config.cwd, 'node_modules', 'isarray', 'package.json'));101 expect(JSON.parse(packageFile).version).toEqual('1.0.0');102 // node_modules/arrify@1.0.0103 packageFile = await fs.readFile(path.join(config.cwd, 'node_modules', 'arrify', 'package.json'));104 expect(JSON.parse(packageFile).version).toEqual('1.0.0');105 // node_modules/arrify/isarray@2.0.0106 packageFile = await fs.readFile(path.join(config.cwd, 'arrify', 'node_modules', 'isarray', 'package.json'));107 expect(JSON.parse(packageFile).version).toEqual('2.0.0');108 });109 },110);111test.concurrent('install should link workspaces that refer each other', (): Promise<void> => {112 return runInstall({}, 'workspaces-install-link', async (config): Promise<void> => {113 // packages/workspace-1/node_modules/left-pad - missing because it is hoisted to the root114 expect(await fs.exists(path.join(config.cwd, 'packages', 'workspace-1', 'node_modules'))).toBe(false);115 // node_modules/left-pad - link116 const packageFile = await fs.readFile(path.join(config.cwd, 'node_modules', 'left-pad', 'package.json'));117 expect(JSON.parse(packageFile).version).toEqual('1.1.2');118 const readme = await fs.readFile(path.join(config.cwd, 'node_modules', 'left-pad', 'README.md'));119 expect(readme.split('\n')[0]).toEqual('WORKSPACES ROCK!');120 });121});122test.concurrent(123 'install should not link workspaces that refer not compatible version of another workspace',124 (): Promise<void> => {125 return runInstall({}, 'workspaces-install-link', async (config): Promise<void> => {126 // packages/workspace-2/node_modules/left-pad - from npm127 const packageFile = await fs.readFile(128 path.join(config.cwd, 'packages', 'workspace-2', 'node_modules', 'left-pad', 'package.json'),129 );130 const readme = await fs.readFile(131 path.join(config.cwd, 'packages', 'workspace-2', 'node_modules', 'left-pad', 'README.md'),132 );133 expect(JSON.parse(packageFile).version).not.toBe('1.1.2');134 expect(readme.split('\n')[0]).not.toEqual('WORKSPACES ROCK!');135 });136 },137);138test.concurrent('install should not link a workspace if the version is not compatible', (): Promise<void> => {139 return runInstall({binLinks: true}, 'workspaces-install-link-invalid', async (config): Promise<void> => {140 // node_modules/left-pad - from npm141 const packageFile = await fs.readFile(path.join(config.cwd, 'node_modules', 'left-pad', 'package.json'));142 const readme = await fs.readFile(path.join(config.cwd, 'node_modules', 'left-pad', 'README.md'));143 expect(JSON.parse(packageFile).version).not.toBe('1.1.2');144 expect(readme.split('\n')[0]).not.toEqual('WORKSPACES ROCK!');145 });146});147test.concurrent('install should prioritize non workspace dependency at root over the workspace symlink', (): Promise<148 void,149> => {150 return runInstall({}, 'workspaces-install-link-root', async (config): Promise<void> => {151 // node_modules/left-pad - from npm152 let packageFile = await fs.readFile(path.join(config.cwd, 'node_modules', 'left-pad', 'package.json'));153 expect(JSON.parse(packageFile).version).toEqual('1.1.3');154 let readme = await fs.readFile(path.join(config.cwd, 'node_modules', 'left-pad', 'README.md'));155 expect(readme.split('\n')[0]).not.toEqual('WORKSPACES ROCK!');156 // node_modules/workspace-1/left-pad - link157 packageFile = await fs.readFile(158 path.join(config.cwd, 'packages', 'workspace-1', 'node_modules', 'left-pad', 'package.json'),159 );160 expect(JSON.parse(packageFile).version).toEqual('1.1.2');161 readme = await fs.readFile(162 path.join(config.cwd, 'packages', 'workspace-1', 'node_modules', 'left-pad', 'README.md'),163 );164 expect(readme.split('\n')[0]).toEqual('WORKSPACES ROCK!');165 // packages/workspace-2/node_modules/left-pad - missing because it is hoisted to the root166 expect(await fs.exists(path.join(config.cwd, 'packages', 'workspace-2', 'node_modules'))).toBe(false);167 });168});169test.concurrent('install should install subdependencies of workspaces', (): Promise<void> => {170 // the tricky part is that isarray is a subdependency of left-pad that is not referenced in the root171 // but another workspace172 return runInstall({}, 'workspaces-install-subdeps', async (config): Promise<void> => {173 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'isarray'))).toBe(true);174 });175});176test.concurrent(177 'install should install subdependencies of workspaces that are not referenced in other workspaces',178 (): Promise<void> => {179 // the tricky part is that left-pad is not a dependency of root180 return runInstall({}, 'workspaces-install-subdeps-2', async (config): Promise<void> => {181 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'isarray'))).toBe(true);182 });183 },184);185test.concurrent('install should install dev dependencies of workspaces', (): Promise<void> => {186 // the tricky part is that left-pad is not a dependency of root187 return runInstall({}, 'workspaces-install-subdeps-dev', async (config): Promise<void> => {188 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'left-pad'))).toBe(true);189 expect(await fs.exists(path.join(config.cwd, 'packages', 'workspace-1', 'node_modules', 'left-pad'))).toBe(true);190 });191});192test.concurrent('install should not install dev dependencies of workspaces in production mode', (): Promise<void> => {193 // the tricky part is that left-pad is not a dependency of root194 return runInstall({production: true}, 'workspaces-install-subdeps-dev', async (config): Promise<void> => {195 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'left-pad'))).toBe(true);196 expect(await fs.exists(path.join(config.cwd, 'packages', 'workspace-1', 'node_modules', 'left-pad'))).toBe(false);197 });198});199// https://github.com/yarnpkg/yarn/issues/3598200test.concurrent('install should work correctly for workspaces that have similar names', (): Promise<void> => {201 return runInstall({production: true}, 'workspaces-install-names-issue', async (config): Promise<void> => {202 expect(await fs.exists(path.join(config.cwd, 'packages', 'jest', 'package.json'))).toBe(true);203 expect(await fs.exists(path.join(config.cwd, 'packages', 'jest-cli', 'package.json'))).toBe(true);204 });205});206test.concurrent('check command should work', (): Promise<void> => {207 return runInstall({checkFiles: true}, 'workspaces-install-basic', async (config, reporter): Promise<void> => {208 // check command + integrity check209 let thrown = false;210 try {211 await check(config, reporter, {integrity: true, checkFiles: true}, []);212 await check(config, reporter, {}, []);213 } catch (e) {214 thrown = true;215 }216 expect(thrown).toBe(false);217 });218});219test.concurrent('install should link binaries at root and in workspace dependents', (): Promise<void> => {220 return runInstall({binLinks: true}, 'workspaces-install-link-bin', async (config): Promise<void> => {221 // node_modules/.bin/workspace-1 - link222 expect(await fs.exists(path.join(config.cwd, 'node_modules', '.bin', 'workspace-1'))).toBe(true);223 // packages/workspace-2/node_modules/.bin/workspace-1 - link224 expect(225 await fs.exists(path.join(config.cwd, 'packages', 'workspace-2', 'node_modules', '.bin', 'workspace-1')),226 ).toBe(true);227 });228});229test.concurrent('install should ignore node_modules in workspaces when used with **/*', (): Promise<void> => {230 return runInstall({}, 'workspaces-install-already-exists', async (config): Promise<void> => {231 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'a'))).toBe(true);232 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'b'))).toBe(true);233 });234});235describe('install should ignore deep node_modules in workspaces', () => {236 test('without nohoist', (): Promise<void> => {237 return runInstall(238 {workspacesNohoistEnabled: false},239 'workspaces-install-already-exists-deep',240 async (config): Promise<void> => {241 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'a'))).toBe(true);242 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'b'))).toBe(true);243 },244 );245 });246 test('with nohoist', (): Promise<void> => {247 return runInstall(248 {workspacesNohoistEnabled: true},249 'workspaces-install-already-exists-deep',250 async (config): Promise<void> => {251 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'a'))).toBe(true);252 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'b'))).toBe(true);253 },254 );255 });256});257test.concurrent('install should link binaries properly when run from child workspace', async () => {258 await runInstall({binLinks: true}, 'workspaces-install-bin', async (config, reporter): Promise<void> => {259 // initial install260 expect(await fs.exists(`${config.cwd}/node_modules/.bin/rimraf`)).toEqual(true);261 expect(await fs.exists(`${config.cwd}/node_modules/.bin/touch`)).toEqual(true);262 expect(await fs.exists(`${config.cwd}/node_modules/.bin/workspace-1`)).toEqual(true);263 expect(await fs.exists(`${config.cwd}/packages/workspace-2/node_modules/.bin/rimraf`)).toEqual(true);264 expect(await fs.exists(`${config.cwd}/packages/workspace-2/node_modules/.bin/workspace-1`)).toEqual(true);265 // reset package folders to simulate running 'install' from266 // child workspace _before_ running it in the root (this is not267 // possible to do without an initial install using the current268 // testing infrastructure)269 await fs.unlink(`${config.cwd}/node_modules`);270 await fs.unlink(`${config.cwd}/packages/workspace-1/node_modules`);271 await fs.unlink(`${config.cwd}/packages/workspace-2/node_modules`);272 // run "install" in child package273 const childConfig = await makeConfigFromDirectory(`${config.cwd}/packages/workspace-1`, reporter, {binLinks: true});274 await install(childConfig, reporter, {}, []);275 expect(await fs.exists(`${config.cwd}/node_modules/.bin/rimraf`)).toEqual(true);276 expect(await fs.exists(`${config.cwd}/node_modules/.bin/touch`)).toEqual(true);277 expect(await fs.exists(`${config.cwd}/node_modules/.bin/workspace-1`)).toEqual(true);278 expect(await fs.exists(`${config.cwd}/packages/workspace-2/node_modules/.bin/rimraf`)).toEqual(true);279 expect(await fs.exists(`${config.cwd}/packages/workspace-2/node_modules/.bin/workspace-1`)).toEqual(true);280 });281});282// TODO need more thorough tests for all kinds of checks: integrity, verify-tree283describe('nohoist', () => {284 async function checkPackage(config: ConfigType, path: string, shouldPresent: boolean): Promise<void> {285 const isPresent = await isPackagePresent(config, path);286 try {287 expect(isPresent).toEqual(shouldPresent);288 } catch (e) {289 throw new Error(`error: ${path} should ${shouldPresent ? '' : 'NOT'} exist`);290 }291 }292 test.concurrent('exclude packages by workspace', (): Promise<void> => {293 return runInstall({}, 'workspaces-install-nohoist-by-ws', async (config): Promise<void> => {294 const existingPackages = [295 'workspace-disable-a',296 'workspace-disable-all',297 'workspace-hoist-all',298 'workspace-disable-all/c',299 'workspace-disable-all/b',300 'workspace-disable-all/d',301 'workspace-disable-a/a',302 'workspace-disable-a/b',303 'workspace-disable-all/workspace-hoist-all',304 'b',305 'c',306 'd',307 ];308 const notExistingPackages = ['a', 'workspace-hoist-all/b', 'workspace-hoist-all/d'];309 for (const p of existingPackages) {310 await checkPackage(config, p, true);311 }312 for (const p of notExistingPackages) {313 await checkPackage(config, p, false);314 }315 });316 });317 test.concurrent('disable all hoist for every workspace', (): Promise<void> => {318 return runInstall({}, 'workspaces-install-nohoist-all-from-root', async config => {319 const existingPackages = [320 'workspace-disable-a',321 'workspace-disable-all',322 'workspace-hoist-all',323 'workspace-disable-all/c',324 'workspace-disable-all/b',325 'workspace-disable-all/d',326 'workspace-disable-a/a',327 'workspace-disable-a/b',328 'workspace-disable-a/d',329 'workspace-hoist-all/b',330 'workspace-hoist-all/d',331 ];332 const notExistingPackages = ['a', 'b', 'c', 'd'];333 for (const p of existingPackages) {334 await checkPackage(config, p, true);335 }336 for (const p of notExistingPackages) {337 await checkPackage(config, p, false);338 }339 });340 });341 test.concurrent('disable some hoist for every workspace', (): Promise<void> => {342 return runInstall({}, 'workspaces-install-nohoist-some-from-root', async config => {343 const existingPackages = [344 'workspace-disable-a',345 'workspace-disable-all',346 'workspace-hoist-all',347 'workspace-disable-all/c',348 'workspace-disable-all/b',349 'workspace-disable-all/d',350 'workspace-disable-a/a',351 'workspace-disable-a/b',352 'workspace-disable-a/d',353 'workspace-hoist-all/d',354 'c',355 'b',356 ];357 const notExistingPackages = ['a', 'd'];358 for (const p of existingPackages) {359 await checkPackage(config, p, true);360 }361 for (const p of notExistingPackages) {362 await checkPackage(config, p, false);363 }364 });365 });366 test.concurrent('disable hoisting package across versions', (): Promise<void> => {367 return runInstall({}, 'workspaces-install-nohoist-across-versions', async config => {368 const existingPackages = [369 'workspace-1',370 'workspace-2',371 'workspace-3',372 'workspace-1/c',373 'workspace-1/b',374 'workspace-1/a',375 'workspace-2/b',376 'workspace-2/c',377 'workspace-2/b',378 'workspace-2/c/b',379 'workspace-3/b',380 'd',381 ];...
lockfiles.js
Source:lockfiles.js
...11const fsNode = require('fs');12const path = require('path');13const os = require('os');14test('does fetch files from the local filesystem', (): Promise<void> => {15 return runInstall(16 {},17 'install-should-fetch-local-tarballs',18 (config): Promise<void> => {19 return Promise.resolve();20 },21 async cwd => {22 let packageJson = await fs.readFile(`${cwd}/package.json`);23 packageJson = packageJson.replace(/%%CWD%%/g, cwd.replace(/\\/g, `/`));24 await fs.writeFile(`${cwd}/package.json`, packageJson);25 },26 );27});28test.concurrent("doesn't write new lockfile if existing one satisfied", (): Promise<void> => {29 return runInstall({}, 'install-dont-write-lockfile-if-satisfied', async (config): Promise<void> => {30 const lockfile = await fs.readFile(path.join(config.cwd, 'yarn.lock'));31 expect(lockfile.indexOf('foobar')).toBeGreaterThanOrEqual(0);32 });33});34test.concurrent("writes new lockfile if existing one isn't satisfied", async (): Promise<void> => {35 await runInstall({}, 'install-write-lockfile-if-not-satisfied', async (config): Promise<void> => {36 const lockfile = await fs.readFile(path.join(config.cwd, 'yarn.lock'));37 expect(lockfile.indexOf('foobar')).toEqual(-1);38 });39});40test.concurrent('writes a lockfile when there are no dependencies', (): Promise<void> => {41 return runInstall({}, 'install-without-dependencies', async config => {42 const lockfileExists = await fs.exists(path.join(config.cwd, 'yarn.lock'));43 const installedDepFiles = await fs.walk(path.join(config.cwd, 'node_modules'));44 expect(lockfileExists).toEqual(true);45 // 1 for integrity file (located in node_modules)46 expect(installedDepFiles).toHaveLength(1);47 });48});49test.concurrent("throws an error if existing lockfile isn't satisfied with --frozen-lockfile", async (): Promise<50 void,51> => {52 const reporter = new reporters.ConsoleReporter({});53 let thrown = false;54 try {55 await runInstall({frozenLockfile: true}, 'install-throws-error-if-not-satisfied-and-frozen-lockfile', () => {});56 } catch (err) {57 thrown = true;58 expect(err.message).toContain(reporter.lang('frozenLockfileError'));59 }60 expect(thrown).toEqual(true);61});62test.concurrent(63 "doesn't write new lockfile if existing one satisfied but not fully optimized with --frozen-lockfile",64 (): Promise<void> => {65 return runInstall(66 {frozenLockfile: true},67 'install-should-not-write-lockfile-if-not-optimized-and-frozen',68 async (config): Promise<void> => {69 const lockfile = await fs.readFile(path.join(config.cwd, 'yarn.lock'));70 expect(lockfile.indexOf('left-pad@1.1.3:')).toBeGreaterThanOrEqual(0);71 },72 );73 },74);75test.concurrent('install transitive optional dependency from lockfile', (): Promise<void> => {76 return runInstall({}, 'install-optional-dep-from-lockfile', (config, reporter, install) => {77 expect(install && install.resolver && install.resolver.patterns['fsevents@^1.0.0']).toBeTruthy();78 });79});80test.concurrent('root install from shrinkwrap', (): Promise<void> => {81 return runInstall({}, 'root-install-with-lockfile');82});83test.concurrent('install have a clean node_modules after lockfile update (branch switch scenario)', (): Promise<84 void,85> => {86 // A@1 -> B@187 // B@288 // after package.json/lock file update89 // A@1.2 -> B@1.290 // (deduped)91 // A@1.292 // B@1.293 return runInstall({}, 'install-should-cleanup-when-package-json-changed', async (config, reporter): Promise<void> => {94 expect(await getPackageVersion(config, 'dep-a')).toEqual('1.0.0');95 expect(await getPackageVersion(config, 'dep-b')).toEqual('2.0.0');96 expect(await getPackageVersion(config, 'dep-a/dep-b')).toEqual('1.0.0');97 await fs.unlink(path.join(config.cwd, 'yarn.lock'));98 await fs.unlink(path.join(config.cwd, 'package.json'));99 await fs.copy(path.join(config.cwd, 'yarn.lock.after'), path.join(config.cwd, 'yarn.lock'), reporter);100 await fs.copy(path.join(config.cwd, 'package.json.after'), path.join(config.cwd, 'package.json'), reporter);101 const reinstall = new Install({}, config, reporter, await Lockfile.fromDirectory(config.cwd));102 await reinstall.init();103 expect(await getPackageVersion(config, 'dep-a')).toEqual('1.2.0');104 expect(await getPackageVersion(config, 'dep-b')).toEqual('1.2.0');105 });106});107test.concurrent('install have a clean node_modules after lockfile update (branch switch scenario 2)', (): Promise<108 void,109> => {110 // A@1 -> B@1111 // after package.json/lock file update112 // A@1.2113 return runInstall({}, 'install-should-cleanup-when-package-json-changed-2', async (config, reporter): Promise<114 void,115 > => {116 expect(await getPackageVersion(config, 'dep-a')).toEqual('1.0.0');117 expect(await getPackageVersion(config, 'dep-b')).toEqual('1.0.0');118 await fs.unlink(path.join(config.cwd, 'yarn.lock'));119 await fs.unlink(path.join(config.cwd, 'package.json'));120 await fs.copy(path.join(config.cwd, 'yarn.lock.after'), path.join(config.cwd, 'yarn.lock'), reporter);121 await fs.copy(path.join(config.cwd, 'package.json.after'), path.join(config.cwd, 'package.json'), reporter);122 const reinstall = new Install({}, config, reporter, await Lockfile.fromDirectory(config.cwd));123 await reinstall.init();124 expect(await getPackageVersion(config, 'dep-a')).toEqual('1.2.0');125 expect(await isPackagePresent(config, 'dep-b')).toEqual(false);126 });127});128test.concurrent('install should write and read integrity file based on lockfile entries', (): Promise<void> => {129 return runInstall({}, 'lockfile-stability', async (config, reporter) => {130 let lockContent = await fs.readFile(path.join(config.cwd, 'yarn.lock'));131 lockContent += `132# changed the file, integrity should be fine133 `;134 await fs.writeFile(path.join(config.cwd, 'yarn.lock'), lockContent);135 let allCorrect = true;136 try {137 await check(config, reporter, {integrity: true}, []);138 } catch (err) {139 allCorrect = false;140 }141 expect(allCorrect).toBe(true);142 // install should bail out with integrity check143 await fs.unlink(path.join(config.cwd, 'node_modules', 'mime-types'));144 const reinstall = new Install({}, config, reporter, await Lockfile.fromDirectory(config.cwd));145 await reinstall.init();146 // integrity check should keep passing147 allCorrect = true;148 try {149 await check(config, reporter, {integrity: true}, []);150 } catch (err) {151 allCorrect = false;152 }153 expect(allCorrect).toBe(true);154 // full check should fail because of deleted file155 allCorrect = false;156 try {157 await check(config, reporter, {integrity: false}, []);158 } catch (err) {159 allCorrect = true;160 }161 expect(allCorrect).toBe(true);162 });163});164test.concurrent('install should retain artifacts when missing integrity file', (): Promise<void> => {165 return runInstall({}, 'install-should-retain-artifacts-when-missing-integrity', async (config, reporter) => {166 const expectedArtifacts = ['foo.txt'];167 const integrityLoc = path.join(config.cwd, 'node_modules', constants.INTEGRITY_FILENAME);168 const beforeIntegrity = await fs.readJson(integrityLoc);169 expect(beforeIntegrity.artifacts['a@0.0.0']).toEqual(expectedArtifacts);170 await fs.unlink(integrityLoc);171 const reinstall = new Install({}, config, reporter, await Lockfile.fromDirectory(config.cwd));172 await reinstall.init();173 const afterIntegrity = await fs.readJson(integrityLoc);174 expect(afterIntegrity.artifacts['a@0.0.0']).toEqual(expectedArtifacts);175 });176});177test.concurrent('install should not continue if integrity check passes', (): Promise<void> => {178 return runInstall({}, 'lockfile-stability', async (config, reporter) => {179 await fs.writeFile(path.join(config.cwd, 'node_modules', 'yarn.test'), 'YARN TEST');180 // install should bail out with integrity check and not remove extraneous file181 let reinstall = new Install({}, config, reporter, await Lockfile.fromDirectory(config.cwd));182 await reinstall.init();183 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'yarn.test'))).toBeTruthy();184 await fs.unlink(path.join(config.cwd, 'node_modules', 'yarn.test'));185 reinstall = new Install({}, config, reporter, await Lockfile.fromDirectory(config.cwd));186 await reinstall.init();187 expect(!await fs.exists(path.join(config.cwd, 'node_modules', 'yarn.test'))).toBeTruthy();188 });189});190test.concurrent('install should not rewrite lockfile with no substantial changes', (): Promise<void> => {191 const fixture = 'lockfile-no-rewrites';192 return runInstall({}, fixture, async (config, reporter) => {193 const originalLockContent = await fs.readFile(path.join(config.cwd, 'yarn.lock'));194 const lockContent =195 originalLockContent +196 `197# changed the file, and it should remain changed after force install198 `;199 await fs.writeFile(path.join(config.cwd, 'yarn.lock'), lockContent);200 await fs.unlink(path.join(config.cwd, 'node_modules', constants.INTEGRITY_FILENAME));201 let reinstall = new Install({}, config, reporter, await Lockfile.fromDirectory(config.cwd));202 await reinstall.init();203 let newLockContent = await fs.readFile(path.join(config.cwd, 'yarn.lock'));204 expect(newLockContent).toEqual(lockContent);205 // force should rewrite lockfile206 reinstall = new Install({force: true}, config, reporter, await Lockfile.fromDirectory(config.cwd));207 await reinstall.init();208 newLockContent = await fs.readFile(path.join(config.cwd, 'yarn.lock'));209 expect(newLockContent).not.toEqual(lockContent);210 });211});212test.concurrent('lockfile should be created when missing even if integrity matches', (): Promise<void> => {213 return runInstall({}, 'lockfile-missing', async (config, reporter) => {214 expect(await fs.exists(path.join(config.cwd, 'yarn.lock'))).toBeTruthy();215 });216});217test.concurrent('install infers line endings from existing win32 lockfile', async (): Promise<void> => {218 await runInstall(219 {},220 'install-infers-line-endings-from-existing-lockfile',221 async (config): Promise<void> => {222 const lockfile = await promisify(fsNode.readFile)(path.join(config.cwd, 'yarn.lock'), 'utf8');223 expect(lockfile).toMatch(/\r\n/);224 expect(lockfile).not.toMatch(/[^\r]\n/);225 },226 async (cwd): Promise<void> => {227 const existingLockfile = '# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.\r\n';228 await promisify(fsNode.writeFile)(path.join(cwd, 'yarn.lock'), existingLockfile, 'utf8');229 },230 );231});232test.concurrent('install infers line endings from existing unix lockfile', async (): Promise<void> => {233 await runInstall(234 {},235 'install-infers-line-endings-from-existing-lockfile',236 async (config): Promise<void> => {237 const lockfile = await promisify(fsNode.readFile)(path.join(config.cwd, 'yarn.lock'), 'utf8');238 expect(lockfile).toMatch(/[^\r]\n/);239 expect(lockfile).not.toMatch(/\r\n/);240 },241 async (cwd): Promise<void> => {242 const existingLockfile = '# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.\n';243 await promisify(fsNode.writeFile)(path.join(cwd, 'yarn.lock'), existingLockfile, 'utf8');244 },245 );246});247test.concurrent("install uses OS line endings when lockfile doesn't exist", async (): Promise<void> => {248 await runInstall({}, 'install-infers-line-endings-from-existing-lockfile', async (config): Promise<void> => {249 const lockfile = await promisify(fsNode.readFile)(path.join(config.cwd, 'yarn.lock'), 'utf8');250 expect(lockfile.indexOf(os.EOL)).toBeGreaterThan(0);251 });252});253test.concurrent('install should rewrite lockfile if patterns can be merged', (): Promise<void> => {254 const fixture = 'lockfile-trimmed';255 return runInstall({}, fixture, async (config, reporter) => {256 const lockContent = await fs.readFile(path.join(config.cwd, 'yarn.lock'));257 expect(lockContent).toContain('mime-db@^1.0.0');258 expect(lockContent).not.toContain('https://fakepath.wont.download.com/mime-db/-/mime-db-1.0.0.tgz');259 });260});261test.concurrent("install should fix if lockfile patterns don't match resolved version", (): Promise<void> => {262 const fixture = 'lockfile-fixed';263 return runInstall({}, fixture, async (config, reporter) => {264 const lockContent = await fs.readFile(path.join(config.cwd, 'yarn.lock'));265 expect(lockContent).not.toContain('mime-db-1.24.0.tgz');266 expect(lockContent).toContain('mime-db-1.23.0.tgz');267 expect(lockContent).not.toContain('left-pad-1.1.3.tgz');268 expect(lockContent).toContain('left-pad-1.1.2.tgz');269 });270});271test.concurrent('install should warn if a conflicting npm package-lock.json exists', (): Promise<void> => {272 const fixture = 'lockfile-conflict-package-lock-json';273 return runInstall({}, fixture, (config, reporter, install, getStdout) => {274 expect(getStdout()).toContain('package-lock.json found');275 });276});277test.concurrent('install should warn if a conflicting npm npm-shrinkwrap.json exists', (): Promise<void> => {278 const fixture = 'lockfile-conflict-npm-shrinkwrap-json';279 return runInstall({}, fixture, (config, reporter, install, getStdout) => {280 expect(getStdout()).toContain('npm-shrinkwrap.json found');281 });...
focus.js
Source:focus.js
...9test.concurrent('focus does not work from a non-workspaces project', async (): Promise<void> => {10 let error = '';11 const reporter = new reporters.ConsoleReporter({});12 try {13 await runInstall({focus: true}, 'install-production');14 } catch (e) {15 error = e.message;16 }17 expect(error).toContain(reporter.lang('workspacesFocusRootCheck'));18});19test.concurrent('focus does not work from the root of a workspaces project', async (): Promise<void> => {20 let error = '';21 const reporter = new reporters.ConsoleReporter({});22 try {23 await runInstall({focus: true}, 'published-monorepo');24 } catch (e) {25 error = e.message;26 }27 expect(error).toContain(reporter.lang('workspacesFocusRootCheck'));28});29test.concurrent('focus does a normal workspace installation', (): Promise<void> => {30 return runInstall(31 {focus: true},32 {source: 'published-monorepo', cwd: '/packages/example-yarn-workspace-1'},33 async (config): Promise<void> => {34 const packageFile = await fs.readFile(35 path.join(config.cwd, '..', '..', 'node_modules', 'example-yarn-workspace-2', 'package.json'),36 );37 expect(JSON.parse(packageFile).version).toEqual('1.1.1');38 const readme = await fs.readFile(39 path.join(config.cwd, '..', '..', 'node_modules', 'example-yarn-workspace-2', 'README.md'),40 );41 expect(readme.split('\n')[0]).toEqual('WORKSPACES ROCK2!');42 },43 );44});45test.concurrent('focus shallowly installs sibling workspaces under target', (): Promise<void> => {46 return runInstall(47 {focus: true},48 {source: 'published-monorepo', cwd: '/packages/example-yarn-workspace-1'},49 async (config): Promise<void> => {50 const packageFile = await fs.readFile(51 path.join(config.cwd, 'node_modules', 'example-yarn-workspace-2', 'package.json'),52 );53 expect(JSON.parse(packageFile).version).toEqual('1.1.1');54 const readme = await fs.readFile(path.join(config.cwd, 'node_modules', 'example-yarn-workspace-2', 'README.md'));55 expect(readme.split('\n')[0]).toEqual('WORKSPACES ROCK2!');56 },57 );58});59test.concurrent('focus should not bail out early after an un-focused install', (): Promise<void> => {60 return runInstall({}, 'published-monorepo', async (config, reporter) => {61 const oldCwd = config.cwd;62 await fs.writeFile(path.join(oldCwd, 'node_modules', 'yarn.test'), 'YARN TEST');63 config.cwd += '/packages/example-yarn-workspace-1';64 config.focus = true;65 config.focusedWorkspaceName = 'example-yarn-workspace-1';66 const reinstall = new Install({}, config, reporter, await Lockfile.fromDirectory(oldCwd));67 await reinstall.init();68 expect(await fs.exists(path.join(oldCwd, 'node_modules', 'yarn.test'))).toBeFalsy();69 });70});71test.concurrent('repeated focused installs should bail out early', (): Promise<void> => {72 return runInstall(73 {focus: true},74 {source: 'published-monorepo', cwd: '/packages/example-yarn-workspace-1'},75 async (config, reporter) => {76 await fs.writeFile(path.join(config.cwd, 'node_modules', 'yarn.test'), 'YARN TEST');77 const lockfileDir = path.join(config.cwd, '..', '..');78 const reinstall = new Install({}, config, reporter, await Lockfile.fromDirectory(lockfileDir));79 await reinstall.init();80 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'yarn.test'))).toBeTruthy();81 await fs.unlink(path.join(config.cwd, 'node_modules', 'yarn.test'));82 },83 );84});85test.concurrent('switching directories for focused installs should fail integrity checks and reinstall', (): Promise<86 void,87> => {88 return runInstall(89 {focus: true},90 {source: 'published-monorepo', cwd: '/packages/example-yarn-workspace-1'},91 async (config, reporter) => {92 const rootDir = path.join(config.cwd, '..', '..');93 await fs.writeFile(path.join(rootDir, 'node_modules', 'yarn.test'), 'YARN TEST');94 config.cwd = path.join(rootDir, 'packages', 'example-yarn-workspace-2');95 config.focusedWorkspaceName = 'example-yarn-workspace-2';96 const reinstall = new Install({}, config, reporter, await Lockfile.fromDirectory(rootDir));97 await reinstall.init();98 expect(await fs.exists(path.join(rootDir, 'node_modules', 'yarn.test'))).toBeFalsy();99 },100 );101});102test.concurrent(103 'focus shallowly installs anything that a sibling needed to shallowly install underneath that sibling',104 (): Promise<void> => {105 return runInstall(106 {focus: true},107 {source: 'focus-conflicts', cwd: '/packages/example-yarn-workspace-1'},108 async (config, reporter) => {109 const packageFile = await fs.readFile(110 path.join(config.cwd, 'node_modules', 'example-yarn-workspace-2', 'node_modules', 'left-pad', 'package.json'),111 );112 expect(JSON.parse(packageFile).version).toEqual('1.1.2');113 },114 );115 },116);117test.concurrent("focus does not shallowly install a sibling's dev dependencies", (): Promise<void> => {118 return runInstall(119 {focus: true},120 {source: 'published-monorepo', cwd: '/packages/example-yarn-workspace-4'},121 async (config, reporter) => {122 expect(123 await fs.exists(path.join(config.cwd, 'node_modules', 'example-yarn-workspace-3', 'node_modules', 'left-pad')),124 ).toBeFalsy();125 },126 );127});128test.concurrent("focus runs shallow dependencies' postinstall scripts", (): Promise<void> => {129 return runInstall(130 {focus: true},131 {source: 'published-monorepo', cwd: '/packages/example-yarn-workspace-4'},132 async (config, reporter) => {133 expect(134 await fs.exists(path.join(config.cwd, 'node_modules', 'example-yarn-workspace-3', 'temp.out')),135 ).toBeTruthy();136 },137 );138});139test.concurrent('focus installs transitive dependencies shallowly', (): Promise<void> => {140 return runInstall(141 {focus: true},142 {source: 'published-monorepo', cwd: '/packages/example-yarn-workspace-4'},143 async (config, reporter) => {144 expect(145 await fs.exists(path.join(config.cwd, 'node_modules', 'example-yarn-workspace-1', 'package.json')),146 ).toBeTruthy();147 },148 );149});150test.concurrent(151 'focus does not install transitive devdependencies shallowly (but does install non-transitive devdeps)',152 (): Promise<void> => {153 return runInstall(154 {focus: true},155 {source: 'published-monorepo', cwd: '/packages/example-yarn-workspace-6'},156 async (config, reporter) => {157 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'example-yarn-workspace-5'))).toBeTruthy();158 expect(159 await fs.exists(160 path.join(161 config.cwd,162 'node_modules',163 'example-yarn-workspace-5',164 'node_modules',165 'example-yarn-workspace-2',166 ),167 ),168 ).toBeFalsy();169 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'example-yarn-workspace-2'))).toBeFalsy();170 },171 );172 },173);174test.concurrent(175 'focus does not shallowly install current version of sibling if another version is specified in package.json',176 (): Promise<void> => {177 return runInstall(178 {focus: true},179 {source: 'focus-different-versions', cwd: '/packages/example-yarn-workspace-1'},180 async (config, reporter) => {181 const packageFile = await fs.readFile(182 path.join(config.cwd, 'node_modules', 'example-yarn-workspace-2', 'package.json'),183 );184 expect(JSON.parse(packageFile).version).toEqual('1.0.1');185 },186 );187 },188);189test.concurrent('focus works correctly when focusing on a scoped package', (): Promise<void> => {190 return runInstall({focus: true}, {source: 'focus-scoped', cwd: '/packages/scoped'}, async (config, reporter) => {191 const packageFile = await fs.readFile(192 path.join(config.cwd, 'node_modules', 'example-yarn-workspace-2', 'package.json'),193 );194 expect(JSON.parse(packageFile).version).toEqual('1.1.1');195 });196});197describe('nohoist', () => {198 test.concurrent('focus installs nohoist dependencies shallowly', (): Promise<void> => {199 return runInstall(200 {focus: true},201 {source: 'focus-nohoist', cwd: '/packages/example-yarn-workspace-1'},202 async (config, reporter) => {203 const moduleDir = path.join(config.cwd, 'node_modules', 'example-yarn-workspace-2');204 expect(await fs.exists(path.join(moduleDir, 'package.json'))).toBeTruthy();205 const stat = await fs.lstat(moduleDir);206 expect(stat.isSymbolicLink()).toEqual(false);207 },208 );209 });210 test.concurrent('focus does not do nested shallow installs of transitive nohoist packages', (): Promise<void> => {211 return runInstall(212 {focus: true},213 {source: 'focus-nohoist', cwd: '/packages/example-yarn-workspace-3'},214 async (config, reporter) => {215 const moduleDir = path.join(216 config.cwd,217 'node_modules',218 'example-yarn-workspace-1',219 'node_modules',220 'example-yarn-workspace-2',221 );222 expect(await fs.exists(path.join(moduleDir, 'package.json'))).toBeFalsy();223 },224 );225 });226 test.concurrent(227 'focus installs the correct version when a package is nohoist but differs from the workspace version',228 (): Promise<void> => {229 return runInstall(230 {focus: true},231 {source: 'focus-nohoist-different-versions', cwd: '/packages/example-yarn-workspace-6'},232 async (config, reporter) => {233 const packageFile = await fs.readFile(234 path.join(config.cwd, 'node_modules', 'example-yarn-workspace-2', 'package.json'),235 );236 expect(JSON.parse(packageFile).version).toEqual('1.0.0');237 },238 );239 },240 );...
resolutions.js
Source:resolutions.js
...7jasmine.DEFAULT_TIMEOUT_INTERVAL = 150000;8const path = require('path');9const semver = require('semver');10test.concurrent('install with simple exact resolutions should override all versions', (): Promise<void> => {11 return runInstall({}, {source: 'resolutions', cwd: 'simple-exact'}, async config => {12 expect(await getPackageVersion(config, 'a')).toEqual('1.0.0');13 expect(await getPackageVersion(config, 'b')).toEqual('1.0.0');14 expect(await getPackageVersion(config, 'd1')).toEqual('2.0.0');15 expect(await getPackageVersion(config, 'd2')).toEqual('1.0.0');16 expect(await isPackagePresent(config, 'a/d1')).toEqual(false);17 expect(await isPackagePresent(config, 'a/d2')).toEqual(false);18 expect(await isPackagePresent(config, 'b/d1')).toEqual(false);19 expect(await isPackagePresent(config, 'b/d2')).toEqual(false);20 });21});22test.concurrent('install with subtree exact resolutions should override subtree versions', (): Promise<void> => {23 return runInstall({}, {source: 'resolutions', cwd: 'subtree-exact'}, async config => {24 expect(await getPackageVersion(config, 'left-pad')).toEqual('1.0.0');25 expect(await getPackageVersion(config, 'd2')).toEqual('1.0.0');26 expect(await getPackageVersion(config, 'd2/left-pad')).toEqual('1.1.1');27 expect(await getPackageVersion(config, 'c')).toEqual('1.0.0');28 expect(await getPackageVersion(config, 'c/left-pad')).toEqual('1.1.2');29 });30});31test.concurrent('install with --frozen-lockfile with resolutions', async (): Promise<void> => {32 const reporter = new ConsoleReporter({});33 try {34 await runInstall({frozenLockfile: true}, {source: 'resolutions', cwd: 'frozen-lockfile'}, async config => {35 expect(await getPackageVersion(config, 'left-pad')).toEqual('1.1.3');36 });37 } catch (err) {38 expect(err.message).not.toContain(reporter.lang('frozenLockfileError'));39 }40});41test.concurrent('install with resolutions on optional dependencies should not resolve', (): Promise<void> => {42 return runInstall({ignoreOptional: true}, {source: 'resolutions', cwd: 'optional-deps'}, async config => {43 expect(await isPackagePresent(config, 'left-pad')).toEqual(false);44 });45});46test.concurrent('install with exotic resolutions should override versions', (): Promise<void> => {47 return runInstall({}, {source: 'resolutions', cwd: 'exotic-version'}, async config => {48 expect(await getPackageVersion(config, 'left-pad')).toEqual('1.1.1');49 });50});51test.concurrent('install with range resolutions should override versions', (): Promise<void> => {52 return runInstall({}, {source: 'resolutions', cwd: 'simple-range'}, async config => {53 expect(await getPackageVersion(config, 'left-pad')).toEqual('1.1.1');54 });55});56test.concurrent('should warn when resolution entries are incorrrect or incompatible', async (): Promise<void> => {57 let error;58 try {59 await runInstall({}, {source: 'resolutions', cwd: 'invalid-entries'});60 } catch (e) {61 error = e.message;62 }63 expect(error).toContain('Resolution field "left-pad@1.0.0" is incompatible with requested version "left-pad@~1.1.0');64 expect(error).toContain('Resolution field "wrongversion" has an invalid version entry and may be ignored');65 expect(error).toContain('Resolution field "invalidname/" does not end with a valid package name and will be ignored');66});67test.concurrent('install with resolutions should correctly install simple scoped packages', (): Promise<void> => {68 return runInstall({}, {source: 'resolutions', cwd: 'scoped-simple'}, async config => {69 expect(await getPackageVersion(config, '@scoped/a')).toEqual('1.0.0');70 expect(await getPackageVersion(config, '@scoped/b')).toEqual('2.0.0');71 });72});73test.concurrent('install with resolutions should correctly install toplevel scoped packages', (): Promise<void> => {74 return runInstall({}, {source: 'resolutions', cwd: 'scoped-toplevel'}, async config => {75 expect(await getPackageVersion(config, '@scoped/a')).toEqual('1.0.0');76 expect(await getPackageVersion(config, '@scoped/b')).toEqual('2.0.0');77 });78});79test.concurrent('install with nested resolutions', (): Promise<void> => {80 return runInstall({}, 'install-nested-resolutions', async config => {81 expect(await getPackageVersion(config, 'strip-ansi')).toEqual('2.0.1');82 expect(await getPackageVersion(config, 'ansi-regex')).toEqual('1.1.1');83 });84});85test.concurrent('install with nested resolutions using flat mode', (): Promise<void> => {86 return runInstall({flat: true}, 'install-nested-resolutions', async config => {87 expect(await getPackageVersion(config, 'strip-ansi')).toEqual('2.0.1');88 expect(await getPackageVersion(config, 'ansi-regex')).toEqual('1.1.1');89 });90});91test.concurrent('install with resolution settings should correctly bailout during the integrity check', (): Promise<92 void,93> => {94 return runInstall(95 {},96 {source: 'resolutions', cwd: 'install-with-resolution-should-bailout-during-the-integrity-check'},97 async (config, reporter): Promise<void> => {98 // remove file99 await fs.unlink(path.join(config.cwd, 'node_modules', 'left-pad', 'index.js'));100 // run install again101 const reinstall = new Install({}, config, reporter, await Lockfile.fromDirectory(config.cwd));102 await reinstall.init();103 // don't expect file being recreated because install should have bailed out104 expect(await fs.exists(path.join(config.cwd, 'node_modules', 'left-pad', 'index.js'))).toBe(false);105 },106 );107});108test.concurrent('adding resolutions after install should cause lockfile regeneration on second install', (): Promise<109 void,110> => {111 return runInstall(112 {},113 {source: 'resolutions', cwd: 'adding-resolutions-should-cause-lockfile-regeneration'},114 async (config, reporter): Promise<void> => {115 const packageJson = await fs.readFile(path.join(config.cwd, 'package.json'));116 // create new package.json with resolutions which override e/left-pad version117 const newPackageJson = JSON.parse(packageJson);118 newPackageJson.resolutions = {};119 newPackageJson.resolutions['e/left-pad'] = '1.1.1';120 // write new package.json121 await fs.writeFile(path.join(config.cwd, 'package.json'), JSON.stringify(newPackageJson));122 // expect left-pad in e/node_modules to be present and have corrent version123 // since it is not satisfied by top-level dependency124 expect(semver.satisfies(await getPackageVersion(config, 'e/left-pad'), '^1.0.0')).toBe(true);125 // run install again...
cache.js
Source:cache.js
...15 return getStdout();16 },17);18test('list', async (): Promise<void> => {19 await runInstall({}, 'artifacts-finds-and-saves', async (config): Promise<void> => {20 const reporter = new BufferReporter();21 await run(config, reporter, {}, ['list']);22 const stdout = reporter.getBufferText();23 expect(stdout).toContain('dummy');24 expect(stdout).toContain('0.0.0');25 });26});27test('list skips corrupted package', async (): Promise<void> => {28 await runCache(['list'], {}, 'corrupted', (config, reporter, stdout) => {29 expect(stdout).not.toContain(JSON.stringify('corrupted'));30 expect(stdout).toContain(JSON.stringify('good-module'));31 });32});33test('ls with scoped packages', async (): Promise<void> => {34 await runInstall({}, 'install-from-authed-private-registry', async (config): Promise<void> => {35 const reporter = new BufferReporter();36 await run(config, reporter, {}, ['list']);37 const stdout = reporter.getBufferText();38 expect(stdout).toContain('@types/lodash');39 expect(stdout).toContain('4.14.37');40 });41});42test('ls with filter that matches cache', async (): Promise<void> => {43 await runInstall({}, 'artifacts-finds-and-saves', async (config): Promise<void> => {44 const reporter = new BufferReporter();45 await run(config, reporter, {pattern: 'dummy'}, ['list']);46 const stdout = reporter.getBufferText();47 expect(stdout).toContain('dummy');48 expect(stdout).toContain('0.0.0');49 });50});51test('ls with filter that matches cache with wildcard', async (): Promise<void> => {52 await runInstall({}, 'artifacts-finds-and-saves', async (config): Promise<void> => {53 const reporter = new BufferReporter();54 await run(config, reporter, {pattern: 'dum*'}, ['list']);55 const stdout = reporter.getBufferText();56 expect(stdout).toContain('dummy');57 expect(stdout).toContain('0.0.0');58 });59});60test('ls with multiple patterns, one matching', async (): Promise<void> => {61 await runInstall({}, 'artifacts-finds-and-saves', async (config): Promise<void> => {62 const reporter = new BufferReporter();63 await run(config, reporter, {pattern: 'dum|dummy'}, ['list']);64 const stdout = reporter.getBufferText();65 expect(stdout).toContain('dummy');66 expect(stdout).toContain('0.0.0');67 });68});69test('ls with pattern that only partially matches', async (): Promise<void> => {70 await runInstall({}, 'artifacts-finds-and-saves', async (config): Promise<void> => {71 const reporter = new BufferReporter();72 await run(config, reporter, {pattern: 'dum'}, ['list']);73 const stdout = reporter.getBufferText();74 expect(stdout).toContain('dummy');75 expect(stdout).toContain('0.0.0');76 });77});78test('ls with filter that does not match', async (): Promise<void> => {79 await runInstall({}, 'artifacts-finds-and-saves', async (config): Promise<void> => {80 const reporter = new BufferReporter();81 await run(config, reporter, {pattern: 'noMatch'}, ['list']);82 const stdout = reporter.getBufferText();83 expect(stdout).not.toContain('dummy');84 expect(stdout).not.toContain('0.0.0');85 });86});87test('ls filter by pattern with scoped package', async (): Promise<void> => {88 await runInstall({}, 'install-from-authed-private-registry', async (config): Promise<void> => {89 const reporter = new BufferReporter();90 await run(config, reporter, {pattern: '@types/*'}, ['list']);91 const stdout = reporter.getBufferText();92 expect(stdout).toContain('@types/lodash');93 expect(stdout).toContain('4.14.37');94 });95});96test('dir', async (): Promise<void> => {97 await runCache(['dir'], {}, '', (config, reporter, stdout) => {98 expect(stdout).toContain(JSON.stringify(config.cacheFolder));99 });100});101test('clean', async (): Promise<void> => {102 await runInstall({}, 'artifacts-finds-and-saves', async (config): Promise<void> => {103 let files = await fs.readdir(config.cacheFolder);104 // Asserting cache size is 1...105 // we need to add one for the .tmp folder106 //107 // Per #2860, file: protocol installs may add the same package to the cache108 // multiple times if it is installed with a force flag or has an install script.109 // We'll add another for a total of 3 because this particular fixture has110 // an install script.111 expect(files.length).toEqual(3);112 const reporter = new BufferReporter();113 await run(config, reporter, {}, ['clean']);114 expect(await fs.exists(config.cacheFolder)).toBeTruthy();115 files = await fs.readdir(config.cacheFolder);116 expect(files.length).toEqual(0);117 });118});119test('clean with package name', async (): Promise<void> => {120 await runInstall({}, 'artifacts-finds-and-saves', async (config): Promise<void> => {121 let files = await fs.readdir(config.cacheFolder);122 expect(files.length).toEqual(3);123 const reporter = new BufferReporter();124 await run(config, reporter, {}, ['clean', 'unknownname']);125 expect(await fs.exists(config.cacheFolder)).toBeTruthy();126 files = await fs.readdir(config.cacheFolder);127 expect(files.length).toEqual(3); // Nothing deleted128 await run(config, reporter, {}, ['clean', 'dummy']);129 expect(await fs.exists(config.cacheFolder)).toBeTruthy();130 files = await fs.readdir(config.cacheFolder);131 expect(files.length).toEqual(1); // Only .tmp folder left132 });133});134test('clean with multiple package names', async (): Promise<void> => {135 await runInstall({}, 'install-production', async (config): Promise<void> => {136 let files = await fs.readdir(config.cacheFolder);137 expect(files.length).toEqual(3);138 const reporter = new BufferReporter();139 await run(config, reporter, {}, ['clean', 'is-array', 'left-pad']);140 expect(await fs.exists(config.cacheFolder)).toBeTruthy();141 files = await fs.readdir(config.cacheFolder);142 expect(files.length).toEqual(1); // Only .tmp folder left143 });...
cli.js
Source:cli.js
1import arg from 'arg';2import inquirer from 'inquirer';3import { createApp } from './main';4function parseArgumentsIntoOptions(rawArgs) {5 const args = arg(6 {7 '--git': Boolean,8 '--yes': Boolean,9 '--install': Boolean,10 '-g': '--git',11 '-y': '--yes',12 '-i': '--install'13 },14 {15 argv: rawArgs.slice(2)16 }17 );18 return {19 skipPrompts: args['--yes'] || false,20 git: args['--git'] || false,21 template: args._[0],22 runInstall: args['--install'] || false23 };24}25async function promptForMissingOptions(options) {26 const defaultTemplate = 'default';27 const initialGitValue = 'true';28 const initialRuninstallValue = 'true';29 if (options.skipPrompts) {30 return {31 ...options,32 template: options.template || defaultTemplate,33 git: options.git || initialGitValue,34 runInstall: options.runInstall || initialRuninstallValue35 };36 }37 const questions = [];38 if (!options.template) {39 questions.push({40 type: 'list',41 name: 'template',42 message: 'Please choose which app template to use',43 choices: ['default', 'basic'],44 default: defaultTemplate45 });46 }47 if (!options.git) {48 questions.push({49 type: 'confirm',50 name: 'git',51 message: 'Would you like to initialize as a git repository?',52 default: true53 });54 }55 if (!options.runInstall) {56 questions.push({57 type: 'confirm',58 name: 'runInstall',59 message: 'Would you like to install all dependencies(Recommended)',60 default: true61 });62 }63 const answers = await inquirer.prompt(questions);64 return {65 ...options,66 template: options.template || answers.template,67 git: options.git || answers.git,68 runInstall: options.runInstall || answers.runInstall69 };70}71export async function cli(args) {72 let options = parseArgumentsIntoOptions(args);73 options = await promptForMissingOptions(options);74 await createApp(options);...
hooks.js
Source:hooks.js
...3test('install should call the resolveStep hook', async () => {4 global.experimentalYarnHooks = {5 resolveStep: jest.fn(cb => cb()),6 };7 await runInstall({}, 'install-production', config => {8 expect(global.experimentalYarnHooks.resolveStep.mock.calls.length).toEqual(1);9 });10 delete global.experimentalYarnHooks;11});12test('install should call the fetchStep hook', async () => {13 global.experimentalYarnHooks = {14 fetchStep: jest.fn(cb => cb()),15 };16 await runInstall({}, 'install-production', config => {17 expect(global.experimentalYarnHooks.fetchStep.mock.calls.length).toEqual(1);18 });19 delete global.experimentalYarnHooks;20});21test('install should call the linkStep hook', async () => {22 global.experimentalYarnHooks = {23 linkStep: jest.fn(cb => cb()),24 };25 await runInstall({}, 'install-production', config => {26 expect(global.experimentalYarnHooks.linkStep.mock.calls.length).toEqual(1);27 });28 delete global.experimentalYarnHooks;29});30test('install should call the buildStep hook', async () => {31 global.experimentalYarnHooks = {32 buildStep: jest.fn(cb => cb()),33 };34 await runInstall({}, 'install-production', config => {35 expect(global.experimentalYarnHooks.buildStep.mock.calls.length).toEqual(1);36 });37 delete global.experimentalYarnHooks;...
Using AI Code Generation
1describe('My First Test', () => {2 it('Does not do much!', () => {3 cy.contains('type').click()4 cy.url().should('include', '/commands/actions')5 cy.get('.action-email')6 .type('
Using AI Code Generation
1Cypress.Commands.add('runInstall', (command) => {2 cy.exec(command, {failOnNonZeroExit: false})3})4describe('My First Test', () => {5 it('Does not do much!', () => {6 cy.runInstall('npm install')7 expect(true).to.equal(true)8 })9})10describe('My First Test', () => {11 it('Does not do much!', () => {12 cy.runInstall('npm install')13 expect(true).to.equal(true)14 })15})
Cypress is a renowned Javascript-based open-source, easy-to-use end-to-end testing framework primarily used for testing web applications. Cypress is a relatively new player in the automation testing space and has been gaining much traction lately, as evidenced by the number of Forks (2.7K) and Stars (42.1K) for the project. LambdaTest’s Cypress Tutorial covers step-by-step guides that will help you learn from the basics till you run automation tests on LambdaTest.
You can elevate your expertise with end-to-end testing using the Cypress automation framework and stay one step ahead in your career by earning a Cypress certification. Check out our Cypress 101 Certification.
Watch this 3 hours of complete tutorial to learn the basics of Cypress and various Cypress commands with the Cypress testing at LambdaTest.
Get 100 minutes of automation test minutes FREE!!