diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 851b3fdcb9fe..14f362b45e30 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,6 +37,48 @@ jobs: - name: Run linting run: node . run licenses + smoke-tests: + strategy: + fail-fast: false + matrix: + node-version: [10.x, 12.x, 14.x] + platform: + - os: ubuntu-latest + shell: bash + - os: macos-latest + shell: bash + - os: windows-latest + shell: bash + - os: windows-latest + shell: powershell + + runs-on: ${{ matrix.platform.os }} + defaults: + run: + shell: ${{ matrix.platform.shell }} + + steps: + # Checkout the npm/cli repo + - uses: actions/checkout@v2 + + # Installs the specific version of Node.js + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + + # Run the installer script + - name: Install dependencies + run: | + node . install --ignore-scripts --no-audit + node . rebuild + + # Run the smoke tests + - name: Run Smoke tests + run: node . run --ignore-scripts smoke-tests -- --no-check-coverage -t600 -Rbase -c + env: + DEPLOY_VERSION: testing + build: strategy: fail-fast: false diff --git a/.npmignore b/.npmignore index 409905efd277..9d02b99f91b3 100644 --- a/.npmignore +++ b/.npmignore @@ -39,3 +39,7 @@ docs/template.html Session.vim .nyc_output /.editorconfig + +# don't ship smoke tests +smoke-tests/ +tap-snapshots/smoke-tests-index.js-TAP.test.js diff --git a/Makefile b/Makefile index 656f64f79efd..b8add91b64d1 100644 --- a/Makefile +++ b/Makefile @@ -76,6 +76,9 @@ docs/content/using-npm/config.md: scripts/config-doc.js lib/utils/config/*.js test: dev-deps node bin/npm-cli.js test +smoke-tests: dev-deps + node bin/npm-cli.js run smoke-tests + ls-ok: node . ls --production >/dev/null @@ -93,7 +96,7 @@ prune: @[[ "$(shell git status -s)" != "" ]] && echo "ERR: found unpruned files" && exit 1 || echo "git status is clean" -publish: gitclean ls-ok link test docs prune +publish: gitclean ls-ok link test smoke-tests docs prune @git push origin :v$(shell node bin/npm-cli.js --no-timing -v) 2>&1 || true git push origin $(BRANCH) &&\ git push origin --tags &&\ diff --git a/package.json b/package.json index 4d531d7de905..2dcc65543f91 100644 --- a/package.json +++ b/package.json @@ -207,7 +207,8 @@ "lint": "npm run eslint -- test/lib test/bin \"lib/**/*.js\"", "lintfix": "npm run lint -- --fix", "prelint": "rimraf test/npm_cache*", - "resetdeps": "bash scripts/resetdeps.sh" + "resetdeps": "bash scripts/resetdeps.sh", + "smoke-tests": "tap smoke-tests/index.js" }, "//": [ "XXX temporarily only run unit tests while v7 beta is in progress", diff --git a/smoke-tests/content/abbrev.json b/smoke-tests/content/abbrev.json new file mode 100644 index 000000000000..ffcf5474a9de --- /dev/null +++ b/smoke-tests/content/abbrev.json @@ -0,0 +1,449 @@ +{ + "_id": "abbrev", + "_rev": "72-d1d46bef3d311d6da6737e109e771869", + "name": "abbrev", + "dist-tags": { + "latest": "1.1.1" + }, + "versions": { + "1.0.3": { + "name": "abbrev", + "version": "1.0.3", + "description": "Like ruby's abbrev module, but in js", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me" + }, + "main": "./lib/abbrev.js", + "scripts": { + "test": "node lib/abbrev.js" + }, + "repository": { + "type": "git", + "url": "git://github.com/isaacs/abbrev-js.git" + }, + "_id": "abbrev@1.0.3", + "engines": { + "node": "*" + }, + "_engineSupported": true, + "_npmVersion": "1.0.0rc7", + "_nodeVersion": "v0.5.0-pre", + "_defaultsLoaded": true, + "dist": { + "shasum": "aa049c967f999222aa42e14434f0c562ef468241", + "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.3.tgz" + }, + "directories": {} + }, + "1.0.4": { + "name": "abbrev", + "version": "1.0.4", + "description": "Like ruby's abbrev module, but in js", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me" + }, + "main": "./lib/abbrev.js", + "scripts": { + "test": "node lib/abbrev.js" + }, + "repository": { + "type": "git", + "url": "http://github.com/isaacs/abbrev-js" + }, + "license": { + "type": "MIT", + "url": "https://github.com/isaacs/abbrev-js/raw/master/LICENSE" + }, + "_id": "abbrev@1.0.4", + "dist": { + "shasum": "bd55ae5e413ba1722ee4caba1f6ea10414a59ecd", + "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.4.tgz" + }, + "_npmVersion": "1.1.70", + "_npmUser": { + "name": "isaacs", + "email": "i@izs.me" + }, + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + } + ], + "directories": {} + }, + "1.0.5": { + "name": "abbrev", + "version": "1.0.5", + "description": "Like ruby's abbrev module, but in js", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me" + }, + "main": "abbrev.js", + "scripts": { + "test": "node test.js" + }, + "repository": { + "type": "git", + "url": "http://github.com/isaacs/abbrev-js" + }, + "license": { + "type": "MIT", + "url": "https://github.com/isaacs/abbrev-js/raw/master/LICENSE" + }, + "bugs": { + "url": "https://github.com/isaacs/abbrev-js/issues" + }, + "homepage": "https://github.com/isaacs/abbrev-js", + "_id": "abbrev@1.0.5", + "_shasum": "5d8257bd9ebe435e698b2fa431afde4fe7b10b03", + "_from": ".", + "_npmVersion": "1.4.7", + "_npmUser": { + "name": "isaacs", + "email": "i@izs.me" + }, + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + } + ], + "dist": { + "shasum": "5d8257bd9ebe435e698b2fa431afde4fe7b10b03", + "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.5.tgz" + }, + "directories": {} + }, + "1.0.6": { + "name": "abbrev", + "version": "1.0.6", + "description": "Like ruby's abbrev module, but in js", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me" + }, + "main": "abbrev.js", + "scripts": { + "test": "node test.js" + }, + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/isaacs/abbrev-js.git" + }, + "license": "ISC", + "gitHead": "648a6735d9c5a7a04885e3ada49eed4db36181c2", + "bugs": { + "url": "https://github.com/isaacs/abbrev-js/issues" + }, + "homepage": "https://github.com/isaacs/abbrev-js#readme", + "_id": "abbrev@1.0.6", + "_shasum": "b6d632b859b3fa2d6f7e4b195472461b9e32dc30", + "_from": ".", + "_npmVersion": "2.10.0", + "_nodeVersion": "2.0.1", + "_npmUser": { + "name": "isaacs", + "email": "isaacs@npmjs.com" + }, + "dist": { + "shasum": "b6d632b859b3fa2d6f7e4b195472461b9e32dc30", + "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.6.tgz" + }, + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + } + ], + "directories": {} + }, + "1.0.7": { + "name": "abbrev", + "version": "1.0.7", + "description": "Like ruby's abbrev module, but in js", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me" + }, + "main": "abbrev.js", + "scripts": { + "test": "tap test.js --cov" + }, + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/isaacs/abbrev-js.git" + }, + "license": "ISC", + "devDependencies": { + "tap": "^1.2.0" + }, + "gitHead": "821d09ce7da33627f91bbd8ed631497ed6f760c2", + "bugs": { + "url": "https://github.com/isaacs/abbrev-js/issues" + }, + "homepage": "https://github.com/isaacs/abbrev-js#readme", + "_id": "abbrev@1.0.7", + "_shasum": "5b6035b2ee9d4fb5cf859f08a9be81b208491843", + "_from": ".", + "_npmVersion": "2.10.1", + "_nodeVersion": "2.0.1", + "_npmUser": { + "name": "isaacs", + "email": "isaacs@npmjs.com" + }, + "dist": { + "shasum": "5b6035b2ee9d4fb5cf859f08a9be81b208491843", + "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.7.tgz" + }, + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + } + ], + "directories": {} + }, + "1.0.9": { + "name": "abbrev", + "version": "1.0.9", + "description": "Like ruby's abbrev module, but in js", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me" + }, + "main": "abbrev.js", + "scripts": { + "test": "tap test.js --cov" + }, + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/isaacs/abbrev-js.git" + }, + "license": "ISC", + "devDependencies": { + "tap": "^5.7.2" + }, + "files": [ + "abbrev.js" + ], + "gitHead": "c386cd9dbb1d8d7581718c54d4ba944cc9298d6f", + "bugs": { + "url": "https://github.com/isaacs/abbrev-js/issues" + }, + "homepage": "https://github.com/isaacs/abbrev-js#readme", + "_id": "abbrev@1.0.9", + "_shasum": "91b4792588a7738c25f35dd6f63752a2f8776135", + "_from": ".", + "_npmVersion": "3.9.1", + "_nodeVersion": "4.4.4", + "_npmUser": { + "name": "isaacs", + "email": "i@izs.me" + }, + "dist": { + "shasum": "91b4792588a7738c25f35dd6f63752a2f8776135", + "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz" + }, + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + } + ], + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/abbrev-1.0.9.tgz_1466016055839_0.7825860097073019" + }, + "directories": {} + }, + "1.1.0": { + "name": "abbrev", + "version": "1.1.0", + "description": "Like ruby's abbrev module, but in js", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me" + }, + "main": "abbrev.js", + "scripts": { + "test": "tap test.js --100", + "preversion": "npm test", + "postversion": "npm publish", + "postpublish": "git push origin --all; git push origin --tags" + }, + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/isaacs/abbrev-js.git" + }, + "license": "ISC", + "devDependencies": { + "tap": "^10.1" + }, + "files": [ + "abbrev.js" + ], + "gitHead": "7136d4d95449dc44115d4f78b80ec907724f64e0", + "bugs": { + "url": "https://github.com/isaacs/abbrev-js/issues" + }, + "homepage": "https://github.com/isaacs/abbrev-js#readme", + "_id": "abbrev@1.1.0", + "_shasum": "d0554c2256636e2f56e7c2e5ad183f859428d81f", + "_from": ".", + "_npmVersion": "4.3.0", + "_nodeVersion": "8.0.0-pre", + "_npmUser": { + "name": "isaacs", + "email": "i@izs.me" + }, + "dist": { + "shasum": "d0554c2256636e2f56e7c2e5ad183f859428d81f", + "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz" + }, + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + } + ], + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/abbrev-1.1.0.tgz_1487054000015_0.9229173036292195" + }, + "directories": {} + }, + "1.1.1": { + "name": "abbrev", + "version": "1.1.1", + "description": "Like ruby's abbrev module, but in js", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me" + }, + "main": "abbrev.js", + "scripts": { + "test": "tap test.js --100", + "preversion": "npm test", + "postversion": "npm publish", + "postpublish": "git push origin --all; git push origin --tags" + }, + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/isaacs/abbrev-js.git" + }, + "license": "ISC", + "devDependencies": { + "tap": "^10.1" + }, + "files": [ + "abbrev.js" + ], + "gitHead": "a9ee72ebc8fe3975f1b0c7aeb3a8f2a806a432eb", + "bugs": { + "url": "https://github.com/isaacs/abbrev-js/issues" + }, + "homepage": "https://github.com/isaacs/abbrev-js#readme", + "_id": "abbrev@1.1.1", + "_npmVersion": "5.4.2", + "_nodeVersion": "8.5.0", + "_npmUser": { + "name": "isaacs", + "email": "i@izs.me" + }, + "dist": { + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "shasum": "f8f2c887ad10bf67f634f005b6987fed3179aac8", + "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz" + }, + "maintainers": [ + { + "name": "gabra", + "email": "jerry+1@npmjs.com" + }, + { + "name": "isaacs", + "email": "i@izs.me" + } + ], + "_npmOperationalInternal": { + "host": "s3://npm-registry-packages", + "tmp": "tmp/abbrev-1.1.1.tgz_1506566833068_0.05750026390887797" + }, + "directories": {} + } + }, + "maintainers": [ + { + "email": "quitlahok@gmail.com", + "name": "nlf" + }, + { + "email": "ruyadorno@hotmail.com", + "name": "ruyadorno" + }, + { + "email": "darcy@darcyclarke.me", + "name": "darcyclarke" + }, + { + "email": "evilpacket@gmail.com", + "name": "adam_baldwin" + }, + { + "email": "i@izs.me", + "name": "isaacs" + } + ], + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me" + }, + "description": "Like ruby's abbrev module, but in js", + "time": { + "modified": "2020-10-13T05:04:03.636Z", + "created": "2011-03-21T22:21:11.183Z", + "1.0.1": "2011-03-21T22:21:11.183Z", + "1.0.2": "2011-03-21T22:21:11.183Z", + "1.0.3": "2011-03-21T22:21:11.183Z", + "1.0.3-1": "2011-03-24T23:01:19.581Z", + "1.0.4": "2013-01-09T00:01:24.135Z", + "1.0.5": "2014-04-17T20:09:12.523Z", + "1.0.6": "2015-05-21T00:58:16.778Z", + "1.0.7": "2015-05-30T22:57:54.685Z", + "1.0.9": "2016-06-15T18:41:01.215Z", + "1.1.0": "2017-02-14T06:33:20.235Z", + "1.1.1": "2017-09-28T02:47:13.220Z" + }, + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/isaacs/abbrev-js.git" + }, + "users": { + "leesei": true, + "ceejbot": true, + "isaacs": true, + "npm-www": true, + "tunnckocore": true, + "ruanyu1": true, + "leodutra": true, + "jessaustin": true, + "jian263994241": true, + "floriannagel": true, + "tdmalone": true, + "ryanve": true, + "detj": true, + "monjer": true, + "d-band": true + }, + "readme": "# abbrev-js\n\nJust like [ruby's Abbrev](http://apidock.com/ruby/Abbrev).\n\nUsage:\n\n var abbrev = require(\"abbrev\");\n abbrev(\"foo\", \"fool\", \"folding\", \"flop\");\n \n // returns:\n { fl: 'flop'\n , flo: 'flop'\n , flop: 'flop'\n , fol: 'folding'\n , fold: 'folding'\n , foldi: 'folding'\n , foldin: 'folding'\n , folding: 'folding'\n , foo: 'foo'\n , fool: 'fool'\n }\n\nThis is handy for command-line scripts, or other cases where you want to be able to accept shorthands.\n", + "readmeFilename": "README.md", + "homepage": "https://github.com/isaacs/abbrev-js#readme", + "bugs": { + "url": "https://github.com/isaacs/abbrev-js/issues" + }, + "license": "ISC" +} diff --git a/smoke-tests/content/abbrev.min.json b/smoke-tests/content/abbrev.min.json new file mode 100644 index 000000000000..c03d91c9c8c1 --- /dev/null +++ b/smoke-tests/content/abbrev.min.json @@ -0,0 +1,89 @@ +{ + "name": "abbrev", + "dist-tags": { + "latest": "1.1.1" + }, + "versions": { + "1.0.3": { + "name": "abbrev", + "version": "1.0.3", + "dist": { + "shasum": "aa049c967f999222aa42e14434f0c562ef468241", + "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.3.tgz" + }, + "engines": { + "node": "*" + } + }, + "1.0.4": { + "name": "abbrev", + "version": "1.0.4", + "dist": { + "shasum": "bd55ae5e413ba1722ee4caba1f6ea10414a59ecd", + "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.4.tgz" + } + }, + "1.0.5": { + "name": "abbrev", + "version": "1.0.5", + "dist": { + "shasum": "5d8257bd9ebe435e698b2fa431afde4fe7b10b03", + "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.5.tgz" + } + }, + "1.0.6": { + "name": "abbrev", + "version": "1.0.6", + "dist": { + "shasum": "b6d632b859b3fa2d6f7e4b195472461b9e32dc30", + "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.6.tgz" + } + }, + "1.0.7": { + "name": "abbrev", + "version": "1.0.7", + "devDependencies": { + "tap": "^1.2.0" + }, + "dist": { + "shasum": "5b6035b2ee9d4fb5cf859f08a9be81b208491843", + "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.7.tgz" + } + }, + "1.0.9": { + "name": "abbrev", + "version": "1.0.9", + "devDependencies": { + "tap": "^5.7.2" + }, + "dist": { + "shasum": "91b4792588a7738c25f35dd6f63752a2f8776135", + "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz" + } + }, + "1.1.0": { + "name": "abbrev", + "version": "1.1.0", + "devDependencies": { + "tap": "^10.1" + }, + "dist": { + "shasum": "d0554c2256636e2f56e7c2e5ad183f859428d81f", + "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz" + } + }, + "1.1.1": { + "name": "abbrev", + "version": "1.1.1", + "devDependencies": { + "tap": "^10.1" + }, + "dist": { + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "shasum": "f8f2c887ad10bf67f634f005b6987fed3179aac8", + "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz" + } + } + }, + "modified": "2020-10-13T05:04:03.636Z" +} diff --git a/smoke-tests/content/abbrev/-/abbrev-1.0.4.tgz b/smoke-tests/content/abbrev/-/abbrev-1.0.4.tgz new file mode 100644 index 000000000000..dfd1b55919e2 Binary files /dev/null and b/smoke-tests/content/abbrev/-/abbrev-1.0.4.tgz differ diff --git a/smoke-tests/content/abbrev/-/abbrev-1.1.1.tgz b/smoke-tests/content/abbrev/-/abbrev-1.1.1.tgz new file mode 100644 index 000000000000..4d9504504f5a Binary files /dev/null and b/smoke-tests/content/abbrev/-/abbrev-1.1.1.tgz differ diff --git a/smoke-tests/content/promise-all-reject-late.json b/smoke-tests/content/promise-all-reject-late.json new file mode 100644 index 000000000000..e243b92a3b92 --- /dev/null +++ b/smoke-tests/content/promise-all-reject-late.json @@ -0,0 +1,138 @@ +{ + "_id": "promise-all-reject-late", + "_rev": "1-bb2ac9479869cc8479d1dd01c568acc0", + "name": "promise-all-reject-late", + "dist-tags": { + "latest": "1.0.1" + }, + "versions": { + "1.0.0": { + "name": "promise-all-reject-late", + "version": "1.0.0", + "description": "Like Promise.all, but save rejections until all promises are resolved", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "https://izs.me" + }, + "license": "ISC", + "scripts": { + "test": "tap", + "preversion": "npm test", + "postversion": "npm publish", + "prepublishOnly": "git push origin --follow-tags" + }, + "tap": { + "check-coverage": true + }, + "devDependencies": { + "tap": "^14.10.5" + }, + "gitHead": "e9614a15b22f421aa97ff281d4e0f23681edbe98", + "_id": "promise-all-reject-late@1.0.0", + "_nodeVersion": "13.3.0", + "_npmVersion": "6.13.4", + "dist": { + "integrity": "sha512-f5XvVl++12pEo7Sv7f7FGfzVuVpeY2msNKjn7nNcXyOSKh5uVu7IAzDO6RE9hDVoHJhxvg+gqEacwkZ891Se5g==", + "shasum": "4fa37515e2d78c3b0462414402a8debce62b8b9f", + "tarball": "https://registry.npmjs.org/promise-all-reject-late/-/promise-all-reject-late-1.0.0.tgz", + "fileCount": 7, + "unpackedSize": 123039, + "npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeBmldCRA9TVsSAnZWagAAaigP/2CarvNCbglNS0dgjOoH\n7ZuFo1cG+N8BkZct00TyEJjuB+5UUmv9TSnZogfEOGutvMqUTSRhvm3fOWsJ\n7TXs8zJ6SotDR9+xlxqi/skpYXfRdNjdaMvo9kYO5jaV84pstdbl17sPeYXd\nCudbAKp1sYodlaJyqpyfUd2PWUNe/VGLODmjLogHB4/bevT3tdjsdauKrUS4\n3VFw8sS1Fwp7P2YneNIK3C1TY/Yb66KysZO23VsQemCQFKXpQJMa9B6yj8zs\n5BQp+W5tM70IfW6OXD0+Vt2jWr9jmKmoWVEiL5usJT3zD7vRbeH3xQvSEgDD\nskI8vH8iJ+3EbEOWTGlIu7mX88Dp2KnHOoRUkOR03WJWuGnsTC8Uyqi0F1Xd\nFeFlaeNzynR/R2LcdRNiFOM+1xtzfAtVGF7TIp9UjgJwSNNkEMlkNzQqSiC7\n/AeqsAYoBBNmYWY2fvXdS9HQ4HfIGjI++jCYWX4I7sUvOjqfcwlEz8MwromA\nqeBAFPdvnB0F/q/AOOLkcdsO81jES7ts0nB7bDt0rDbztWWq34BSMDnNoSDo\nDE9q8u7g68tQcr3WmOQr4ro10sSbJVJZmz8DSJKCbVJ+FN0+GM+49oyyhIFl\nOjokXn5U8ASEdiZnmFnt51dr9A4fyjhehotJA6qSs7t2fBe86VnufijC971U\nv3Jc\r\n=lLwf\r\n-----END PGP SIGNATURE-----\r\n" + }, + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + } + ], + "_npmUser": { + "name": "isaacs", + "email": "i@izs.me" + }, + "directories": {}, + "_npmOperationalInternal": { + "host": "s3://npm-registry-packages", + "tmp": "tmp/promise-all-reject-late_1.0.0_1577478492470_0.9438095135747766" + }, + "_hasShrinkwrap": false + }, + "1.0.1": { + "name": "promise-all-reject-late", + "version": "1.0.1", + "description": "Like Promise.all, but save rejections until all promises are resolved", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "https://izs.me" + }, + "license": "ISC", + "scripts": { + "test": "tap", + "preversion": "npm test", + "postversion": "npm publish", + "prepublishOnly": "git push origin --follow-tags" + }, + "tap": { + "check-coverage": true + }, + "devDependencies": { + "tap": "^14.10.5" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "gitHead": "c892a9db86650c9229ab4cc70395106684d6818a", + "_id": "promise-all-reject-late@1.0.1", + "_nodeVersion": "12.14.1", + "_npmVersion": "6.13.6", + "dist": { + "integrity": "sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw==", + "shasum": "f8ebf13483e5ca91ad809ccc2fcf25f26f8643c2", + "tarball": "https://registry.npmjs.org/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz", + "fileCount": 8, + "unpackedSize": 123171, + "npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeL65kCRA9TVsSAnZWagAAas4P/2WFFJvncp0LWb3DbE0t\ndx9BhZEwY3W8V6ug8uKvph24LoQp1PakkncscKS7PsCVHyIslD+fi6V99AmI\nOmL2ECAMUd5N69Cs8eTi4tKTNtUoIslfCu0+SMlCAF11D7oBXSabdOxGQofA\nuksoHdCqGM6M1y2BGjK7FR8dSwvgbQCPaUzazZ5w7w4XqVxDlzbvNj2E5mSF\n5HjlT5q239uNQppwPIFpisyi9DKa0ran2N7F2ioZ1PHvhFCqo6rmL8tAQsxQ\n+3OA4eFD0FJCJuqd3MOaY66mkncfNpmPvQYMyigKBUdJJyrgNsB67yfaFduy\ndK198Bnva5kotttQ4EHxM6gkqRm2d9o1/sYmAUtDELgrVDxzeNl+yG+nCkho\n1ta4cY+wy1dTjqAYaprQJ855nIeGGnr3tvz4dEGX/5eyh5K+oYVOYRFvWFX6\nVlEhBmSRqamfW5N1ndMyY18FM+Vc12yu66yZ3z1FqbgEGqdf3EP3lwWqClpP\nbPdXANzHM1FIz1PGHC7IZFWXH5KV1z+JXXahg/d8CLzz0PY6jaBt4c2xDvo7\nLaEAm7kNMbdewKvuTuG7x2Kqyf1KwjpOhXMrq6h0rlFm0pRt0xAArQ9Sglw8\n2Vq9Ic9EEsSIpzA5iQ86O1xkTREGHTB3uTRXUJixXIGkhLkhBB+Uj9y+GoOh\nX+Dm\r\n=yF+m\r\n-----END PGP SIGNATURE-----\r\n" + }, + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + } + ], + "_npmUser": { + "name": "isaacs", + "email": "i@izs.me" + }, + "directories": {}, + "_npmOperationalInternal": { + "host": "s3://npm-registry-packages", + "tmp": "tmp/promise-all-reject-late_1.0.1_1580183139628_0.5159334029276426" + }, + "_hasShrinkwrap": false + } + }, + "time": { + "created": "2019-12-27T20:28:12.428Z", + "1.0.0": "2019-12-27T20:28:12.645Z", + "modified": "2020-01-28T03:45:42.154Z", + "1.0.1": "2020-01-28T03:45:39.762Z" + }, + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + } + ], + "description": "Like Promise.all, but save rejections until all promises are resolved", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "https://izs.me" + }, + "license": "ISC", + "readme": "# promise-all-reject-late\n\nLike Promise.all, but save rejections until all promises are resolved.\n\nThis is handy when you want to do a bunch of things in parallel, and\nrollback on failure, without clobbering or conflicting with those parallel\nactions that may be in flight. For example, creating a bunch of files,\nand deleting any if they don't all succeed.\n\nExample:\n\n```js\nconst lateReject = require('promise-all-reject-late')\n\nconst { promisify } = require('util')\nconst fs = require('fs')\nconst writeFile = promisify(fs.writeFile)\n\nconst createFilesOrRollback = (files) => {\n return lateReject(files.map(file => writeFile(file, 'some data')))\n .catch(er => {\n // try to clean up, then fail with the initial error\n // we know that all write attempts are finished at this point\n return lateReject(files.map(file => rimraf(file)))\n .catch(er => {\n console.error('failed to clean up, youre on your own i guess', er)\n })\n .then(() => {\n // fail with the original error\n throw er\n })\n })\n}\n```\n\n## API\n\n* `lateReject([array, of, promises])` - Resolve all the promises,\n returning a promise that rejects with the first error, or resolves with\n the array of results, but only after all promises are settled.\n", + "readmeFilename": "README.md", + "_cached": false, + "_contentLength": 0 +} \ No newline at end of file diff --git a/smoke-tests/content/promise-all-reject-late.min.json b/smoke-tests/content/promise-all-reject-late.min.json new file mode 100644 index 000000000000..699be7aaf2e8 --- /dev/null +++ b/smoke-tests/content/promise-all-reject-late.min.json @@ -0,0 +1,44 @@ +{ + "name": "promise-all-reject-late", + "dist-tags": { + "latest": "1.0.1" + }, + "versions": { + "1.0.0": { + "name": "promise-all-reject-late", + "version": "1.0.0", + "devDependencies": { + "tap": "^14.10.5" + }, + "dist": { + "integrity": "sha512-f5XvVl++12pEo7Sv7f7FGfzVuVpeY2msNKjn7nNcXyOSKh5uVu7IAzDO6RE9hDVoHJhxvg+gqEacwkZ891Se5g==", + "shasum": "4fa37515e2d78c3b0462414402a8debce62b8b9f", + "tarball": "https://registry.npmjs.org/promise-all-reject-late/-/promise-all-reject-late-1.0.0.tgz", + "fileCount": 7, + "unpackedSize": 123039, + "npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeBmldCRA9TVsSAnZWagAAaigP/2CarvNCbglNS0dgjOoH\n7ZuFo1cG+N8BkZct00TyEJjuB+5UUmv9TSnZogfEOGutvMqUTSRhvm3fOWsJ\n7TXs8zJ6SotDR9+xlxqi/skpYXfRdNjdaMvo9kYO5jaV84pstdbl17sPeYXd\nCudbAKp1sYodlaJyqpyfUd2PWUNe/VGLODmjLogHB4/bevT3tdjsdauKrUS4\n3VFw8sS1Fwp7P2YneNIK3C1TY/Yb66KysZO23VsQemCQFKXpQJMa9B6yj8zs\n5BQp+W5tM70IfW6OXD0+Vt2jWr9jmKmoWVEiL5usJT3zD7vRbeH3xQvSEgDD\nskI8vH8iJ+3EbEOWTGlIu7mX88Dp2KnHOoRUkOR03WJWuGnsTC8Uyqi0F1Xd\nFeFlaeNzynR/R2LcdRNiFOM+1xtzfAtVGF7TIp9UjgJwSNNkEMlkNzQqSiC7\n/AeqsAYoBBNmYWY2fvXdS9HQ4HfIGjI++jCYWX4I7sUvOjqfcwlEz8MwromA\nqeBAFPdvnB0F/q/AOOLkcdsO81jES7ts0nB7bDt0rDbztWWq34BSMDnNoSDo\nDE9q8u7g68tQcr3WmOQr4ro10sSbJVJZmz8DSJKCbVJ+FN0+GM+49oyyhIFl\nOjokXn5U8ASEdiZnmFnt51dr9A4fyjhehotJA6qSs7t2fBe86VnufijC971U\nv3Jc\r\n=lLwf\r\n-----END PGP SIGNATURE-----\r\n" + } + }, + "1.0.1": { + "name": "promise-all-reject-late", + "version": "1.0.1", + "devDependencies": { + "tap": "^14.10.5" + }, + "dist": { + "integrity": "sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw==", + "shasum": "f8ebf13483e5ca91ad809ccc2fcf25f26f8643c2", + "tarball": "https://registry.npmjs.org/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz", + "fileCount": 8, + "unpackedSize": 123171, + "npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeL65kCRA9TVsSAnZWagAAas4P/2WFFJvncp0LWb3DbE0t\ndx9BhZEwY3W8V6ug8uKvph24LoQp1PakkncscKS7PsCVHyIslD+fi6V99AmI\nOmL2ECAMUd5N69Cs8eTi4tKTNtUoIslfCu0+SMlCAF11D7oBXSabdOxGQofA\nuksoHdCqGM6M1y2BGjK7FR8dSwvgbQCPaUzazZ5w7w4XqVxDlzbvNj2E5mSF\n5HjlT5q239uNQppwPIFpisyi9DKa0ran2N7F2ioZ1PHvhFCqo6rmL8tAQsxQ\n+3OA4eFD0FJCJuqd3MOaY66mkncfNpmPvQYMyigKBUdJJyrgNsB67yfaFduy\ndK198Bnva5kotttQ4EHxM6gkqRm2d9o1/sYmAUtDELgrVDxzeNl+yG+nCkho\n1ta4cY+wy1dTjqAYaprQJ855nIeGGnr3tvz4dEGX/5eyh5K+oYVOYRFvWFX6\nVlEhBmSRqamfW5N1ndMyY18FM+Vc12yu66yZ3z1FqbgEGqdf3EP3lwWqClpP\nbPdXANzHM1FIz1PGHC7IZFWXH5KV1z+JXXahg/d8CLzz0PY6jaBt4c2xDvo7\nLaEAm7kNMbdewKvuTuG7x2Kqyf1KwjpOhXMrq6h0rlFm0pRt0xAArQ9Sglw8\n2Vq9Ic9EEsSIpzA5iQ86O1xkTREGHTB3uTRXUJixXIGkhLkhBB+Uj9y+GoOh\nX+Dm\r\n=yF+m\r\n-----END PGP SIGNATURE-----\r\n" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + } + }, + "modified": "2020-01-28T03:45:42.154Z", + "_cached": false, + "_contentLength": 2803 +} \ No newline at end of file diff --git a/smoke-tests/content/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz b/smoke-tests/content/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz new file mode 100644 index 000000000000..7da404423876 Binary files /dev/null and b/smoke-tests/content/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz differ diff --git a/smoke-tests/index.js b/smoke-tests/index.js new file mode 100644 index 000000000000..38c3ed306e5f --- /dev/null +++ b/smoke-tests/index.js @@ -0,0 +1,196 @@ +const fs = require('fs') +const { promisify } = require('util') +const execAsync = promisify(require('child_process').exec) +const { resolve } = require('path') +const t = require('tap') + +const normalizePath = path => path.replace(/[A-Z]:/, '').replace(/\\/g, '/') +const cwd = normalizePath(process.cwd()) +t.cleanSnapshot = s => s.split(cwd).join('{CWD}') + .split(registry).join('https://registry.npmjs.org/') + .split(normalizePath(process.execPath)).join('node') + .split(process.cwd()).join('{CWD}') + .replace(/\\+/g, '/') + .replace(/\r\n/g, '\n') + +// setup server +const registryServer = require('./server.js') +const { registry } = registryServer +t.test('setup server', { bail: true, buffered: false }, registryServer) + +// setup fixtures +const path = t.testdir({ + '.npmrc': '', + cache: {}, + project: {}, + bin: {}, +}) +const localPrefix = resolve(path, 'project') +const userconfigLocation = resolve(path, '.npmrc') +const npmLocation = resolve(__dirname, '..') +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` +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) + return String(res.stdout) +} +const readFile = filename => + String(fs.readFileSync(resolve(localPrefix, filename))) + +t.test('npm init', async t => { + const cmd = `${npmBin} init -y` + const cmdRes = await exec(cmd) + + t.matchSnapshot(cmdRes, 'should have successful npm init result') + const pkg = JSON.parse(fs.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 install prodDep@version', async t => { + const cmd = `${npmBin} install abbrev@1.0.4` + const cmdRes = await exec(cmd) + + t.matchSnapshot(cmdRes.replace(/in.*s/, ''), + 'should have expected install reify output') + t.matchSnapshot( + readFile('package.json'), + 'should have expected package.json result' + ) + t.matchSnapshot( + readFile('package-lock.json'), + 'should have expected lockfile result' + ) +}) + +t.test('npm install dev dep', async t => { + const cmd = `${npmBin} install -D promise-all-reject-late` + const cmdRes = await exec(cmd) + + t.matchSnapshot(cmdRes.replace(/in.*s/, ''), + 'should have expected dev dep added reify output') + t.matchSnapshot( + readFile('package.json'), + 'should have expected dev dep added package.json result' + ) + t.matchSnapshot( + readFile('package-lock.json'), + 'should have expected dev dep added lockfile result' + ) +}) + +t.test('npm ls', async t => { + const cmd = `${npmBin} ls` + const cmdRes = await exec(cmd) + + t.matchSnapshot(cmdRes, + 'should have expected ls output') +}) + +t.test('npm fund', async t => { + const cmd = `${npmBin} fund` + const cmdRes = await exec(cmd) + + t.matchSnapshot(cmdRes, + 'should have expected fund output') +}) + +t.test('npm explain', async t => { + const cmd = `${npmBin} explain abbrev` + const cmdRes = await exec(cmd) + + 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) + + t.matchSnapshot(cmdRes, + 'should have expected diff output') +}) + +t.test('npm outdated', async t => { + const cmd = `${npmBin} outdated` + const cmdRes = await exec(cmd) + + t.matchSnapshot(cmdRes, + '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) + + t.matchSnapshot(cmdRes, + 'should have expected set-script output') + t.matchSnapshot( + readFile('package.json'), + 'should have expected script added package.json result' + ) +}) + +t.test('npm run-script', async t => { + const cmd = `${npmBin} run hello` + const cmdRes = await exec(cmd) + + t.matchSnapshot(cmdRes, + 'should have expected run-script output') +}) + +t.test('npm prefix', async t => { + const cmd = `${npmBin} prefix` + const cmdRes = await exec(cmd) + + 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) + + 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) + + t.matchSnapshot(cmdRes.replace(/in.*s/, ''), + 'should have expected update reify output') + t.matchSnapshot( + readFile('package.json'), + 'should have expected update package.json result' + ) + t.matchSnapshot( + readFile('package-lock.json'), + 'should have expected update lockfile result' + ) +}) + +t.test('npm uninstall', async t => { + const cmd = `${npmBin} uninstall promise-all-reject-late` + const cmdRes = await exec(cmd) + + t.matchSnapshot(cmdRes.replace(/in.*s/, ''), + 'should have expected uninstall reify output') + t.matchSnapshot( + readFile('package.json'), + 'should have expected uninstall package.json result' + ) + t.matchSnapshot( + readFile('package-lock.json'), + 'should have expected uninstall lockfile result' + ) +}) diff --git a/smoke-tests/server.js b/smoke-tests/server.js new file mode 100644 index 000000000000..88cb5883da74 --- /dev/null +++ b/smoke-tests/server.js @@ -0,0 +1,276 @@ +const {join, dirname} = 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 = cb => { + const server = module.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, '/'))) + 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, cb) +} + +module.exports = t => startServer(() => { + t.parent.teardown(() => module.exports.server.close()) + t.end() +}) + +module.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 +} +module.exports.failAudit = () => { + failAudit = true + return () => failAudit = false +} + +module.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 +} +module.exports.failAdvisoryBulk = () => { + failAdvisoryBulk = true + return () => failAdvisoryBulk = false +} + +module.exports.registry = `http://localhost:${PORT}/` + +module.exports.start = startServer +module.exports.stop = () => module.exports.server.close() + +if (require.main === module) { + startServer(() => { + console.log(`Mock registry live at: + ${module.exports.registry} +Press ^D to close gracefully.`) + }) + process.openStdin() + process.stdin.on('end', () => module.exports.server.close()) +} diff --git a/tap-snapshots/smoke-tests-index.js-TAP.test.js b/tap-snapshots/smoke-tests-index.js-TAP.test.js new file mode 100644 index 000000000000..aa8977316b1c --- /dev/null +++ b/tap-snapshots/smoke-tests-index.js-TAP.test.js @@ -0,0 +1,649 @@ +/* IMPORTANT + * This snapshot file is auto-generated, but designed for humans. + * It should be checked into source control and tracked carefully. + * Re-generate by setting TAP_SNAPSHOT=1 and running tests. + * Make sure to inspect the output below. Do not ignore changes! + */ +'use strict' +exports[`smoke-tests/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 ++++ b/package.json +@@ -1,15 +1,21 @@ + { + "name": "abbrev", +- "version": "1.0.4", ++ "version": "1.1.1", + "description": "Like ruby's abbrev module, but in js", + "author": "Isaac Z. Schlueter ", +- "main": "./lib/abbrev.js", ++ "main": "abbrev.js", + "scripts": { +- "test": "node lib/abbrev.js" ++ "test": "tap test.js --100", ++ "preversion": "npm test", ++ "postversion": "npm publish", ++ "postpublish": "git push origin --all; git push origin --tags" + }, + "repository": "http://github.com/isaacs/abbrev-js", +- "license": { +- "type": "MIT", +- "url": "https://github.com/isaacs/abbrev-js/raw/master/LICENSE" +- } ++ "license": "ISC", ++ "devDependencies": { ++ "tap": "^10.1" ++ }, ++ "files": [ ++ "abbrev.js" ++ ] + } +diff --git a/LICENSE b/LICENSE +index v1.0.4..v1.1.1 100644 +--- a/LICENSE ++++ b/LICENSE +@@ -1,4 +1,27 @@ +-Copyright 2009, 2010, 2011 Isaac Z. Schlueter. ++This software is dual-licensed under the ISC and MIT licenses. ++You may use this software under EITHER of the following licenses. ++ ++---------- ++ ++The ISC License ++ ++Copyright (c) Isaac Z. Schlueter and Contributors ++ ++Permission to use, copy, modify, and/or distribute this software for any ++purpose with or without fee is hereby granted, provided that the above ++copyright notice and this permission notice appear in all copies. ++ ++THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR ++IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ ++---------- ++ ++Copyright Isaac Z. Schlueter and Contributors + All rights reserved. + + Permission is hereby granted, free of charge, to any person +diff --git a/lib/abbrev.js b/lib/abbrev.js +deleted file mode 100644 +index v1.0.4..v1.1.1 +--- a/lib/abbrev.js ++++ b/lib/abbrev.js +@@ -1,111 +0,0 @@ +- +-module.exports = exports = abbrev.abbrev = abbrev +- +-abbrev.monkeyPatch = monkeyPatch +- +-function monkeyPatch () { +- Object.defineProperty(Array.prototype, 'abbrev', { +- value: function () { return abbrev(this) }, +- enumerable: false, configurable: true, writable: true +- }) +- +- Object.defineProperty(Object.prototype, 'abbrev', { +- value: function () { return abbrev(Object.keys(this)) }, +- enumerable: false, configurable: true, writable: true +- }) +-} +- +-function abbrev (list) { +- if (arguments.length !== 1 || !Array.isArray(list)) { +- list = Array.prototype.slice.call(arguments, 0) +- } +- for (var i = 0, l = list.length, args = [] ; i < l ; i ++) { +- args[i] = typeof list[i] === "string" ? list[i] : String(list[i]) +- } +- +- // sort them lexicographically, so that they're next to their nearest kin +- args = args.sort(lexSort) +- +- // walk through each, seeing how much it has in common with the next and previous +- var abbrevs = {} +- , prev = "" +- for (var i = 0, l = args.length ; i < l ; i ++) { +- var current = args[i] +- , next = args[i + 1] || "" +- , nextMatches = true +- , prevMatches = true +- if (current === next) continue +- for (var j = 0, cl = current.length ; j < cl ; j ++) { +- var curChar = current.charAt(j) +- nextMatches = nextMatches && curChar === next.charAt(j) +- prevMatches = prevMatches && curChar === prev.charAt(j) +- if (!nextMatches && !prevMatches) { +- j ++ +- break +- } +- } +- prev = current +- if (j === cl) { +- abbrevs[current] = current +- continue +- } +- for (var a = current.substr(0, j) ; j <= cl ; j ++) { +- abbrevs[a] = current +- a += current.charAt(j) +- } +- } +- return abbrevs +-} +- +-function lexSort (a, b) { +- return a === b ? 0 : a > b ? 1 : -1 +-} +- +- +-// tests +-if (module === require.main) { +- +-var assert = require("assert") +-var util = require("util") +- +-console.log("running tests") +-function test (list, expect) { +- var actual = abbrev(list) +- assert.deepEqual(actual, expect, +- "abbrev("+util.inspect(list)+") === " + util.inspect(expect) + "/n"+ +- "actual: "+util.inspect(actual)) +- actual = abbrev.apply(exports, list) +- assert.deepEqual(abbrev.apply(exports, list), expect, +- "abbrev("+list.map(JSON.stringify).join(",")+") === " + util.inspect(expect) + "/n"+ +- "actual: "+util.inspect(actual)) +-} +- +-test([ "ruby", "ruby", "rules", "rules", "rules" ], +-{ rub: 'ruby' +-, ruby: 'ruby' +-, rul: 'rules' +-, rule: 'rules' +-, rules: 'rules' +-}) +-test(["fool", "foom", "pool", "pope"], +-{ fool: 'fool' +-, foom: 'foom' +-, poo: 'pool' +-, pool: 'pool' +-, pop: 'pope' +-, pope: 'pope' +-}) +-test(["a", "ab", "abc", "abcd", "abcde", "acde"], +-{ a: 'a' +-, ab: 'ab' +-, abc: 'abc' +-, abcd: 'abcd' +-, abcde: 'abcde' +-, ac: 'acde' +-, acd: 'acde' +-, acde: 'acde' +-}) +- +-console.log("pass") +- +-} +/ No newline at end of file +diff --git a/abbrev.js b/abbrev.js +new file mode 100644 +index v1.0.4..v1.1.1 +--- a/abbrev.js ++++ b/abbrev.js +@@ -0,0 +1,61 @@ ++module.exports = exports = abbrev.abbrev = abbrev ++ ++abbrev.monkeyPatch = monkeyPatch ++ ++function monkeyPatch () { ++ Object.defineProperty(Array.prototype, 'abbrev', { ++ value: function () { return abbrev(this) }, ++ enumerable: false, configurable: true, writable: true ++ }) ++ ++ Object.defineProperty(Object.prototype, 'abbrev', { ++ value: function () { return abbrev(Object.keys(this)) }, ++ enumerable: false, configurable: true, writable: true ++ }) ++} ++ ++function abbrev (list) { ++ if (arguments.length !== 1 || !Array.isArray(list)) { ++ list = Array.prototype.slice.call(arguments, 0) ++ } ++ for (var i = 0, l = list.length, args = [] ; i < l ; i ++) { ++ args[i] = typeof list[i] === "string" ? list[i] : String(list[i]) ++ } ++ ++ // sort them lexicographically, so that they're next to their nearest kin ++ args = args.sort(lexSort) ++ ++ // walk through each, seeing how much it has in common with the next and previous ++ var abbrevs = {} ++ , prev = "" ++ for (var i = 0, l = args.length ; i < l ; i ++) { ++ var current = args[i] ++ , next = args[i + 1] || "" ++ , nextMatches = true ++ , prevMatches = true ++ if (current === next) continue ++ for (var j = 0, cl = current.length ; j < cl ; j ++) { ++ var curChar = current.charAt(j) ++ nextMatches = nextMatches && curChar === next.charAt(j) ++ prevMatches = prevMatches && curChar === prev.charAt(j) ++ if (!nextMatches && !prevMatches) { ++ j ++ ++ break ++ } ++ } ++ prev = current ++ if (j === cl) { ++ abbrevs[current] = current ++ continue ++ } ++ for (var a = current.substr(0, j) ; j <= cl ; j ++) { ++ abbrevs[a] = current ++ a += current.charAt(j) ++ } ++ } ++ return abbrevs ++} ++ ++function lexSort (a, b) { ++ return a === b ? 0 : a > b ? 1 : -1 ++} + +` + +exports[`smoke-tests/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`] = ` +project@1.0.0 +\`-- https://github.com/sponsors/isaacs + \`-- promise-all-reject-late@1.0.1 + + +` + +exports[`smoke-tests/index.js TAP npm init > should have successful npm init result 1`] = ` +Wrote to {CWD}/smoke-tests/index/project/package.json: + +{ + "name": "project", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo /"Error: no test specified/" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC" +} + + + +` + +exports[`smoke-tests/index.js TAP npm install dev dep > should have expected dev dep added lockfile result 1`] = ` +{ + "name": "project", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "abbrev": "^1.0.4" + }, + "devDependencies": { + "promise-all-reject-late": "^1.0.1" + } + }, + "node_modules/abbrev": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.4.tgz", + "integrity": "sha1-vVWuXkE7oXIu5Mq6H26hBBSlns0=" + }, + "node_modules/promise-all-reject-late": { + "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==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + } + }, + "dependencies": { + "abbrev": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.4.tgz", + "integrity": "sha1-vVWuXkE7oXIu5Mq6H26hBBSlns0=" + }, + "promise-all-reject-late": { + "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==", + "dev": true + } + } +} + +` + +exports[`smoke-tests/index.js TAP npm install dev dep > should have expected dev dep added package.json result 1`] = ` +{ + "name": "project", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo /"Error: no test specified/" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "abbrev": "^1.0.4" + }, + "devDependencies": { + "promise-all-reject-late": "^1.0.1" + } +} + +` + +exports[`smoke-tests/index.js TAP npm install dev dep > should have expected dev dep added reify output 1`] = ` + +added 1 package + +1 package is looking for funding + run \`npm fund\` for details + +` + +exports[`smoke-tests/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`] = ` +{ + "name": "project", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "abbrev": "^1.0.4" + } + }, + "node_modules/abbrev": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.4.tgz", + "integrity": "sha1-vVWuXkE7oXIu5Mq6H26hBBSlns0=" + } + }, + "dependencies": { + "abbrev": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.4.tgz", + "integrity": "sha1-vVWuXkE7oXIu5Mq6H26hBBSlns0=" + } + } +} + +` + +exports[`smoke-tests/index.js TAP npm install prodDep@version > should have expected package.json result 1`] = ` +{ + "name": "project", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo /"Error: no test specified/" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "abbrev": "^1.0.4" + } +} + +` + +exports[`smoke-tests/index.js TAP npm ls > should have expected ls output 1`] = ` +project@1.0.0 {CWD}/smoke-tests/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`] = ` +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 prefix > should have expected prefix output 1`] = ` +{CWD}/smoke-tests/index/project + +` + +exports[`smoke-tests/index.js TAP npm run-script > should have expected run-script output 1`] = ` + +> project@1.0.0 hello +> echo Hello + +Hello + +` + +exports[`smoke-tests/index.js TAP npm set-script > should have expected script added package.json result 1`] = ` +{ + "name": "project", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo /"Error: no test specified/" && exit 1", + "hello": "echo Hello" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "abbrev": "^1.0.4" + }, + "devDependencies": { + "promise-all-reject-late": "^1.0.1" + } +} + +` + +exports[`smoke-tests/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`] = ` +{ + "name": "project", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "abbrev": "^1.0.4" + } + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + } + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + } + } +} + +` + +exports[`smoke-tests/index.js TAP npm uninstall > should have expected uninstall package.json result 1`] = ` +{ + "name": "project", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo /"Error: no test specified/" && exit 1", + "hello": "echo Hello" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "abbrev": "^1.0.4" + } +} + +` + +exports[`smoke-tests/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`] = ` +{ + "name": "project", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "abbrev": "^1.0.4" + }, + "devDependencies": { + "promise-all-reject-late": "^1.0.1" + } + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "node_modules/promise-all-reject-late": { + "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==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + } + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "promise-all-reject-late": { + "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==", + "dev": true + } + } +} + +` + +exports[`smoke-tests/index.js TAP npm update dep > should have expected update package.json result 1`] = ` +{ + "name": "project", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo /"Error: no test specified/" && exit 1", + "hello": "echo Hello" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "abbrev": "^1.0.4" + }, + "devDependencies": { + "promise-all-reject-late": "^1.0.1" + } +} + +` + +exports[`smoke-tests/index.js TAP npm update dep > should have expected update reify output 1`] = ` + +changed 1 package + +1 package is looking for funding + run \`npm fund\` for details + +` + +exports[`smoke-tests/index.js TAP npm view > should have expected view output 1`] = ` + +abbrev@1.0.4 | MIT | deps: none | versions: 8 +Like ruby's abbrev module, but in js +https://github.com/isaacs/abbrev-js#readme + +dist +.tarball: https://registry.npmjs.org/abbrev/-/abbrev-1.0.4.tgz +.shasum: bd55ae5e413ba1722ee4caba1f6ea10414a59ecd + +maintainers: +- nlf <quitlahok@gmail.com> +- ruyadorno <ruyadorno@hotmail.com> +- darcyclarke <darcy@darcyclarke.me> +- adam_baldwin <evilpacket@gmail.com> +- isaacs <i@izs.me> + +dist-tags: +latest: 1.1.1 + +published over a year ago by isaacs <i@izs.me> + +`