Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
test('global installation', async (t) => {
prepare(t)
const globalPrefix = path.resolve('..', 'global')
const opts = await testDefaults({global: true, prefix: globalPrefix})
await installPkgs(['is-positive'], opts)
// there was an issue when subsequent installations were removing everything installed prior
// https://github.com/pnpm/pnpm/issues/808
await installPkgs(['is-negative'], opts)
const isPositive = require(path.join(globalPrefix, LAYOUT_VERSION, 'node_modules', 'is-positive'))
t.ok(typeof isPositive === 'function', 'isPositive() is available')
const isNegative = require(path.join(globalPrefix, LAYOUT_VERSION, 'node_modules', 'is-negative'))
t.ok(typeof isNegative === 'function', 'isNegative() is available')
})
test('readonly side effects cache', async (t) => {
const project = prepare(t)
const opts1 = await testDefaults({sideEffectsCache: true, verifyStoreIntegrity: false})
await installPkgs(['runas@3.1.1'], opts1)
// Modify the side effects cache to make sure we are using it
const cacheBuildDir = path.join(opts1.store, 'localhost+4873', 'runas', '3.1.1', 'side_effects', `${process.platform}-${process.arch}-node-${process.version.split('.')[0]}`, 'package', 'build')
await fs.writeFile(path.join(cacheBuildDir, 'new-file.txt'), 'some new content')
await rimraf('node_modules')
const opts2 = await testDefaults({sideEffectsCacheReadonly: true, verifyStoreIntegrity: false}, {}, {}, {packageImportMethod: 'copy'})
await installPkgs(['runas@3.1.1'], opts2)
t.ok(await exists(path.join('node_modules', 'runas', 'build', 'new-file.txt')), 'side effects cache correctly used')
await rimraf('node_modules')
// changing version to make sure we don't create the cache
await await installPkgs(['runas@3.1.0'], opts2)
t.ok(await exists(path.join('node_modules', 'runas', 'build')), 'build folder created')
test('readonly side effects cache', async (t) => {
const project = prepare(t)
const opts1 = await testDefaults({sideEffectsCache: true, verifyStoreIntegrity: false})
await installPkgs(['runas@3.1.1'], opts1)
// Modify the side effects cache to make sure we are using it
const cacheBuildDir = path.join(opts1.store, 'localhost+4873', 'runas', '3.1.1', 'side_effects', `${process.platform}-${process.arch}-node-${process.version.split('.')[0]}`, 'package', 'build')
await fs.writeFile(path.join(cacheBuildDir, 'new-file.txt'), 'some new content')
await rimraf('node_modules')
const opts2 = await testDefaults({sideEffectsCacheReadonly: true, verifyStoreIntegrity: false}, {}, {}, {packageImportMethod: 'copy'})
await installPkgs(['runas@3.1.1'], opts2)
t.ok(await exists(path.join('node_modules', 'runas', 'build', 'new-file.txt')), 'side effects cache correctly used')
await rimraf('node_modules')
// changing version to make sure we don't create the cache
await await installPkgs(['runas@3.1.0'], opts2)
t.ok(await exists(path.join('node_modules', 'runas', 'build')), 'build folder created')
t.notOk(await exists(path.join(opts2.store, 'localhost+4873', 'runas', '3.1.0', 'side_effects', `${process.platform}-${process.arch}-node-${process.version.split('.')[0]}`, 'package', 'build')), 'cache folder not created')
})
await installPkgs(['@private/foo'], opts)
await project.has('@private/foo')
// should work when a shrinkwrap is available
await rimraf('node_modules')
await rimraf(path.join('..', '.store'))
// Recreating options to have a new storeController with clean cache
opts = await testDefaults({}, {
rawNpmConfig,
registry: 'https://registry.npmjs.org/',
}, {
rawNpmConfig,
})
await installPkgs(['@private/foo'], opts)
await project.has('@private/foo')
})
test('fail on non-compatible store when forced during named installation', async (t) => {
const project = prepare(t)
const opts = await testDefaults({force: true})
await saveModulesYaml('0.32.0', opts.store)
try {
await installPkgs(['is-negative'], opts)
t.fail('should have failed')
} catch (err) {
t.ok(err.message.indexOf('Named installation cannot be used to regenerate the node_modules structure') !== -1)
}
})
test('do not run install scripts if unsafePerm is false', async (t: tape.Test) => {
const project = prepare(t, {
name: 'different-name',
scripts: {
install: `node -e "process.stdout.write('install')" | json-append output.json`,
postinstall: `node -e "process.stdout.write('postinstall')" | json-append output.json`,
preinstall: `node -e "process.stdout.write('preinstall')" | json-append output.json`,
},
})
const opts = await testDefaults({ unsafePerm: false })
await installPkgs(['json-append@1.1.1'], opts)
await install(opts)
const outputExists = await exists('output.json')
t.false(outputExists, 'no output expected as install scripts should not run')
})
test('idempotency (rimraf)', async (t: tape.Test) => {
const project = prepare(t)
const reporter = sinon.spy()
const opts = await testDefaults({reporter})
await installPkgs(['rimraf@2.5.1'], opts)
t.ok(reporter.calledWithMatch({
added: {
dependencyType: 'prod',
name: 'rimraf',
version: '2.5.1',
},
level: 'info',
name: 'pnpm:root',
} as RootLog), 'reported that rimraf added to the root')
reporter.resetHistory()
await installPkgs(['rimraf@2.5.1'], opts)
t.notOk(reporter.calledWithMatch({
test('nothing is needlessly removed from node_modules', async (t: tape.Test) => {
const project = prepare(t)
const opts = await testDefaults()
await installPkgs(['using-ajv', 'ajv-keywords@1.5.0'], opts)
t.ok(await exists(path.join(NM, '.localhost+4873', 'ajv-keywords', '1.5.0', 'ajv@4.10.4', NM, 'ajv')), 'peer dependency is linked')
t.ok(await exists(path.join(NM, '.localhost+4873', 'ajv-keywords', '1.5.0', NM, 'ajv-keywords')), 'root dependency resolution is present')
t.equal(deepRequireCwd(['using-ajv', 'ajv-keywords', 'ajv', './package.json']).version, '4.10.4')
await uninstall(['ajv-keywords'], opts)
t.ok(await exists(path.join(NM, '.localhost+4873', 'ajv-keywords', '1.5.0', 'ajv@4.10.4', NM, 'ajv')), 'peer dependency link is not removed')
t.notOk(await exists(path.join(NM, '.localhost+4873', 'ajv-keywords', '1.5.0', NM, 'ajv-keywords')), 'root dependency resolution is removed')
})
test('store status returns empty array when store was not modified', async (t: tape.Test) => {
const project = prepare(t)
const opts = await testDefaults()
await installPkgs(['is-positive@3.1.0'], opts)
const mutatedPkgs = await storeStatus(opts)
t.equal(mutatedPkgs && mutatedPkgs.length, 0, 'no packages were modified')
})
test['skip']('installing from shrinkwrap when using npm enterprise', async (t: tape.Test) => {
const project = prepare(t)
const opts = await testDefaults({registry: 'https://npm-registry.compass.com/'})
await installPkgs(['is-positive@3.1.0'], opts)
const shr = await project.loadShrinkwrap()
t.deepEqual(shr, {
dependencies: {
'is-positive': '3.1.0',
},
packages: {
'/is-positive/3.1.0': {
dev: false,
engines: {
node: '>=0.10.0',
},
resolution: {
integrity: 'sha1-hX21hKG6XRyymAUn/DtsQ103sP0=',
tarball: '/i/is-positive/_attachments/is-positive-3.1.0.tgz',