1const t = require('tap') 2const { load: loadMockNpm } = require('../../fixtures/mock-npm') 3const { cleanZlib } = require('../../fixtures/clean-snapshot') 4const path = require('path') 5const fs = require('fs') 6 7t.cleanSnapshot = data => cleanZlib(data) 8 9t.test('should pack current directory with no arguments', async t => { 10 const { npm, outputs, logs } = await loadMockNpm(t, { 11 prefixDir: { 12 'package.json': JSON.stringify({ 13 name: 'test-package', 14 version: '1.0.0', 15 }), 16 }, 17 }) 18 await npm.exec('pack', []) 19 const filename = 'test-package-1.0.0.tgz' 20 t.strictSame(outputs, [[filename]]) 21 t.matchSnapshot(logs.notice.map(([, m]) => m), 'logs pack contents') 22 t.ok(fs.statSync(path.resolve(npm.prefix, filename))) 23}) 24 25t.test('follows pack-destination config', async t => { 26 const { npm, outputs } = await loadMockNpm(t, { 27 prefixDir: { 28 'package.json': JSON.stringify({ 29 name: 'test-package', 30 version: '1.0.0', 31 }), 32 'tar-destination': {}, 33 }, 34 config: ({ prefix }) => ({ 'pack-destination': path.join(prefix, 'tar-destination') }), 35 }) 36 await npm.exec('pack', []) 37 const filename = 'test-package-1.0.0.tgz' 38 t.strictSame(outputs, [[filename]]) 39 t.ok(fs.statSync(path.resolve(npm.prefix, 'tar-destination', filename))) 40}) 41 42t.test('should pack given directory for scoped package', async t => { 43 const { npm, outputs } = await loadMockNpm(t, { 44 prefixDir: { 45 'package.json': JSON.stringify({ 46 name: '@npm/test-package', 47 version: '1.0.0', 48 }), 49 }, 50 }) 51 await npm.exec('pack', []) 52 const filename = 'npm-test-package-1.0.0.tgz' 53 t.strictSame(outputs, [[filename]]) 54 t.ok(fs.statSync(path.resolve(npm.prefix, filename))) 55}) 56 57t.test('should log output as valid json', async t => { 58 const { npm, outputs, logs } = await loadMockNpm(t, { 59 prefixDir: { 60 'package.json': JSON.stringify({ 61 name: 'test-package', 62 version: '1.0.0', 63 }), 64 }, 65 config: { json: true }, 66 }) 67 await npm.exec('pack', []) 68 const filename = 'test-package-1.0.0.tgz' 69 t.matchSnapshot(outputs.map(JSON.parse), 'outputs as json') 70 t.matchSnapshot(logs.notice.map(([, m]) => m), 'logs pack contents') 71 t.ok(fs.statSync(path.resolve(npm.prefix, filename))) 72}) 73 74t.test('should log scoped package output as valid json', async t => { 75 const { npm, outputs, logs } = await loadMockNpm(t, { 76 prefixDir: { 77 'package.json': JSON.stringify({ 78 name: '@myscope/test-package', 79 version: '1.0.0', 80 }), 81 }, 82 config: { json: true }, 83 }) 84 await npm.exec('pack', []) 85 const filename = 'myscope-test-package-1.0.0.tgz' 86 t.matchSnapshot(outputs.map(JSON.parse), 'outputs as json') 87 t.matchSnapshot(logs.notice.map(([, m]) => m), 'logs pack contents') 88 t.ok(fs.statSync(path.resolve(npm.prefix, filename))) 89}) 90 91t.test('dry run', async t => { 92 const { npm, outputs, logs } = await loadMockNpm(t, { 93 prefixDir: { 94 'package.json': JSON.stringify({ 95 name: 'test-package', 96 version: '1.0.0', 97 }), 98 }, 99 config: { 'dry-run': true }, 100 }) 101 await npm.exec('pack', []) 102 const filename = 'test-package-1.0.0.tgz' 103 t.strictSame(outputs, [[filename]]) 104 t.matchSnapshot(logs.notice.map(([, m]) => m), 'logs pack contents') 105 t.throws(() => fs.statSync(path.resolve(npm.prefix, filename))) 106}) 107 108t.test('foreground-scripts defaults to true', async t => { 109 const { npm, outputs, logs } = await loadMockNpm(t, { 110 prefixDir: { 111 'package.json': JSON.stringify({ 112 name: 'test-fg-scripts', 113 version: '0.0.0', 114 scripts: { 115 prepack: 'echo prepack!', 116 postpack: 'echo postpack!', 117 }, 118 } 119 ), 120 }, 121 config: { 'dry-run': true }, 122 }) 123 124 /* eslint no-console: 0 */ 125 // TODO: replace this with `const results = t.intercept(console, 'log')` 126 const log = console.log 127 t.teardown(() => { 128 console.log = log 129 }) 130 const caughtLogs = [] 131 console.log = (...args) => { 132 caughtLogs.push(args) 133 } 134 // end TODO 135 136 await npm.exec('pack', []) 137 const filename = 'test-fg-scripts-0.0.0.tgz' 138 t.same( 139 caughtLogs, 140 [ 141 ['\n> test-fg-scripts@0.0.0 prepack\n> echo prepack!\n'], 142 ['\n> test-fg-scripts@0.0.0 postpack\n> echo postpack!\n'], 143 ], 144 'prepack and postpack log to stdout') 145 t.strictSame(outputs, [[filename]]) 146 t.matchSnapshot(logs.notice.map(([, m]) => m), 'logs pack contents') 147 t.throws(() => fs.statSync(path.resolve(npm.prefix, filename))) 148}) 149 150t.test('foreground-scripts can still be set to false', async t => { 151 const { npm, outputs, logs } = await loadMockNpm(t, { 152 prefixDir: { 153 'package.json': JSON.stringify({ 154 name: 'test-fg-scripts', 155 version: '0.0.0', 156 scripts: { 157 prepack: 'echo prepack!', 158 postpack: 'echo postpack!', 159 }, 160 } 161 ), 162 }, 163 config: { 'dry-run': true, 'foreground-scripts': false }, 164 }) 165 166 /* eslint no-console: 0 */ 167 // TODO: replace this with `const results = t.intercept(console, 'log')` 168 const log = console.log 169 t.teardown(() => { 170 console.log = log 171 }) 172 const caughtLogs = [] 173 console.log = (...args) => { 174 caughtLogs.push(args) 175 } 176 // end TODO 177 178 await npm.exec('pack', []) 179 const filename = 'test-fg-scripts-0.0.0.tgz' 180 t.same( 181 caughtLogs, 182 [], 183 'prepack and postpack do not log to stdout') 184 t.strictSame(outputs, [[filename]]) 185 t.matchSnapshot(logs.notice.map(([, m]) => m), 'logs pack contents') 186 t.throws(() => fs.statSync(path.resolve(npm.prefix, filename))) 187}) 188 189t.test('invalid packument', async t => { 190 const { npm, outputs } = await loadMockNpm(t, { 191 prefixDir: { 192 'package.json': '{}', 193 }, 194 }) 195 await t.rejects( 196 npm.exec('pack', []), 197 /Invalid package, must have name and version/ 198 ) 199 t.strictSame(outputs, []) 200}) 201 202t.test('workspaces', async t => { 203 const loadWorkspaces = (t) => loadMockNpm(t, { 204 prefixDir: { 205 'package.json': JSON.stringify( 206 { 207 name: 'workspaces-test', 208 version: '1.0.0', 209 workspaces: ['workspace-a', 'workspace-b'], 210 }, 211 null, 212 2 213 ), 214 'workspace-a': { 215 'package.json': JSON.stringify({ 216 name: 'workspace-a', 217 version: '1.0.0', 218 }), 219 }, 220 'workspace-b': { 221 'package.json': JSON.stringify({ 222 name: 'workspace-b', 223 version: '1.0.0', 224 }), 225 }, 226 }, 227 config: { 228 workspaces: true, 229 // TODO: this is a workaround for npm run test-all 230 // somehow leaking include-workspace-root 231 'include-workspace-root': false, 232 }, 233 }) 234 235 t.test('all workspaces', async t => { 236 const { npm, outputs } = await loadWorkspaces(t) 237 await npm.exec('pack', []) 238 t.strictSame(outputs, [['workspace-a-1.0.0.tgz'], ['workspace-b-1.0.0.tgz']]) 239 }) 240 241 t.test('all workspaces, `.` first arg', async t => { 242 const { npm, outputs } = await loadWorkspaces(t) 243 await npm.exec('pack', ['.']) 244 t.strictSame(outputs, [['workspace-a-1.0.0.tgz'], ['workspace-b-1.0.0.tgz']]) 245 }) 246 247 t.test('one workspace', async t => { 248 const { npm, outputs } = await loadWorkspaces(t) 249 await npm.exec('pack', ['workspace-a']) 250 t.strictSame(outputs, [['workspace-a-1.0.0.tgz']]) 251 }) 252 253 t.test('specific package', async t => { 254 const { npm, outputs } = await loadWorkspaces(t) 255 await npm.exec('pack', [npm.prefix]) 256 t.strictSame(outputs, [['workspaces-test-1.0.0.tgz']]) 257 }) 258}) 259