diff options
author | Luke Karrys <luke@lukekarrys.com> | 2022-04-08 18:24:56 +0300 |
---|---|---|
committer | Nathan Fritz <fritzy@github.com> | 2022-04-14 00:20:48 +0300 |
commit | 672fce84b25ecbe58d311acfae6c43e5ca2d778d (patch) | |
tree | 39e8ac90263f4386284e8d93ef2bbe7f30a9f32a | |
parent | 3f7fe17d1ea743b3ce1f27b9156e9fa0e358a7df (diff) |
chore: refactor smoke-tests
-rw-r--r-- | .eslintrc.local.json | 1 | ||||
-rw-r--r-- | node_modules/.gitignore | 1 | ||||
-rw-r--r-- | package-lock.json | 45 | ||||
-rw-r--r-- | package.json | 4 | ||||
-rwxr-xr-x | scripts/resetdeps.sh | 1 | ||||
-rw-r--r-- | smoke-tests/.eslintrc.js | 15 | ||||
-rw-r--r-- | smoke-tests/.gitignore | 21 | ||||
-rw-r--r-- | smoke-tests/package.json | 49 | ||||
-rw-r--r-- | smoke-tests/server.js | 282 | ||||
-rw-r--r-- | smoke-tests/tap-snapshots/test/index.js.test.cjs (renamed from tap-snapshots/smoke-tests/index.js.test.cjs) | 70 | ||||
-rw-r--r-- | smoke-tests/test/fixtures/abbrev.json (renamed from smoke-tests/content/abbrev.json) | 0 | ||||
-rw-r--r-- | smoke-tests/test/fixtures/abbrev.min.json (renamed from smoke-tests/content/abbrev.min.json) | 0 | ||||
-rw-r--r-- | smoke-tests/test/fixtures/abbrev/-/abbrev-1.0.4.tgz (renamed from smoke-tests/content/abbrev/-/abbrev-1.0.4.tgz) | bin | 2295 -> 2295 bytes | |||
-rw-r--r-- | smoke-tests/test/fixtures/abbrev/-/abbrev-1.1.1.tgz (renamed from smoke-tests/content/abbrev/-/abbrev-1.1.1.tgz) | bin | 2301 -> 2301 bytes | |||
-rw-r--r-- | smoke-tests/test/fixtures/promise-all-reject-late.json (renamed from smoke-tests/content/promise-all-reject-late.json) | 0 | ||||
-rw-r--r-- | smoke-tests/test/fixtures/promise-all-reject-late.min.json (renamed from smoke-tests/content/promise-all-reject-late.min.json) | 0 | ||||
-rw-r--r-- | smoke-tests/test/fixtures/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz (renamed from smoke-tests/content/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz) | bin | 30838 -> 30838 bytes | |||
-rw-r--r-- | smoke-tests/test/fixtures/server.js | 49 | ||||
-rw-r--r-- | smoke-tests/test/index.js (renamed from smoke-tests/index.js) | 249 |
19 files changed, 344 insertions, 443 deletions
diff --git a/.eslintrc.local.json b/.eslintrc.local.json index 16c85e07d..beb4581f4 100644 --- a/.eslintrc.local.json +++ b/.eslintrc.local.json @@ -10,7 +10,6 @@ "overrides": [{ "files": [ "scripts/**", - "smoke-tests/**", "bin/**", "test/**" ], diff --git a/node_modules/.gitignore b/node_modules/.gitignore index 508199997..9b34c0807 100644 --- a/node_modules/.gitignore +++ b/node_modules/.gitignore @@ -351,6 +351,7 @@ readme* /side-channel /simple-concat /simple-get +/smoke-tests /source-map /source-map-support /space-separated-tokens diff --git a/package-lock.json b/package-lock.json index 9222c5f4e..43cb34cce 100644 --- a/package-lock.json +++ b/package-lock.json @@ -84,6 +84,7 @@ "license": "Artistic-2.0", "workspaces": [ "docs", + "smoke-tests", "workspaces/*" ], "dependencies": { @@ -5795,7 +5796,8 @@ }, "node_modules/promise-all-reject-late": { "version": "1.0.1", - "license": "ISC", + "resolved": "https://registry.npmjs.org/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz", + "integrity": "sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw==", "funding": { "url": "https://github.com/sponsors/isaacs" } @@ -6282,8 +6284,9 @@ }, "node_modules/rimraf": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "inBundle": true, - "license": "ISC", "dependencies": { "glob": "^7.1.3" }, @@ -6447,6 +6450,10 @@ "npm": ">= 3.0.0" } }, + "node_modules/smoke-tests": { + "resolved": "smoke-tests", + "link": true + }, "node_modules/socks": { "version": "2.6.2", "inBundle": true, @@ -9737,6 +9744,22 @@ "url": "https://github.com/sponsors/wooorm" } }, + "smoke-tests": { + "version": "1.0.0", + "license": "ISC", + "devDependencies": { + "@npmcli/eslint-config": "^3.0.1", + "@npmcli/promise-spawn": "^3.0.0", + "@npmcli/template-oss": "3.3.2", + "minify-registry-metadata": "^2.2.0", + "rimraf": "^3.0.2", + "tap": "^16.0.1", + "which": "^2.0.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, "workspaces/arborist": { "name": "@npmcli/arborist", "version": "5.0.5", @@ -13792,7 +13815,9 @@ } }, "promise-all-reject-late": { - "version": "1.0.1" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz", + "integrity": "sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw==" }, "promise-call-limit": { "version": "1.0.1" @@ -14117,6 +14142,8 @@ }, "rimraf": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "requires": { "glob": "^7.1.3" } @@ -14192,6 +14219,18 @@ "smart-buffer": { "version": "4.2.0" }, + "smoke-tests": { + "version": "file:smoke-tests", + "requires": { + "@npmcli/eslint-config": "^3.0.1", + "@npmcli/promise-spawn": "^3.0.0", + "@npmcli/template-oss": "3.3.2", + "minify-registry-metadata": "^2.2.0", + "rimraf": "^3.0.2", + "tap": "^16.0.1", + "which": "^2.0.2" + } + }, "socks": { "version": "2.6.2", "requires": { diff --git a/package.json b/package.json index 277320d11..3989e8e72 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "description": "a package manager for JavaScript", "workspaces": [ "docs", + "smoke-tests", "workspaces/*" ], "files": [ @@ -225,8 +226,7 @@ "lintfix": "npm run lint -- --fix", "lint-all": "npm run lint --if-present --workspaces --include-workspace-root", "prelint": "rimraf test/npm_cache*", - "resetdeps": "bash scripts/resetdeps.sh", - "smoke-tests": "tap smoke-tests/index.js --no-coverage" + "resetdeps": "bash scripts/resetdeps.sh" }, "tap": { "test-env": [ diff --git a/scripts/resetdeps.sh b/scripts/resetdeps.sh index a8527f859..2362c2092 100755 --- a/scripts/resetdeps.sh +++ b/scripts/resetdeps.sh @@ -3,6 +3,7 @@ set -e set -x rm -rf node_modules rm -rf docs/node_modules +rm -rf smoke-tests/node_modules rm -rf "workspaces/*/node_modules" git checkout node_modules node . i --ignore-scripts --no-audit --no-fund diff --git a/smoke-tests/.eslintrc.js b/smoke-tests/.eslintrc.js new file mode 100644 index 000000000..0e8ad0071 --- /dev/null +++ b/smoke-tests/.eslintrc.js @@ -0,0 +1,15 @@ +/* This file is automatically added by @npmcli/template-oss. Do not edit. */ + +const { readdirSync: readdir } = require('fs') + +const localConfigs = readdir(__dirname) + .filter((file) => file.startsWith('.eslintrc.local.')) + .map((file) => `./${file}`) + +module.exports = { + root: true, + extends: [ + '@npmcli', + ...localConfigs, + ], +} diff --git a/smoke-tests/.gitignore b/smoke-tests/.gitignore new file mode 100644 index 000000000..617e50ca0 --- /dev/null +++ b/smoke-tests/.gitignore @@ -0,0 +1,21 @@ +# This file is automatically added by @npmcli/template-oss. Do not edit. + +# ignore everything in the root +/* + +# keep these +!/.eslintrc.local.* +!**/.gitignore +!/docs/ +!/tap-snapshots/ +!/test/ +!/map.js +!/scripts/ +!/README* +!/LICENSE* +!/CHANGELOG* +!/.eslintrc.js +!/.gitignore +!/bin/ +!/lib/ +!/package.json diff --git a/smoke-tests/package.json b/smoke-tests/package.json new file mode 100644 index 000000000..f8d1ffd0b --- /dev/null +++ b/smoke-tests/package.json @@ -0,0 +1,49 @@ +{ + "name": "smoke-tests", + "description": "The npm cli smoke tests", + "version": "1.0.0", + "private": true, + "scripts": { + "lint": "eslint \"**/*.js\"", + "postlint": "template-oss-check", + "template-oss-apply": "template-oss-apply --force", + "lintfix": "npm run lint -- --fix", + "preversion": "npm test", + "postversion": "git push origin --follow-tags", + "snap": "tap", + "test": "tap", + "posttest": "npm run lint" + }, + "repository": { + "type": "git", + "url": "https://github.com/npm/cli.git", + "directory": "smoke-tests" + }, + "devDependencies": { + "@npmcli/eslint-config": "^3.0.1", + "@npmcli/promise-spawn": "^3.0.0", + "@npmcli/template-oss": "3.3.2", + "minify-registry-metadata": "^2.2.0", + "rimraf": "^3.0.2", + "tap": "^16.0.1", + "which": "^2.0.2" + }, + "author": "GitHub Inc.", + "license": "ISC", + "templateOSS": { + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "3.3.2", + "workspaceRepo": false + }, + "tap": { + "no-coverage": true, + "files": "test/index.js" + }, + "files": [ + "bin/", + "lib/" + ], + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } +} diff --git a/smoke-tests/server.js b/smoke-tests/server.js deleted file mode 100644 index 31ffebb2a..000000000 --- a/smoke-tests/server.js +++ /dev/null @@ -1,282 +0,0 @@ -/* istanbul ignore file */ -const { join, dirname, basename } = require('path') -const { existsSync, readFileSync, writeFileSync } = require('fs') -const PORT = 12345 + (+process.env.TAP_CHILD_ID || 0) -const http = require('http') -const https = require('https') - -const mkdirp = require('mkdirp') -const doProxy = process.env.ARBORIST_TEST_PROXY -const missing = /\/@isaacs(\/|%2[fF])(this-does-not-exist-at-all|testing-missing-tgz\/-\/)/ -const corgiDoc = 'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*' -const { gzipSync, unzipSync } = require('zlib') - -let advisoryBulkResponse = null -let failAdvisoryBulk = false -let auditResponse = null -let failAudit = false -const startServer = () => new Promise((res, rej) => { - const server = exports.server = http.createServer((req, res) => { - res.setHeader('connection', 'close') - - if (req.url === '/-/npm/v1/security/advisories/bulk') { - const body = [] - req.on('data', c => body.push(c)) - req.on('end', () => { - res.setHeader('connection', 'close') - if (failAdvisoryBulk) { - res.statusCode = 503 - return res.end('no advisory bulk for you') - } - if (!advisoryBulkResponse) { - if (auditResponse && !failAudit) { - // simulate what the registry does when quick audits are allowed, - // but advisory bulk requests are not - res.statusCode = 405 - return res.end(JSON.stringify({ - code: 'MethodNotAllowedError', - message: 'POST is not allowed', - })) - } else { - res.statusCode = 404 - return res.end('not found') - } - } - if (doProxy && !existsSync(advisoryBulkResponse)) { - // hit the main registry, then fall back to staging for now - // XXX: remove this when bulk advisory endpoint pushed to production! - const opts = { - host: 'registry.npmjs.org', - method: req.method, - path: req.url, - headers: { - ...req.headers, - accept: '*', - host: 'registry.npmjs.org', - connection: 'close', - 'if-none-match': '', - }, - } - const handleUpstream = upstream => { - res.statusCode = upstream.statusCode - if (upstream.statusCode >= 300 || upstream.statusCode < 200) { - console.error('UPSTREAM ERROR', upstream.statusCode) - return upstream.pipe(res) - } - res.setHeader('content-encoding', upstream.headers['content-encoding']) - const file = advisoryBulkResponse - console.error('PROXY', `${req.url} -> ${file} ${upstream.statusCode}`) - mkdirp.sync(dirname(file)) - const data = [] - upstream.on('end', () => { - const out = Buffer.concat(data) - const obj = JSON.parse(unzipSync(out).toString()) - writeFileSync(file, JSON.stringify(obj, 0, 2) + '\n') - res.end(out) - }) - upstream.on('data', c => data.push(c)) - } - return https.request(opts).on('response', upstream => { - if (upstream.statusCode !== 200) { - console.error('ATTEMPTING TO PROXY FROM STAGING') - console.error('NOTE: THIS WILL FAIL WHEN NOT ON VPN!') - opts.host = 'security-microservice-3-west.npm.red' - opts.headers.host = opts.host - opts.path = '/v1/advisories/bulk' - https.request(opts) - .on('response', upstream => handleUpstream(upstream)) - .end(Buffer.concat(body)) - } else { - handleUpstream(upstream) - } - }).end(Buffer.concat(body)) - } else { - res.setHeader('content-encoding', 'gzip') - res.end(gzipSync(readFileSync(advisoryBulkResponse))) - } - }) - return - } else if (req.url === '/-/npm/v1/security/audits/quick') { - const body = [] - req.on('data', c => body.push(c)) - req.on('end', () => { - res.setHeader('connection', 'close') - if (failAudit) { - res.statusCode = 503 - return res.end('no audit for you') - } - if (!auditResponse) { - res.statusCode = 404 - return res.end('not found') - } - if (doProxy && !existsSync(auditResponse)) { - return https.request({ - host: 'registry.npmjs.org', - method: req.method, - path: req.url, - headers: { - ...req.headers, - accept: '*', - host: 'registry.npmjs.org', - connection: 'close', - 'if-none-match': '', - }, - }).on('response', upstream => { - res.statusCode = upstream.statusCode - if (upstream.statusCode >= 300 || upstream.statusCode < 200) { - console.error('UPSTREAM ERROR', upstream.statusCode) - // don't save if it's not a valid response - return upstream.pipe(res) - } - res.setHeader('content-encoding', upstream.headers['content-encoding']) - const file = auditResponse - console.error('PROXY', `${req.url} -> ${file} ${upstream.statusCode}`) - mkdirp.sync(dirname(file)) - const data = [] - upstream.on('end', () => { - const out = Buffer.concat(data) - // make it a bit prettier to read later - const obj = JSON.parse(unzipSync(out).toString()) - writeFileSync(file, JSON.stringify(obj, 0, 2) + '\n') - res.end(out) - }) - upstream.on('data', c => data.push(c)) - }).end(Buffer.concat(body)) - } else { - res.setHeader('content-encoding', 'gzip') - res.end(gzipSync(readFileSync(auditResponse))) - } - }) - return - } - - const f = join(__dirname, 'content', join('/', req.url.replace(/@/, '').replace(/%2f/i, '/'))) - // a magic package that causes us to return an error that will be logged - if (basename(f) === 'fail_reflect_user_agent') { - res.setHeader('npm-notice', req.headers['user-agent']) - res.writeHead(404) - return res.end() - } - const isCorgi = req.headers.accept.includes('application/vnd.npm.install-v1+json') - const file = f + ( - isCorgi && existsSync(`${f}.min.json`) ? '.min.json' - : existsSync(`${f}.json`) ? '.json' - : existsSync(`${f}/index.json`) ? 'index.json' - : '' - ) - - try { - const body = readFileSync(file) - res.setHeader('content-length', body.length) - res.setHeader('content-type', /\.min\.json$/.test(file) ? corgiDoc - : /\.json$/.test(file) ? 'application/json' - : 'application/octet-stream') - res.end(body) - } catch (er) { - // testing things going missing from the registry somehow - if (missing.test(req.url)) { - res.statusCode = 404 - res.end('{"error": "not found"}') - return - } - - if (doProxy) { - return https.get({ - host: 'registry.npmjs.org', - path: req.url, - headers: { - ...req.headers, - accept: '*', - 'accept-encoding': 'identity', - host: 'registry.npmjs.org', - connection: 'close', - 'if-none-match': '', - }, - }).on('response', upstream => { - const errorStatus = - upstream.statusCode >= 300 || upstream.statusCode < 200 - - if (errorStatus) { - console.error('UPSTREAM ERROR', upstream.statusCode) - } - - const ct = upstream.headers['content-type'] - const isJson = ct.includes('application/json') - const file = isJson ? f + '.json' : f - console.error('PROXY', `${req.url} -> ${file} ${ct}`) - mkdirp.sync(dirname(file)) - const data = [] - res.statusCode = upstream.statusCode - res.setHeader('content-type', ct) - upstream.on('end', () => { - console.error('ENDING', req.url) - const out = Buffer.concat(data) - if (!errorStatus) { - if (isJson) { - const obj = JSON.parse(out.toString()) - writeFileSync(file, JSON.stringify(obj, 0, 2) + '\n') - const mrm = require('minify-registry-metadata') - const minFile = file.replace(/\.json$/, '.min.json') - writeFileSync(minFile, JSON.stringify(mrm(obj), 0, 2) + '\n') - console.error('WROTE JSONS', [file, minFile]) - } else { - writeFileSync(file, out) - } - } - res.end(out) - }) - upstream.on('data', c => data.push(c)) - }).end() - } - - res.statusCode = er.code === 'ENOENT' ? 404 : 500 - if (res.method === 'GET') { - console.error(er) - } - res.setHeader('content-type', 'text/plain') - res.end(er.stack) - } - }) - server.listen(PORT, res) -}) - -exports.auditResponse = value => { - if (auditResponse && auditResponse !== value) { - throw new Error('setting audit response, but already set\n' + - '(did you forget to call the returned function on teardown?)') - } - auditResponse = value - return () => auditResponse = null -} -exports.failAudit = () => { - failAudit = true - return () => failAudit = false -} - -exports.advisoryBulkResponse = value => { - if (advisoryBulkResponse && advisoryBulkResponse !== value) { - throw new Error('setting advisory bulk response, but already set\n' + - '(did you forget to call the returned function on teardown?)') - } - advisoryBulkResponse = value - return () => advisoryBulkResponse = null -} -exports.failAdvisoryBulk = () => { - failAdvisoryBulk = true - return () => failAdvisoryBulk = false -} - -exports.registry = `http://localhost:${PORT}/` - -exports.start = startServer -exports.stop = () => exports.server.close() - -if (require.main === module) { - startServer().then(() => { - console.log(`Mock registry live at: - ${exports.registry} -Press ^D to close gracefully.`) - }) - process.openStdin() - process.stdin.on('end', () => exports.stop()) -} diff --git a/tap-snapshots/smoke-tests/index.js.test.cjs b/smoke-tests/tap-snapshots/test/index.js.test.cjs index 5fa3977a8..486849d6c 100644 --- a/tap-snapshots/smoke-tests/index.js.test.cjs +++ b/smoke-tests/tap-snapshots/test/index.js.test.cjs @@ -5,7 +5,7 @@ * Make sure to inspect the output below. Do not ignore changes! */ 'use strict' -exports[`smoke-tests/index.js TAP npm (no args) > should have expected no args output 1`] = ` +exports[`test/index.js TAP npm (no args) > should have expected no args output 1`] = ` npm <command> Usage: @@ -32,7 +32,7 @@ All commands: uninstall, unpublish, unstar, update, version, view, whoami Specify configs in the ini-formatted file: - {CWD}/smoke-tests/tap-testdir-index/.npmrc + {CWD}/smoke-tests/test/tap-testdir-index/.npmrc or on the command line via: npm <command> --key=value More configuration info: npm help config @@ -42,7 +42,7 @@ npm {CWD} ` -exports[`smoke-tests/index.js TAP npm ci > should throw mismatch deps in lock file error 1`] = ` +exports[`test/index.js TAP npm ci > should throw mismatch deps in lock file error 1`] = ` npm ERR! \`npm ci\` can only install packages when your package.json and package-lock.json or npm-shrinkwrap.json are in sync. Please update your lock file with \`npm install\` before continuing. npm ERR! npm ERR! Invalid: lock file's abbrev@1.0.4 does not satisfy abbrev@1.1.1 @@ -53,7 +53,7 @@ npm ERR! A complete log of this run can be found in: ` -exports[`smoke-tests/index.js TAP npm diff > should have expected diff output 1`] = ` +exports[`test/index.js TAP npm diff > should have expected diff output 1`] = ` diff --git a/package.json b/package.json index v1.0.4..v1.1.1 100644 --- a/package.json @@ -308,14 +308,14 @@ index v1.0.4..v1.1.1 ` -exports[`smoke-tests/index.js TAP npm explain > should have expected explain output 1`] = ` +exports[`test/index.js TAP npm explain > should have expected explain output 1`] = ` abbrev@1.0.4 node_modules/abbrev abbrev@"^1.0.4" from the root project ` -exports[`smoke-tests/index.js TAP npm fund > should have expected fund output 1`] = ` +exports[`test/index.js TAP npm fund > should have expected fund output 1`] = ` project@1.0.0 \`-- https://github.com/sponsors/isaacs \`-- promise-all-reject-late@1.0.1 @@ -323,8 +323,8 @@ project@1.0.0 ` -exports[`smoke-tests/index.js TAP npm init > should have successful npm init result 1`] = ` -Wrote to {CWD}/smoke-tests/tap-testdir-index/project/package.json: +exports[`test/index.js TAP npm init > should have successful npm init result 1`] = ` +Wrote to {CWD}/smoke-tests/test/tap-testdir-index/project/package.json: { "name": "project", @@ -343,7 +343,7 @@ Wrote to {CWD}/smoke-tests/tap-testdir-index/project/package.json: ` -exports[`smoke-tests/index.js TAP npm install dev dep > should have expected dev dep added lockfile result 1`] = ` +exports[`test/index.js TAP npm install dev dep > should have expected dev dep added lockfile result 1`] = ` { "name": "project", "version": "1.0.0", @@ -393,7 +393,7 @@ exports[`smoke-tests/index.js TAP npm install dev dep > should have expected dev ` -exports[`smoke-tests/index.js TAP npm install dev dep > should have expected dev dep added package.json result 1`] = ` +exports[`test/index.js TAP npm install dev dep > should have expected dev dep added package.json result 1`] = ` { "name": "project", "version": "1.0.0", @@ -415,7 +415,7 @@ exports[`smoke-tests/index.js TAP npm install dev dep > should have expected dev ` -exports[`smoke-tests/index.js TAP npm install dev dep > should have expected dev dep added reify output 1`] = ` +exports[`test/index.js TAP npm install dev dep > should have expected dev dep added reify output 1`] = ` added 1 package @@ -424,13 +424,13 @@ added 1 package ` -exports[`smoke-tests/index.js TAP npm install prodDep@version > should have expected install reify output 1`] = ` +exports[`test/index.js TAP npm install prodDep@version > should have expected install reify output 1`] = ` added 1 package ` -exports[`smoke-tests/index.js TAP npm install prodDep@version > should have expected lockfile result 1`] = ` +exports[`test/index.js TAP npm install prodDep@version > should have expected lockfile result 1`] = ` { "name": "project", "version": "1.0.0", @@ -462,7 +462,7 @@ exports[`smoke-tests/index.js TAP npm install prodDep@version > should have expe ` -exports[`smoke-tests/index.js TAP npm install prodDep@version > should have expected package.json result 1`] = ` +exports[`test/index.js TAP npm install prodDep@version > should have expected package.json result 1`] = ` { "name": "project", "version": "1.0.0", @@ -481,21 +481,21 @@ exports[`smoke-tests/index.js TAP npm install prodDep@version > should have expe ` -exports[`smoke-tests/index.js TAP npm ls > should have expected ls output 1`] = ` -project@1.0.0 {CWD}/smoke-tests/tap-testdir-index/project +exports[`test/index.js TAP npm ls > should have expected ls output 1`] = ` +project@1.0.0 {CWD}/smoke-tests/test/tap-testdir-index/project +-- abbrev@1.0.4 \`-- promise-all-reject-late@1.0.1 ` -exports[`smoke-tests/index.js TAP npm outdated > should have expected outdated output 1`] = ` +exports[`test/index.js TAP npm outdated > should have expected outdated output 1`] = ` Package Current Wanted Latest Location Depended by abbrev 1.0.4 1.1.1 1.1.1 node_modules/abbrev project ` -exports[`smoke-tests/index.js TAP npm pkg > should have expected npm pkg delete modified package.json result 1`] = ` +exports[`test/index.js TAP npm pkg > should have expected npm pkg delete modified package.json result 1`] = ` { "name": "project", "version": "1.0.0", @@ -515,7 +515,7 @@ exports[`smoke-tests/index.js TAP npm pkg > should have expected npm pkg delete ` -exports[`smoke-tests/index.js TAP npm pkg > should have expected npm pkg set modified package.json result 1`] = ` +exports[`test/index.js TAP npm pkg > should have expected npm pkg set modified package.json result 1`] = ` { "name": "project", "version": "1.0.0", @@ -540,20 +540,20 @@ exports[`smoke-tests/index.js TAP npm pkg > should have expected npm pkg set mod ` -exports[`smoke-tests/index.js TAP npm pkg > should have expected pkg delete output 1`] = ` +exports[`test/index.js TAP npm pkg > should have expected pkg delete output 1`] = ` ` -exports[`smoke-tests/index.js TAP npm pkg > should have expected pkg get output 1`] = ` +exports[`test/index.js TAP npm pkg > should have expected pkg get output 1`] = ` "ISC" ` -exports[`smoke-tests/index.js TAP npm pkg > should have expected pkg set output 1`] = ` +exports[`test/index.js TAP npm pkg > should have expected pkg set output 1`] = ` ` -exports[`smoke-tests/index.js TAP npm pkg > should print package.json contents 1`] = ` +exports[`test/index.js TAP npm pkg > should print package.json contents 1`] = ` { "name": "project", "version": "1.0.0", @@ -578,12 +578,12 @@ exports[`smoke-tests/index.js TAP npm pkg > should print package.json contents 1 ` -exports[`smoke-tests/index.js TAP npm prefix > should have expected prefix output 1`] = ` -{CWD}/smoke-tests/tap-testdir-index/project +exports[`test/index.js TAP npm prefix > should have expected prefix output 1`] = ` +{CWD}/smoke-tests/test/tap-testdir-index/project ` -exports[`smoke-tests/index.js TAP npm run-script > should have expected run-script output 1`] = ` +exports[`test/index.js TAP npm run-script > should have expected run-script output 1`] = ` > project@1.0.0 hello > echo Hello @@ -592,7 +592,7 @@ Hello ` -exports[`smoke-tests/index.js TAP npm set-script > should have expected script added package.json result 1`] = ` +exports[`test/index.js TAP npm set-script > should have expected script added package.json result 1`] = ` { "name": "project", "version": "1.0.0", @@ -615,11 +615,11 @@ exports[`smoke-tests/index.js TAP npm set-script > should have expected script a ` -exports[`smoke-tests/index.js TAP npm set-script > should have expected set-script output 1`] = ` +exports[`test/index.js TAP npm set-script > should have expected set-script output 1`] = ` ` -exports[`smoke-tests/index.js TAP npm uninstall > should have expected uninstall lockfile result 1`] = ` +exports[`test/index.js TAP npm uninstall > should have expected uninstall lockfile result 1`] = ` { "name": "project", "version": "1.0.0", @@ -651,7 +651,7 @@ exports[`smoke-tests/index.js TAP npm uninstall > should have expected uninstall ` -exports[`smoke-tests/index.js TAP npm uninstall > should have expected uninstall package.json result 1`] = ` +exports[`test/index.js TAP npm uninstall > should have expected uninstall package.json result 1`] = ` { "name": "project", "version": "1.0.0", @@ -671,13 +671,13 @@ exports[`smoke-tests/index.js TAP npm uninstall > should have expected uninstall ` -exports[`smoke-tests/index.js TAP npm uninstall > should have expected uninstall reify output 1`] = ` +exports[`test/index.js TAP npm uninstall > should have expected uninstall reify output 1`] = ` removed 1 package ` -exports[`smoke-tests/index.js TAP npm update dep > should have expected update lockfile result 1`] = ` +exports[`test/index.js TAP npm update dep > should have expected update lockfile result 1`] = ` { "name": "project", "version": "1.0.0", @@ -727,7 +727,7 @@ exports[`smoke-tests/index.js TAP npm update dep > should have expected update l ` -exports[`smoke-tests/index.js TAP npm update dep > should have expected update package.json result 1`] = ` +exports[`test/index.js TAP npm update dep > should have expected update package.json result 1`] = ` { "name": "project", "version": "1.0.0", @@ -750,7 +750,7 @@ exports[`smoke-tests/index.js TAP npm update dep > should have expected update p ` -exports[`smoke-tests/index.js TAP npm update dep > should have expected update reify output 1`] = ` +exports[`test/index.js TAP npm update dep > should have expected update reify output 1`] = ` changed 1 package @@ -759,7 +759,7 @@ changed 1 package ` -exports[`smoke-tests/index.js TAP npm view > should have expected view output 1`] = ` +exports[`test/index.js TAP npm view > should have expected view output 1`] = ` [4m[1m[32mabbrev[39m@[32m1.0.4[39m[22m[24m | [32mMIT[39m | deps: [32mnone[39m | versions: [33m8[39m Like ruby's abbrev module, but in js diff --git a/smoke-tests/content/abbrev.json b/smoke-tests/test/fixtures/abbrev.json index ffcf5474a..ffcf5474a 100644 --- a/smoke-tests/content/abbrev.json +++ b/smoke-tests/test/fixtures/abbrev.json diff --git a/smoke-tests/content/abbrev.min.json b/smoke-tests/test/fixtures/abbrev.min.json index c03d91c9c..c03d91c9c 100644 --- a/smoke-tests/content/abbrev.min.json +++ b/smoke-tests/test/fixtures/abbrev.min.json diff --git a/smoke-tests/content/abbrev/-/abbrev-1.0.4.tgz b/smoke-tests/test/fixtures/abbrev/-/abbrev-1.0.4.tgz Binary files differindex dfd1b5591..dfd1b5591 100644 --- a/smoke-tests/content/abbrev/-/abbrev-1.0.4.tgz +++ b/smoke-tests/test/fixtures/abbrev/-/abbrev-1.0.4.tgz diff --git a/smoke-tests/content/abbrev/-/abbrev-1.1.1.tgz b/smoke-tests/test/fixtures/abbrev/-/abbrev-1.1.1.tgz Binary files differindex 4d9504504..4d9504504 100644 --- a/smoke-tests/content/abbrev/-/abbrev-1.1.1.tgz +++ b/smoke-tests/test/fixtures/abbrev/-/abbrev-1.1.1.tgz diff --git a/smoke-tests/content/promise-all-reject-late.json b/smoke-tests/test/fixtures/promise-all-reject-late.json index e243b92a3..e243b92a3 100644 --- a/smoke-tests/content/promise-all-reject-late.json +++ b/smoke-tests/test/fixtures/promise-all-reject-late.json diff --git a/smoke-tests/content/promise-all-reject-late.min.json b/smoke-tests/test/fixtures/promise-all-reject-late.min.json index 699be7aaf..699be7aaf 100644 --- a/smoke-tests/content/promise-all-reject-late.min.json +++ b/smoke-tests/test/fixtures/promise-all-reject-late.min.json diff --git a/smoke-tests/content/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz b/smoke-tests/test/fixtures/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz Binary files differindex 7da404423..7da404423 100644 --- a/smoke-tests/content/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz +++ b/smoke-tests/test/fixtures/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz diff --git a/smoke-tests/test/fixtures/server.js b/smoke-tests/test/fixtures/server.js new file mode 100644 index 000000000..b1056a221 --- /dev/null +++ b/smoke-tests/test/fixtures/server.js @@ -0,0 +1,49 @@ +const { join, basename } = require('path') +const { existsSync, readFileSync } = require('fs') +const http = require('http') +const PORT = 12345 + (+process.env.TAP_CHILD_ID || 0) + +let server = null +const corgiDoc = 'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*' + +const start = () => new Promise((resolve) => { + server = http.createServer((req, res) => { + res.setHeader('connection', 'close') + + const f = join(__dirname, join('/', req.url.replace(/@/, '').replace(/%2f/i, '/'))) + + // a magic package that causes us to return an error that will be logged + if (basename(f) === 'fail_reflect_user_agent') { + res.statusCode = 404 + res.setHeader('npm-notice', req.headers['user-agent']) + return res.end() + } + + const isCorgi = req.headers.accept.includes('application/vnd.npm.install-v1+json') + const file = f + ( + isCorgi && existsSync(`${f}.min.json`) ? '.min.json' + : existsSync(`${f}.json`) ? '.json' + : existsSync(`${f}/index.json`) ? 'index.json' + : '' + ) + + try { + const body = readFileSync(file) + res.setHeader('content-length', body.length) + res.setHeader('content-type', /\.min\.json$/.test(file) ? corgiDoc + : /\.json$/.test(file) ? 'application/json' + : 'application/octet-stream') + res.end(body) + } catch { + res.statusCode = 500 + res.setHeader('content-type', 'text/plain') + res.end('bad') + } + }).listen(PORT, resolve) +}) + +module.exports = { + start, + stop: () => server.close(), + registry: `http://localhost:${PORT}/`, +} diff --git a/smoke-tests/index.js b/smoke-tests/test/index.js index 464187da0..bbb833a57 100644 --- a/smoke-tests/index.js +++ b/smoke-tests/test/index.js @@ -1,21 +1,47 @@ -const fs = require('fs') -const { promisify } = require('util') -const execAsync = promisify(require('child_process').exec) -const { join, resolve } = require('path') +const { readFileSync, realpathSync, mkdirSync, existsSync, writeFileSync } = require('fs') +const spawn = require('@npmcli/promise-spawn') +const { join, resolve, sep } = require('path') const t = require('tap') -const rimraf = promisify(require('rimraf')) +const rimraf = require('rimraf') +const which = require('which').sync +const { start, stop, registry } = require('./fixtures/server.js') +const { SMOKE_PUBLISH_NPM, CI, PATH } = process.env +const log = CI ? console.error : () => {} + +const cwd = resolve(__dirname, '..', '..') +const npmCli = join('bin', 'npm-cli.js') +const execArgv = SMOKE_PUBLISH_NPM ? ['npm'] : [process.execPath, join(cwd, npmCli)] +const npmDir = SMOKE_PUBLISH_NPM ? realpathSync(which('npm')).replace(sep + npmCli, '') : cwd + +// setup server +t.before(start) +t.teardown(stop) +// update notifier should never be written +t.afterEach((t) => { + const updateExists = existsSync(join(cacheLocation, '_update-notifier-last-checked')) + t.equal(updateExists, false) +}) + +const readFile = filename => readFileSync(resolve(localPrefix, filename), 'utf-8') const normalizePath = path => path.replace(/[A-Z]:/, '').replace(/\\/g, '/') -const cwd = normalizePath(process.cwd()) + t.cleanSnapshot = s => s - .split(cwd) + // sometimes we print normalized paths in snapshots regardless of + // platform so replace those first + .split(normalizePath(npmDir)) + .join('{CWD}') + .split(normalizePath(cwd)) .join('{CWD}') .split(registry) .join('https://registry.npmjs.org/') .split(normalizePath(process.execPath)) .join('node') - .split(process.cwd()) + // then replace platform style paths + .split(npmDir) + .join('{CWD}') + .split(cwd) .join('{CWD}') .replace(/\\+/g, '/') .replace(/\r\n/g, '\n') @@ -23,11 +49,6 @@ t.cleanSnapshot = s => .replace(/^npm@.* /gm, 'npm ') .replace(/^.*debug-[0-9]+.log$/gm, '') -// setup server -const { start, stop, registry } = require('./server.js') -t.before(start) -t.teardown(stop) - // setup fixtures const path = t.testdir({ '.npmrc': '', @@ -37,30 +58,49 @@ const path = t.testdir({ }) const localPrefix = resolve(path, 'project') const userconfigLocation = resolve(path, '.npmrc') -const npmLocation = resolve(__dirname, '../bin/npm-cli.js') const cacheLocation = resolve(path, 'cache') const binLocation = resolve(path, 'bin') -const env = { - HOME: path, - PATH: `${process.env.PATH}:${binLocation}`, -} -const npmOpts = [ - `--registry=${registry}`, - `--cache="${cacheLocation}"`, - `--userconfig="${userconfigLocation}"`, - '--no-audit', - '--no-update-notifier', - '--loglevel=silly', -].join(' ') -const npmBin = `"${process.execPath}" "${npmLocation}" ${npmOpts}` -const exec = async cmd => { - const res = await execAsync(cmd, { cwd: localPrefix, env }) - if (res.stderr) { - console.error(res.stderr) + +const exec = async (...args) => { + const cmd = [] + const opts = [ + `--registry=${registry}`, + `--cache=${cacheLocation}`, + `--userconfig=${userconfigLocation}`, + '--no-audit', + '--no-update-notifier', + '--loglevel=silly', + ] + for (const arg of args) { + if (arg.startsWith('--')) { + opts.push(arg) + } else { + cmd.push(arg) + } + } + + // XXX: not sure why outdated fails with no-workspaces but works without it + if (!opts.includes('--workspaces') && cmd[0] !== 'outdated') { + // This is required so we dont detect any workspace roots above the testdir + opts.push('--no-workspaces') } - return String(res.stdout) + + const spawnArgs = [execArgv[0], [...execArgv.slice(1), ...cmd, ...opts]] + log([spawnArgs[0], ...spawnArgs[1]].join(' ')) + + const res = await spawn(...spawnArgs, { + cwd: localPrefix, + env: { + HOME: path, + PATH: `${PATH}:${binLocation}`, + }, + stdioString: true, + encoding: 'utf-8', + }) + + log(res.stderr) + return res.stdout } -const readFile = filename => String(fs.readFileSync(resolve(localPrefix, filename))) // this test must come first, its package.json will be destroyed and the one // created in the next test (npm init) will create a new one that must be @@ -71,35 +111,31 @@ t.test('npm install sends correct user-agent', async t => { name: 'smoke-test-workspaces', workspaces: ['packages/*'], }) - fs.writeFileSync(pkgPath, pkgContent, { encoding: 'utf8' }) + writeFileSync(pkgPath, pkgContent, { encoding: 'utf8' }) const wsRoot = join(localPrefix, 'packages') - fs.mkdirSync(wsRoot) + mkdirSync(wsRoot) const wsPath = join(wsRoot, 'foo') - fs.mkdirSync(wsPath) + mkdirSync(wsPath) const wsPkgPath = join(wsPath, 'package.json') const wsContent = JSON.stringify({ name: 'foo', }) - fs.writeFileSync(wsPkgPath, wsContent, { encoding: 'utf8' }) - t.teardown(async () => { - await rimraf(`${localPrefix}/*`) - }) + writeFileSync(wsPkgPath, wsContent, { encoding: 'utf8' }) + t.teardown(() => rimraf.sync(`${localPrefix}/*`)) - const cmd = `${npmBin} install fail_reflect_user_agent` await t.rejects( - exec(cmd), + exec('install', 'fail_reflect_user_agent'), { stderr: /workspaces\/false/, }, 'workspaces/false is present in output' ) - const wsCmd = `${npmBin} install fail_reflect_user_agent --workspaces` await t.rejects( - exec(wsCmd), + exec('install', 'fail_reflect_user_agent', '--workspaces'), { stderr: /workspaces\/true/, }, @@ -108,29 +144,34 @@ t.test('npm install sends correct user-agent', async t => { }) t.test('npm init', async t => { - const cmd = `${npmBin} init -y` - const cmdRes = await exec(cmd) + const cmdRes = await exec('init', '-y') t.matchSnapshot(cmdRes, 'should have successful npm init result') - const pkg = JSON.parse(fs.readFileSync(resolve(localPrefix, 'package.json'))) + const pkg = JSON.parse(readFileSync(resolve(localPrefix, 'package.json'))) t.equal(pkg.name, 'project', 'should have expected generated name') t.equal(pkg.version, '1.0.0', 'should have expected generated version') }) +t.test('npm --version', async t => { + const v = await exec('--version') + + if (SMOKE_PUBLISH_NPM) { + t.match(v.trim(), /-[0-9a-f]{40}\.\d$/, 'must have a git version') + } else { + t.skip('not checking version') + } +}) + t.test('npm (no args)', async t => { - const cmd = `"${process.execPath}" "${npmLocation}" --no-audit --no-update-notifier` - const cmdRes = await execAsync(cmd, { cwd: localPrefix, env }).catch(err => { - t.equal(err.code, 1, 'should exit with error code') - return err - }) + const err = await exec('--loglevel=notice').catch(e => e) - t.equal(cmdRes.stderr, '', 'should have no stderr output') - t.matchSnapshot(String(cmdRes.stdout), 'should have expected no args output') + t.equal(err.code, 1, 'should exit with error code') + t.equal(err.stderr, '', 'should have no stderr output') + t.matchSnapshot(err.stdout, 'should have expected no args output') }) t.test('npm install prodDep@version', async t => { - const cmd = `${npmBin} install abbrev@1.0.4` - const cmdRes = await exec(cmd) + const cmdRes = await exec('install', 'abbrev@1.0.4') t.matchSnapshot(cmdRes.replace(/in.*s/, ''), 'should have expected install reify output') t.matchSnapshot(readFile('package.json'), 'should have expected package.json result') @@ -138,8 +179,7 @@ t.test('npm install prodDep@version', async t => { }) t.test('npm install dev dep', async t => { - const cmd = `${npmBin} install -D promise-all-reject-late` - const cmdRes = await exec(cmd) + const cmdRes = await exec('install', 'promise-all-reject-late', '-D') t.matchSnapshot(cmdRes.replace(/in.*s/, ''), 'should have expected dev dep added reify output') t.matchSnapshot( @@ -153,47 +193,39 @@ t.test('npm install dev dep', async t => { }) t.test('npm ls', async t => { - const cmd = `${npmBin} ls` - const cmdRes = await exec(cmd) + const cmdRes = await exec('ls') t.matchSnapshot(cmdRes, 'should have expected ls output') }) t.test('npm fund', async t => { - const cmd = `${npmBin} fund` - const cmdRes = await exec(cmd) + const cmdRes = await exec('fund') t.matchSnapshot(cmdRes, 'should have expected fund output') }) t.test('npm explain', async t => { - const cmd = `${npmBin} explain abbrev` - const cmdRes = await exec(cmd) + const cmdRes = await exec('explain', 'abbrev') t.matchSnapshot(cmdRes, 'should have expected explain output') }) t.test('npm diff', async t => { - const cmd = `${npmBin} diff --diff=abbrev@1.0.4 --diff=abbrev@1.1.1` - const cmdRes = await exec(cmd) + const cmdRes = await exec('diff', '--diff=abbrev@1.0.4', '--diff=abbrev@1.1.1') t.matchSnapshot(cmdRes, 'should have expected diff output') }) t.test('npm outdated', async t => { - const cmd = `${npmBin} outdated` - const cmdRes = await exec(cmd).catch(err => { - t.equal(err.code, 1, 'should exit with error code') - return err - }) + const err = await exec('outdated').catch(e => e) - t.not(cmdRes.stderr, '', 'should have stderr output') - t.matchSnapshot(String(cmdRes.stdout), 'should have expected outdated output') + t.equal(err.code, 1, 'should exit with error code') + t.not(err.stderr, '', 'should have stderr output') + t.matchSnapshot(err.stdout, 'should have expected outdated output') }) t.test('npm set-script', async t => { - const cmd = `${npmBin} set-script "hello" "echo Hello"` - const cmdRes = await exec(cmd) + const cmdRes = await exec('set-script', 'hello', 'echo Hello') t.matchSnapshot(cmdRes, 'should have expected set-script output') t.matchSnapshot( @@ -203,29 +235,25 @@ t.test('npm set-script', async t => { }) t.test('npm run-script', async t => { - const cmd = `${npmBin} run hello` - const cmdRes = await exec(cmd) + const cmdRes = await exec('run', 'hello') t.matchSnapshot(cmdRes, 'should have expected run-script output') }) t.test('npm prefix', async t => { - const cmd = `${npmBin} prefix` - const cmdRes = await exec(cmd) + const cmdRes = await exec('prefix') t.matchSnapshot(cmdRes, 'should have expected prefix output') }) t.test('npm view', async t => { - const cmd = `${npmBin} view abbrev@1.0.4` - const cmdRes = await exec(cmd) + const cmdRes = await exec('view', 'abbrev@1.0.4') t.matchSnapshot(cmdRes, 'should have expected view output') }) t.test('npm update dep', async t => { - const cmd = `${npmBin} update abbrev` - const cmdRes = await exec(cmd) + const cmdRes = await exec('update', 'abbrev') t.matchSnapshot(cmdRes.replace(/in.*s/, ''), 'should have expected update reify output') t.matchSnapshot(readFile('package.json'), 'should have expected update package.json result') @@ -233,8 +261,7 @@ t.test('npm update dep', async t => { }) t.test('npm uninstall', async t => { - const cmd = `${npmBin} uninstall promise-all-reject-late` - const cmdRes = await exec(cmd) + const cmdRes = await exec('uninstall', 'promise-all-reject-late') t.matchSnapshot(cmdRes.replace(/in.*s/, ''), 'should have expected uninstall reify output') t.matchSnapshot(readFile('package.json'), 'should have expected uninstall package.json result') @@ -242,12 +269,10 @@ t.test('npm uninstall', async t => { }) t.test('npm pkg', async t => { - let cmd = `${npmBin} pkg get license` - let cmdRes = await exec(cmd) + let cmdRes = await exec('pkg', 'get', 'license') t.matchSnapshot(cmdRes.replace(/in.*s/, ''), 'should have expected pkg get output') - cmd = `${npmBin} pkg set tap[test-env][0]=LC_ALL=sk` - cmdRes = await exec(cmd) + cmdRes = await exec('pkg', 'set', 'tap[test-env][0]=LC_ALL=sk') t.matchSnapshot(cmdRes.replace(/in.*s/, ''), 'should have expected pkg set output') t.matchSnapshot( @@ -255,12 +280,10 @@ t.test('npm pkg', async t => { 'should have expected npm pkg set modified package.json result' ) - cmd = `${npmBin} pkg get` - cmdRes = await exec(cmd) + cmdRes = await exec('pkg', 'get') t.matchSnapshot(cmdRes.replace(/in.*s/, ''), 'should print package.json contents') - cmd = `${npmBin} pkg delete tap` - cmdRes = await exec(cmd) + cmdRes = await exec('pkg', 'delete', 'tap') t.matchSnapshot(cmdRes.replace(/in.*s/, ''), 'should have expected pkg delete output') t.matchSnapshot( @@ -271,12 +294,11 @@ t.test('npm pkg', async t => { t.test('npm update --no-save --no-package-lock', async t => { // setup, manually reset dep value - await exec(`${npmBin} pkg set "dependencies.abbrev==1.0.4"`) - await exec(`${npmBin} install`) - await exec(`${npmBin} pkg set "dependencies.abbrev=^1.0.4"`) + await exec('pkg', 'set', 'dependencies.abbrev==1.0.4') + await exec(`install`) + await exec('pkg', 'set', 'dependencies.abbrev=^1.0.4') - const cmd = `${npmBin} update --no-save --no-package-lock` - await exec(cmd) + await exec('update', '--no-save', '--no-package-lock') t.equal( JSON.parse(readFile('package.json')).dependencies.abbrev, @@ -291,8 +313,7 @@ t.test('npm update --no-save --no-package-lock', async t => { }) t.test('npm update --no-save', async t => { - const cmd = `${npmBin} update --no-save` - await exec(cmd) + await exec('update', '--no-save') t.equal( JSON.parse(readFile('package.json')).dependencies.abbrev, @@ -307,8 +328,7 @@ t.test('npm update --no-save', async t => { }) t.test('npm update --save', async t => { - const cmd = `${npmBin} update --save` - await exec(cmd) + await exec('update', '--save') t.equal( JSON.parse(readFile('package.json')).dependencies.abbrev, @@ -323,8 +343,8 @@ t.test('npm update --save', async t => { }) t.test('npm ci', async t => { - await exec(`${npmBin} uninstall abbrev`) - await exec(`${npmBin} install abbrev@1.0.4 --save-exact`) + await exec('uninstall', 'abbrev') + await exec('install', 'abbrev@1.0.4', '--save-exact') t.equal( JSON.parse(readFile('package-lock.json')).packages['node_modules/abbrev'].version, @@ -332,20 +352,9 @@ t.test('npm ci', async t => { 'should have stored exact installed version' ) - await exec(`${npmBin} pkg set "dependencies.abbrev=^1.1.1"`) - - try { - const npmOpts = [ - `--registry=${registry}`, - `--cache="${cacheLocation}"`, - `--userconfig="${userconfigLocation}"`, - '--no-audit', - '--no-update-notifier', - '--loglevel=error', - ].join(' ') - const npmBin = `"${process.execPath}" "${npmLocation}" ${npmOpts}` - await exec(`${npmBin} ci`) - } catch (err) { - t.matchSnapshot(err.stderr, 'should throw mismatch deps in lock file error') - } + await exec('pkg', 'set', 'dependencies.abbrev=^1.1.1') + + const err = await exec('ci', '--loglevel=error').catch(e => e) + t.equal(err.code, 1) + t.matchSnapshot(err.stderr, 'should throw mismatch deps in lock file error') }) |