11cb0ef41Sopenharmony_ciconst t = require('tap') 21cb0ef41Sopenharmony_ciconst { resolve, dirname, join } = require('path') 31cb0ef41Sopenharmony_ciconst fs = require('fs') 41cb0ef41Sopenharmony_ciconst { load: loadMockNpm } = require('../fixtures/mock-npm.js') 51cb0ef41Sopenharmony_ciconst mockGlobals = require('@npmcli/mock-globals') 61cb0ef41Sopenharmony_ciconst { commands } = require('../../lib/utils/cmd-list.js') 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_cit.test('not yet loaded', async t => { 91cb0ef41Sopenharmony_ci const { npm, logs } = await loadMockNpm(t, { load: false }) 101cb0ef41Sopenharmony_ci t.match(npm, { 111cb0ef41Sopenharmony_ci started: Number, 121cb0ef41Sopenharmony_ci command: null, 131cb0ef41Sopenharmony_ci config: { 141cb0ef41Sopenharmony_ci loaded: false, 151cb0ef41Sopenharmony_ci get: Function, 161cb0ef41Sopenharmony_ci set: Function, 171cb0ef41Sopenharmony_ci }, 181cb0ef41Sopenharmony_ci version: String, 191cb0ef41Sopenharmony_ci }) 201cb0ef41Sopenharmony_ci t.throws(() => npm.config.set('foo', 'bar')) 211cb0ef41Sopenharmony_ci t.throws(() => npm.config.get('foo')) 221cb0ef41Sopenharmony_ci t.same(logs, []) 231cb0ef41Sopenharmony_ci}) 241cb0ef41Sopenharmony_ci 251cb0ef41Sopenharmony_cit.test('npm.load', async t => { 261cb0ef41Sopenharmony_ci await t.test('load error', async t => { 271cb0ef41Sopenharmony_ci const { npm } = await loadMockNpm(t, { load: false }) 281cb0ef41Sopenharmony_ci const loadError = new Error('load error') 291cb0ef41Sopenharmony_ci npm.config.load = async () => { 301cb0ef41Sopenharmony_ci throw loadError 311cb0ef41Sopenharmony_ci } 321cb0ef41Sopenharmony_ci await t.rejects( 331cb0ef41Sopenharmony_ci () => npm.load(), 341cb0ef41Sopenharmony_ci /load error/ 351cb0ef41Sopenharmony_ci ) 361cb0ef41Sopenharmony_ci 371cb0ef41Sopenharmony_ci t.equal(npm.loadErr, loadError) 381cb0ef41Sopenharmony_ci npm.config.load = async () => { 391cb0ef41Sopenharmony_ci throw new Error('different error') 401cb0ef41Sopenharmony_ci } 411cb0ef41Sopenharmony_ci await t.rejects( 421cb0ef41Sopenharmony_ci () => npm.load(), 431cb0ef41Sopenharmony_ci /load error/, 441cb0ef41Sopenharmony_ci 'loading again returns the original error' 451cb0ef41Sopenharmony_ci ) 461cb0ef41Sopenharmony_ci t.equal(npm.loadErr, loadError) 471cb0ef41Sopenharmony_ci }) 481cb0ef41Sopenharmony_ci 491cb0ef41Sopenharmony_ci await t.test('basic loading', async t => { 501cb0ef41Sopenharmony_ci const { npm, logs, prefix: dir, cache, other } = await loadMockNpm(t, { 511cb0ef41Sopenharmony_ci prefixDir: { node_modules: {} }, 521cb0ef41Sopenharmony_ci otherDirs: { 531cb0ef41Sopenharmony_ci newCache: {}, 541cb0ef41Sopenharmony_ci }, 551cb0ef41Sopenharmony_ci }) 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_ci t.equal(npm.loaded, true) 581cb0ef41Sopenharmony_ci t.equal(npm.config.loaded, true) 591cb0ef41Sopenharmony_ci t.equal(npm.config.get('force'), false) 601cb0ef41Sopenharmony_ci t.ok(npm.usage, 'has usage') 611cb0ef41Sopenharmony_ci 621cb0ef41Sopenharmony_ci t.match(npm, { 631cb0ef41Sopenharmony_ci flatOptions: {}, 641cb0ef41Sopenharmony_ci }) 651cb0ef41Sopenharmony_ci t.match(logs.timing.filter(([p]) => p === 'npm:load'), [ 661cb0ef41Sopenharmony_ci ['npm:load', /Completed in [0-9.]+ms/], 671cb0ef41Sopenharmony_ci ]) 681cb0ef41Sopenharmony_ci 691cb0ef41Sopenharmony_ci mockGlobals(t, { process: { platform: 'posix' } }) 701cb0ef41Sopenharmony_ci t.equal(resolve(npm.cache), resolve(cache), 'cache is cache') 711cb0ef41Sopenharmony_ci npm.cache = other.newCache 721cb0ef41Sopenharmony_ci t.equal(npm.config.get('cache'), other.newCache, 'cache setter sets config') 731cb0ef41Sopenharmony_ci t.equal(npm.cache, other.newCache, 'cache getter gets new config') 741cb0ef41Sopenharmony_ci t.equal(npm.lockfileVersion, 2, 'lockfileVersion getter') 751cb0ef41Sopenharmony_ci t.equal(npm.prefix, npm.localPrefix, 'prefix is local prefix') 761cb0ef41Sopenharmony_ci t.not(npm.prefix, npm.globalPrefix, 'prefix is not global prefix') 771cb0ef41Sopenharmony_ci npm.globalPrefix = npm.prefix 781cb0ef41Sopenharmony_ci t.equal(npm.prefix, npm.globalPrefix, 'globalPrefix setter') 791cb0ef41Sopenharmony_ci npm.localPrefix = dir + '/extra/prefix' 801cb0ef41Sopenharmony_ci t.equal(npm.prefix, npm.localPrefix, 'prefix is local prefix after localPrefix setter') 811cb0ef41Sopenharmony_ci t.not(npm.prefix, npm.globalPrefix, 'prefix is not global prefix after localPrefix setter') 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ci npm.prefix = dir + '/some/prefix' 841cb0ef41Sopenharmony_ci t.equal(npm.prefix, npm.localPrefix, 'prefix is local prefix after prefix setter') 851cb0ef41Sopenharmony_ci t.not(npm.prefix, npm.globalPrefix, 'prefix is not global prefix after prefix setter') 861cb0ef41Sopenharmony_ci t.equal(npm.bin, npm.localBin, 'bin is local bin after prefix setter') 871cb0ef41Sopenharmony_ci t.not(npm.bin, npm.globalBin, 'bin is not global bin after prefix setter') 881cb0ef41Sopenharmony_ci t.equal(npm.dir, npm.localDir, 'dir is local dir after prefix setter') 891cb0ef41Sopenharmony_ci t.not(npm.dir, npm.globalDir, 'dir is not global dir after prefix setter') 901cb0ef41Sopenharmony_ci 911cb0ef41Sopenharmony_ci npm.config.set('global', true) 921cb0ef41Sopenharmony_ci t.equal(npm.prefix, npm.globalPrefix, 'prefix is global prefix after setting global') 931cb0ef41Sopenharmony_ci t.not(npm.prefix, npm.localPrefix, 'prefix is not local prefix after setting global') 941cb0ef41Sopenharmony_ci t.equal(npm.bin, npm.globalBin, 'bin is global bin after setting global') 951cb0ef41Sopenharmony_ci t.not(npm.bin, npm.localBin, 'bin is not local bin after setting global') 961cb0ef41Sopenharmony_ci t.equal(npm.dir, npm.globalDir, 'dir is global dir after setting global') 971cb0ef41Sopenharmony_ci t.not(npm.dir, npm.localDir, 'dir is not local dir after setting global') 981cb0ef41Sopenharmony_ci 991cb0ef41Sopenharmony_ci npm.prefix = dir + '/new/global/prefix' 1001cb0ef41Sopenharmony_ci t.equal(npm.prefix, npm.globalPrefix, 'prefix is global prefix after prefix setter') 1011cb0ef41Sopenharmony_ci t.not(npm.prefix, npm.localPrefix, 'prefix is not local prefix after prefix setter') 1021cb0ef41Sopenharmony_ci t.equal(npm.bin, npm.globalBin, 'bin is global bin after prefix setter') 1031cb0ef41Sopenharmony_ci t.not(npm.bin, npm.localBin, 'bin is not local bin after prefix setter') 1041cb0ef41Sopenharmony_ci 1051cb0ef41Sopenharmony_ci mockGlobals(t, { process: { platform: 'win32' } }) 1061cb0ef41Sopenharmony_ci t.equal(npm.bin, npm.globalBin, 'bin is global bin in windows mode') 1071cb0ef41Sopenharmony_ci t.equal(npm.dir, npm.globalDir, 'dir is global dir in windows mode') 1081cb0ef41Sopenharmony_ci }) 1091cb0ef41Sopenharmony_ci 1101cb0ef41Sopenharmony_ci await t.test('forceful loading', async t => { 1111cb0ef41Sopenharmony_ci const { logs } = await loadMockNpm(t, { 1121cb0ef41Sopenharmony_ci globals: { 1131cb0ef41Sopenharmony_ci 'process.argv': [...process.argv, '--force', '--color', 'always'], 1141cb0ef41Sopenharmony_ci }, 1151cb0ef41Sopenharmony_ci }) 1161cb0ef41Sopenharmony_ci t.match(logs.warn, [ 1171cb0ef41Sopenharmony_ci [ 1181cb0ef41Sopenharmony_ci 'using --force', 1191cb0ef41Sopenharmony_ci 'Recommended protections disabled.', 1201cb0ef41Sopenharmony_ci ], 1211cb0ef41Sopenharmony_ci ]) 1221cb0ef41Sopenharmony_ci }) 1231cb0ef41Sopenharmony_ci 1241cb0ef41Sopenharmony_ci await t.test('node is a symlink', async t => { 1251cb0ef41Sopenharmony_ci const node = process.platform === 'win32' ? 'node.exe' : 'node' 1261cb0ef41Sopenharmony_ci const { Npm, npm, logs, outputs, prefix } = await loadMockNpm(t, { 1271cb0ef41Sopenharmony_ci prefixDir: { 1281cb0ef41Sopenharmony_ci bin: t.fixture('symlink', dirname(process.execPath)), 1291cb0ef41Sopenharmony_ci }, 1301cb0ef41Sopenharmony_ci globals: (dirs) => ({ 1311cb0ef41Sopenharmony_ci 'process.env.PATH': resolve(dirs.prefix, 'bin'), 1321cb0ef41Sopenharmony_ci 'process.argv': [ 1331cb0ef41Sopenharmony_ci node, 1341cb0ef41Sopenharmony_ci process.argv[1], 1351cb0ef41Sopenharmony_ci '--usage', 1361cb0ef41Sopenharmony_ci '--scope=foo', 1371cb0ef41Sopenharmony_ci 'token', 1381cb0ef41Sopenharmony_ci 'revoke', 1391cb0ef41Sopenharmony_ci 'blergggg', 1401cb0ef41Sopenharmony_ci ], 1411cb0ef41Sopenharmony_ci }), 1421cb0ef41Sopenharmony_ci }) 1431cb0ef41Sopenharmony_ci 1441cb0ef41Sopenharmony_ci t.equal(npm.config.get('scope'), '@foo', 'added the @ sign to scope') 1451cb0ef41Sopenharmony_ci t.match([ 1461cb0ef41Sopenharmony_ci ...logs.timing.filter(([p]) => p === 'npm:load:whichnode'), 1471cb0ef41Sopenharmony_ci ...logs.verbose, 1481cb0ef41Sopenharmony_ci ...logs.timing.filter(([p]) => p === 'npm:load'), 1491cb0ef41Sopenharmony_ci ], [ 1501cb0ef41Sopenharmony_ci ['npm:load:whichnode', /Completed in [0-9.]+ms/], 1511cb0ef41Sopenharmony_ci ['node symlink', resolve(prefix, 'bin', node)], 1521cb0ef41Sopenharmony_ci ['title', 'npm token revoke blergggg'], 1531cb0ef41Sopenharmony_ci ['argv', '"--usage" "--scope" "foo" "token" "revoke" "blergggg"'], 1541cb0ef41Sopenharmony_ci ['logfile', /logs-max:\d+ dir:.*/], 1551cb0ef41Sopenharmony_ci ['logfile', /.*-debug-0.log/], 1561cb0ef41Sopenharmony_ci ['npm:load', /Completed in [0-9.]+ms/], 1571cb0ef41Sopenharmony_ci ]) 1581cb0ef41Sopenharmony_ci t.equal(process.execPath, resolve(prefix, 'bin', node)) 1591cb0ef41Sopenharmony_ci 1601cb0ef41Sopenharmony_ci outputs.length = 0 1611cb0ef41Sopenharmony_ci logs.length = 0 1621cb0ef41Sopenharmony_ci await npm.exec('ll', []) 1631cb0ef41Sopenharmony_ci 1641cb0ef41Sopenharmony_ci t.equal(npm.command, 'll', 'command set to first npm command') 1651cb0ef41Sopenharmony_ci t.equal(npm.flatOptions.npmCommand, 'll', 'npmCommand flatOption set') 1661cb0ef41Sopenharmony_ci 1671cb0ef41Sopenharmony_ci const ll = Npm.cmd('ll') 1681cb0ef41Sopenharmony_ci t.same(outputs, [[ll.describeUsage]], 'print usage') 1691cb0ef41Sopenharmony_ci npm.config.set('usage', false) 1701cb0ef41Sopenharmony_ci 1711cb0ef41Sopenharmony_ci outputs.length = 0 1721cb0ef41Sopenharmony_ci logs.length = 0 1731cb0ef41Sopenharmony_ci await npm.exec('get', ['scope', '\u2010not-a-dash']) 1741cb0ef41Sopenharmony_ci 1751cb0ef41Sopenharmony_ci t.strictSame([npm.command, npm.flatOptions.npmCommand], ['ll', 'll'], 1761cb0ef41Sopenharmony_ci 'does not change npm.command when another command is called') 1771cb0ef41Sopenharmony_ci 1781cb0ef41Sopenharmony_ci t.match(logs, [ 1791cb0ef41Sopenharmony_ci [ 1801cb0ef41Sopenharmony_ci 'error', 1811cb0ef41Sopenharmony_ci 'arg', 1821cb0ef41Sopenharmony_ci 'Argument starts with non-ascii dash, this is probably invalid:', 1831cb0ef41Sopenharmony_ci '\u2010not-a-dash', 1841cb0ef41Sopenharmony_ci ], 1851cb0ef41Sopenharmony_ci [ 1861cb0ef41Sopenharmony_ci 'timing', 1871cb0ef41Sopenharmony_ci 'command:config', 1881cb0ef41Sopenharmony_ci /Completed in [0-9.]+ms/, 1891cb0ef41Sopenharmony_ci ], 1901cb0ef41Sopenharmony_ci [ 1911cb0ef41Sopenharmony_ci 'timing', 1921cb0ef41Sopenharmony_ci 'command:get', 1931cb0ef41Sopenharmony_ci /Completed in [0-9.]+ms/, 1941cb0ef41Sopenharmony_ci ], 1951cb0ef41Sopenharmony_ci ]) 1961cb0ef41Sopenharmony_ci t.same(outputs, [['scope=@foo\n\u2010not-a-dash=undefined']]) 1971cb0ef41Sopenharmony_ci }) 1981cb0ef41Sopenharmony_ci 1991cb0ef41Sopenharmony_ci await t.test('--no-workspaces with --workspace', async t => { 2001cb0ef41Sopenharmony_ci const { npm } = await loadMockNpm(t, { 2011cb0ef41Sopenharmony_ci prefixDir: { 2021cb0ef41Sopenharmony_ci packages: { 2031cb0ef41Sopenharmony_ci a: { 2041cb0ef41Sopenharmony_ci 'package.json': JSON.stringify({ 2051cb0ef41Sopenharmony_ci name: 'a', 2061cb0ef41Sopenharmony_ci version: '1.0.0', 2071cb0ef41Sopenharmony_ci scripts: { test: 'echo test a' }, 2081cb0ef41Sopenharmony_ci }), 2091cb0ef41Sopenharmony_ci }, 2101cb0ef41Sopenharmony_ci }, 2111cb0ef41Sopenharmony_ci 'package.json': JSON.stringify({ 2121cb0ef41Sopenharmony_ci name: 'root', 2131cb0ef41Sopenharmony_ci version: '1.0.0', 2141cb0ef41Sopenharmony_ci workspaces: ['./packages/*'], 2151cb0ef41Sopenharmony_ci }), 2161cb0ef41Sopenharmony_ci }, 2171cb0ef41Sopenharmony_ci globals: { 2181cb0ef41Sopenharmony_ci 'process.argv': [ 2191cb0ef41Sopenharmony_ci process.execPath, 2201cb0ef41Sopenharmony_ci process.argv[1], 2211cb0ef41Sopenharmony_ci '--color', 'false', 2221cb0ef41Sopenharmony_ci '--workspaces', 'false', 2231cb0ef41Sopenharmony_ci '--workspace', 'a', 2241cb0ef41Sopenharmony_ci ], 2251cb0ef41Sopenharmony_ci }, 2261cb0ef41Sopenharmony_ci }) 2271cb0ef41Sopenharmony_ci await t.rejects( 2281cb0ef41Sopenharmony_ci npm.exec('run', []), 2291cb0ef41Sopenharmony_ci /Can not use --no-workspaces and --workspace at the same time/ 2301cb0ef41Sopenharmony_ci ) 2311cb0ef41Sopenharmony_ci }) 2321cb0ef41Sopenharmony_ci 2331cb0ef41Sopenharmony_ci await t.test('workspace-aware configs and commands', async t => { 2341cb0ef41Sopenharmony_ci const { npm, outputs } = await loadMockNpm(t, { 2351cb0ef41Sopenharmony_ci prefixDir: { 2361cb0ef41Sopenharmony_ci packages: { 2371cb0ef41Sopenharmony_ci a: { 2381cb0ef41Sopenharmony_ci 'package.json': JSON.stringify({ 2391cb0ef41Sopenharmony_ci name: 'a', 2401cb0ef41Sopenharmony_ci version: '1.0.0', 2411cb0ef41Sopenharmony_ci scripts: { test: 'echo test a' }, 2421cb0ef41Sopenharmony_ci }), 2431cb0ef41Sopenharmony_ci }, 2441cb0ef41Sopenharmony_ci b: { 2451cb0ef41Sopenharmony_ci 'package.json': JSON.stringify({ 2461cb0ef41Sopenharmony_ci name: 'b', 2471cb0ef41Sopenharmony_ci version: '1.0.0', 2481cb0ef41Sopenharmony_ci scripts: { test: 'echo test b' }, 2491cb0ef41Sopenharmony_ci }), 2501cb0ef41Sopenharmony_ci }, 2511cb0ef41Sopenharmony_ci }, 2521cb0ef41Sopenharmony_ci 'package.json': JSON.stringify({ 2531cb0ef41Sopenharmony_ci name: 'root', 2541cb0ef41Sopenharmony_ci version: '1.0.0', 2551cb0ef41Sopenharmony_ci workspaces: ['./packages/*'], 2561cb0ef41Sopenharmony_ci }), 2571cb0ef41Sopenharmony_ci }, 2581cb0ef41Sopenharmony_ci globals: { 2591cb0ef41Sopenharmony_ci 'process.argv': [ 2601cb0ef41Sopenharmony_ci process.execPath, 2611cb0ef41Sopenharmony_ci process.argv[1], 2621cb0ef41Sopenharmony_ci '--color', 'false', 2631cb0ef41Sopenharmony_ci '--workspaces', 'true', 2641cb0ef41Sopenharmony_ci ], 2651cb0ef41Sopenharmony_ci }, 2661cb0ef41Sopenharmony_ci }) 2671cb0ef41Sopenharmony_ci 2681cb0ef41Sopenharmony_ci await npm.exec('run', []) 2691cb0ef41Sopenharmony_ci 2701cb0ef41Sopenharmony_ci t.equal(npm.command, 'run-script', 'npm.command set to canonical name') 2711cb0ef41Sopenharmony_ci 2721cb0ef41Sopenharmony_ci t.match( 2731cb0ef41Sopenharmony_ci outputs, 2741cb0ef41Sopenharmony_ci [ 2751cb0ef41Sopenharmony_ci ['Lifecycle scripts included in a@1.0.0:'], 2761cb0ef41Sopenharmony_ci [' test\n echo test a'], 2771cb0ef41Sopenharmony_ci [''], 2781cb0ef41Sopenharmony_ci ['Lifecycle scripts included in b@1.0.0:'], 2791cb0ef41Sopenharmony_ci [' test\n echo test b'], 2801cb0ef41Sopenharmony_ci [''], 2811cb0ef41Sopenharmony_ci ], 2821cb0ef41Sopenharmony_ci 'should exec workspaces version of commands' 2831cb0ef41Sopenharmony_ci ) 2841cb0ef41Sopenharmony_ci }) 2851cb0ef41Sopenharmony_ci 2861cb0ef41Sopenharmony_ci await t.test('workspaces in global mode', async t => { 2871cb0ef41Sopenharmony_ci const { npm } = await loadMockNpm(t, { 2881cb0ef41Sopenharmony_ci prefixDir: { 2891cb0ef41Sopenharmony_ci packages: { 2901cb0ef41Sopenharmony_ci a: { 2911cb0ef41Sopenharmony_ci 'package.json': JSON.stringify({ 2921cb0ef41Sopenharmony_ci name: 'a', 2931cb0ef41Sopenharmony_ci version: '1.0.0', 2941cb0ef41Sopenharmony_ci scripts: { test: 'echo test a' }, 2951cb0ef41Sopenharmony_ci }), 2961cb0ef41Sopenharmony_ci }, 2971cb0ef41Sopenharmony_ci b: { 2981cb0ef41Sopenharmony_ci 'package.json': JSON.stringify({ 2991cb0ef41Sopenharmony_ci name: 'b', 3001cb0ef41Sopenharmony_ci version: '1.0.0', 3011cb0ef41Sopenharmony_ci scripts: { test: 'echo test b' }, 3021cb0ef41Sopenharmony_ci }), 3031cb0ef41Sopenharmony_ci }, 3041cb0ef41Sopenharmony_ci }, 3051cb0ef41Sopenharmony_ci 'package.json': JSON.stringify({ 3061cb0ef41Sopenharmony_ci name: 'root', 3071cb0ef41Sopenharmony_ci version: '1.0.0', 3081cb0ef41Sopenharmony_ci workspaces: ['./packages/*'], 3091cb0ef41Sopenharmony_ci }), 3101cb0ef41Sopenharmony_ci }, 3111cb0ef41Sopenharmony_ci globals: { 3121cb0ef41Sopenharmony_ci 'process.argv': [ 3131cb0ef41Sopenharmony_ci process.execPath, 3141cb0ef41Sopenharmony_ci process.argv[1], 3151cb0ef41Sopenharmony_ci '--color', 3161cb0ef41Sopenharmony_ci 'false', 3171cb0ef41Sopenharmony_ci '--workspaces', 3181cb0ef41Sopenharmony_ci '--global', 3191cb0ef41Sopenharmony_ci 'true', 3201cb0ef41Sopenharmony_ci ], 3211cb0ef41Sopenharmony_ci }, 3221cb0ef41Sopenharmony_ci }) 3231cb0ef41Sopenharmony_ci 3241cb0ef41Sopenharmony_ci await t.rejects( 3251cb0ef41Sopenharmony_ci npm.exec('run', []), 3261cb0ef41Sopenharmony_ci /Workspaces not supported for global packages/ 3271cb0ef41Sopenharmony_ci ) 3281cb0ef41Sopenharmony_ci }) 3291cb0ef41Sopenharmony_ci}) 3301cb0ef41Sopenharmony_ci 3311cb0ef41Sopenharmony_cit.test('set process.title', async t => { 3321cb0ef41Sopenharmony_ci t.test('basic title setting', async t => { 3331cb0ef41Sopenharmony_ci const { npm } = await loadMockNpm(t, { 3341cb0ef41Sopenharmony_ci globals: { 3351cb0ef41Sopenharmony_ci 'process.argv': [ 3361cb0ef41Sopenharmony_ci process.execPath, 3371cb0ef41Sopenharmony_ci process.argv[1], 3381cb0ef41Sopenharmony_ci '--usage', 3391cb0ef41Sopenharmony_ci '--scope=foo', 3401cb0ef41Sopenharmony_ci 'ls', 3411cb0ef41Sopenharmony_ci ], 3421cb0ef41Sopenharmony_ci }, 3431cb0ef41Sopenharmony_ci }) 3441cb0ef41Sopenharmony_ci t.equal(npm.title, 'npm ls') 3451cb0ef41Sopenharmony_ci t.equal(process.title, 'npm ls') 3461cb0ef41Sopenharmony_ci }) 3471cb0ef41Sopenharmony_ci 3481cb0ef41Sopenharmony_ci t.test('do not expose token being revoked', async t => { 3491cb0ef41Sopenharmony_ci const { npm } = await loadMockNpm(t, { 3501cb0ef41Sopenharmony_ci globals: { 3511cb0ef41Sopenharmony_ci 'process.argv': [ 3521cb0ef41Sopenharmony_ci process.execPath, 3531cb0ef41Sopenharmony_ci process.argv[1], 3541cb0ef41Sopenharmony_ci '--usage', 3551cb0ef41Sopenharmony_ci '--scope=foo', 3561cb0ef41Sopenharmony_ci 'token', 3571cb0ef41Sopenharmony_ci 'revoke', 3581cb0ef41Sopenharmony_ci `npm_${'a'.repeat(36)}`, 3591cb0ef41Sopenharmony_ci ], 3601cb0ef41Sopenharmony_ci }, 3611cb0ef41Sopenharmony_ci }) 3621cb0ef41Sopenharmony_ci t.equal(npm.title, 'npm token revoke npm_***') 3631cb0ef41Sopenharmony_ci t.equal(process.title, 'npm token revoke npm_***') 3641cb0ef41Sopenharmony_ci }) 3651cb0ef41Sopenharmony_ci 3661cb0ef41Sopenharmony_ci t.test('do show *** unless a token is actually being revoked', async t => { 3671cb0ef41Sopenharmony_ci const { npm } = await loadMockNpm(t, { 3681cb0ef41Sopenharmony_ci globals: { 3691cb0ef41Sopenharmony_ci 'process.argv': [ 3701cb0ef41Sopenharmony_ci process.execPath, 3711cb0ef41Sopenharmony_ci process.argv[1], 3721cb0ef41Sopenharmony_ci '--usage', 3731cb0ef41Sopenharmony_ci '--scope=foo', 3741cb0ef41Sopenharmony_ci 'token', 3751cb0ef41Sopenharmony_ci 'revoke', 3761cb0ef41Sopenharmony_ci 'notatoken', 3771cb0ef41Sopenharmony_ci ], 3781cb0ef41Sopenharmony_ci }, 3791cb0ef41Sopenharmony_ci }) 3801cb0ef41Sopenharmony_ci t.equal(npm.title, 'npm token revoke notatoken') 3811cb0ef41Sopenharmony_ci t.equal(process.title, 'npm token revoke notatoken') 3821cb0ef41Sopenharmony_ci }) 3831cb0ef41Sopenharmony_ci}) 3841cb0ef41Sopenharmony_ci 3851cb0ef41Sopenharmony_cit.test('debug log', async t => { 3861cb0ef41Sopenharmony_ci t.test('writes log file', async t => { 3871cb0ef41Sopenharmony_ci const { npm, debugFile } = await loadMockNpm(t, { load: false }) 3881cb0ef41Sopenharmony_ci 3891cb0ef41Sopenharmony_ci const log1 = ['silly', 'test', 'before load'] 3901cb0ef41Sopenharmony_ci const log2 = ['silly', 'test', 'after load'] 3911cb0ef41Sopenharmony_ci const log3 = ['silly', 'test', 'hello\x00world'] 3921cb0ef41Sopenharmony_ci 3931cb0ef41Sopenharmony_ci process.emit('log', ...log1) 3941cb0ef41Sopenharmony_ci await npm.load() 3951cb0ef41Sopenharmony_ci process.emit('log', ...log2) 3961cb0ef41Sopenharmony_ci process.emit('log', ...log3) 3971cb0ef41Sopenharmony_ci 3981cb0ef41Sopenharmony_ci const debug = await debugFile() 3991cb0ef41Sopenharmony_ci t.equal(npm.logFiles.length, 1, 'one debug file') 4001cb0ef41Sopenharmony_ci t.match(debug, log1.join(' '), 'before load appears') 4011cb0ef41Sopenharmony_ci t.match(debug, log2.join(' '), 'after load log appears') 4021cb0ef41Sopenharmony_ci t.match(debug, 'hello^@world') 4031cb0ef41Sopenharmony_ci }) 4041cb0ef41Sopenharmony_ci 4051cb0ef41Sopenharmony_ci t.test('can load with bad dir', async t => { 4061cb0ef41Sopenharmony_ci const { npm, testdir } = await loadMockNpm(t, { 4071cb0ef41Sopenharmony_ci load: false, 4081cb0ef41Sopenharmony_ci config: (dirs) => ({ 4091cb0ef41Sopenharmony_ci 'logs-dir': join(dirs.testdir, 'my_logs_dir'), 4101cb0ef41Sopenharmony_ci }), 4111cb0ef41Sopenharmony_ci }) 4121cb0ef41Sopenharmony_ci const logsDir = join(testdir, 'my_logs_dir') 4131cb0ef41Sopenharmony_ci 4141cb0ef41Sopenharmony_ci // make logs dir a file before load so it files 4151cb0ef41Sopenharmony_ci fs.writeFileSync(logsDir, 'A_TEXT_FILE') 4161cb0ef41Sopenharmony_ci await t.resolves(npm.load(), 'loads with invalid logs dir') 4171cb0ef41Sopenharmony_ci 4181cb0ef41Sopenharmony_ci t.equal(npm.logFiles.length, 0, 'no log files array') 4191cb0ef41Sopenharmony_ci t.strictSame(fs.readFileSync(logsDir, 'utf-8'), 'A_TEXT_FILE') 4201cb0ef41Sopenharmony_ci }) 4211cb0ef41Sopenharmony_ci}) 4221cb0ef41Sopenharmony_ci 4231cb0ef41Sopenharmony_cit.test('cache dir', async t => { 4241cb0ef41Sopenharmony_ci t.test('creates a cache dir', async t => { 4251cb0ef41Sopenharmony_ci const { npm } = await loadMockNpm(t) 4261cb0ef41Sopenharmony_ci 4271cb0ef41Sopenharmony_ci t.ok(fs.existsSync(npm.cache), 'cache dir exists') 4281cb0ef41Sopenharmony_ci }) 4291cb0ef41Sopenharmony_ci 4301cb0ef41Sopenharmony_ci t.test('can load with a bad cache dir', async t => { 4311cb0ef41Sopenharmony_ci const { npm, cache } = await loadMockNpm(t, { 4321cb0ef41Sopenharmony_ci load: false, 4331cb0ef41Sopenharmony_ci // The easiest way to make mkdir(cache) fail is to make it a file. 4341cb0ef41Sopenharmony_ci // This will have the same effect as if its read only or inaccessible. 4351cb0ef41Sopenharmony_ci cacheDir: 'A_TEXT_FILE', 4361cb0ef41Sopenharmony_ci }) 4371cb0ef41Sopenharmony_ci 4381cb0ef41Sopenharmony_ci await t.resolves(npm.load(), 'loads with cache dir as a file') 4391cb0ef41Sopenharmony_ci 4401cb0ef41Sopenharmony_ci t.equal(fs.readFileSync(cache, 'utf-8'), 'A_TEXT_FILE') 4411cb0ef41Sopenharmony_ci }) 4421cb0ef41Sopenharmony_ci}) 4431cb0ef41Sopenharmony_ci 4441cb0ef41Sopenharmony_cit.test('timings', async t => { 4451cb0ef41Sopenharmony_ci t.test('gets/sets timers', async t => { 4461cb0ef41Sopenharmony_ci const { npm, logs } = await loadMockNpm(t, { load: false }) 4471cb0ef41Sopenharmony_ci process.emit('time', 'foo') 4481cb0ef41Sopenharmony_ci process.emit('time', 'bar') 4491cb0ef41Sopenharmony_ci t.match(npm.unfinishedTimers.get('foo'), Number, 'foo timer is a number') 4501cb0ef41Sopenharmony_ci t.match(npm.unfinishedTimers.get('bar'), Number, 'foo timer is a number') 4511cb0ef41Sopenharmony_ci process.emit('timeEnd', 'foo') 4521cb0ef41Sopenharmony_ci process.emit('timeEnd', 'bar') 4531cb0ef41Sopenharmony_ci process.emit('timeEnd', 'baz') 4541cb0ef41Sopenharmony_ci // npm timer is started by default 4551cb0ef41Sopenharmony_ci process.emit('timeEnd', 'npm') 4561cb0ef41Sopenharmony_ci t.match(logs.timing, [ 4571cb0ef41Sopenharmony_ci ['foo', /Completed in [0-9]+ms/], 4581cb0ef41Sopenharmony_ci ['bar', /Completed in [0-9]+ms/], 4591cb0ef41Sopenharmony_ci ['npm', /Completed in [0-9]+ms/], 4601cb0ef41Sopenharmony_ci ]) 4611cb0ef41Sopenharmony_ci t.match(logs.silly, [[ 4621cb0ef41Sopenharmony_ci 'timing', 4631cb0ef41Sopenharmony_ci "Tried to end timer that doesn't exist:", 4641cb0ef41Sopenharmony_ci 'baz', 4651cb0ef41Sopenharmony_ci ]]) 4661cb0ef41Sopenharmony_ci t.notOk(npm.unfinishedTimers.has('foo'), 'foo timer is gone') 4671cb0ef41Sopenharmony_ci t.notOk(npm.unfinishedTimers.has('bar'), 'bar timer is gone') 4681cb0ef41Sopenharmony_ci t.match(npm.finishedTimers, { foo: Number, bar: Number, npm: Number }) 4691cb0ef41Sopenharmony_ci }) 4701cb0ef41Sopenharmony_ci 4711cb0ef41Sopenharmony_ci t.test('writes timings file', async t => { 4721cb0ef41Sopenharmony_ci const { npm, cache, timingFile } = await loadMockNpm(t, { 4731cb0ef41Sopenharmony_ci config: { timing: true }, 4741cb0ef41Sopenharmony_ci }) 4751cb0ef41Sopenharmony_ci process.emit('time', 'foo') 4761cb0ef41Sopenharmony_ci process.emit('timeEnd', 'foo') 4771cb0ef41Sopenharmony_ci process.emit('time', 'bar') 4781cb0ef41Sopenharmony_ci npm.writeTimingFile() 4791cb0ef41Sopenharmony_ci t.match(npm.timingFile, cache) 4801cb0ef41Sopenharmony_ci t.match(npm.timingFile, /-timing.json$/) 4811cb0ef41Sopenharmony_ci const timings = await timingFile() 4821cb0ef41Sopenharmony_ci t.match(timings, { 4831cb0ef41Sopenharmony_ci metadata: { 4841cb0ef41Sopenharmony_ci command: [], 4851cb0ef41Sopenharmony_ci logfiles: [String], 4861cb0ef41Sopenharmony_ci version: String, 4871cb0ef41Sopenharmony_ci }, 4881cb0ef41Sopenharmony_ci unfinishedTimers: { 4891cb0ef41Sopenharmony_ci bar: [Number, Number], 4901cb0ef41Sopenharmony_ci npm: [Number, Number], 4911cb0ef41Sopenharmony_ci }, 4921cb0ef41Sopenharmony_ci timers: { 4931cb0ef41Sopenharmony_ci foo: Number, 4941cb0ef41Sopenharmony_ci 'npm:load': Number, 4951cb0ef41Sopenharmony_ci }, 4961cb0ef41Sopenharmony_ci }) 4971cb0ef41Sopenharmony_ci }) 4981cb0ef41Sopenharmony_ci 4991cb0ef41Sopenharmony_ci t.test('does not write timings file with timers:false', async t => { 5001cb0ef41Sopenharmony_ci const { npm, timingFile } = await loadMockNpm(t, { 5011cb0ef41Sopenharmony_ci config: { timing: false }, 5021cb0ef41Sopenharmony_ci }) 5031cb0ef41Sopenharmony_ci npm.writeTimingFile() 5041cb0ef41Sopenharmony_ci await t.rejects(() => timingFile()) 5051cb0ef41Sopenharmony_ci }) 5061cb0ef41Sopenharmony_ci 5071cb0ef41Sopenharmony_ci const timingDisplay = [ 5081cb0ef41Sopenharmony_ci [{ loglevel: 'silly' }, true, false], 5091cb0ef41Sopenharmony_ci [{ loglevel: 'silly', timing: true }, true, true], 5101cb0ef41Sopenharmony_ci [{ loglevel: 'silent', timing: true }, false, false], 5111cb0ef41Sopenharmony_ci ] 5121cb0ef41Sopenharmony_ci 5131cb0ef41Sopenharmony_ci for (const [config, expectedDisplay, expectedTiming] of timingDisplay) { 5141cb0ef41Sopenharmony_ci const msg = `${JSON.stringify(config)}, display:${expectedDisplay}, timing:${expectedTiming}` 5151cb0ef41Sopenharmony_ci await t.test(`timing display: ${msg}`, async t => { 5161cb0ef41Sopenharmony_ci const { display } = await loadMockNpm(t, { config }) 5171cb0ef41Sopenharmony_ci t.equal(!!display.length, expectedDisplay, 'display') 5181cb0ef41Sopenharmony_ci t.equal(!!display.timing.length, expectedTiming, 'timing display') 5191cb0ef41Sopenharmony_ci }) 5201cb0ef41Sopenharmony_ci } 5211cb0ef41Sopenharmony_ci}) 5221cb0ef41Sopenharmony_ci 5231cb0ef41Sopenharmony_cit.test('output clears progress and console.logs cleaned messages', async t => { 5241cb0ef41Sopenharmony_ci t.plan(4) 5251cb0ef41Sopenharmony_ci let showingProgress = true 5261cb0ef41Sopenharmony_ci const logs = [] 5271cb0ef41Sopenharmony_ci const errors = [] 5281cb0ef41Sopenharmony_ci const { npm } = await loadMockNpm(t, { 5291cb0ef41Sopenharmony_ci load: false, 5301cb0ef41Sopenharmony_ci mocks: { 5311cb0ef41Sopenharmony_ci npmlog: { 5321cb0ef41Sopenharmony_ci clearProgress: () => showingProgress = false, 5331cb0ef41Sopenharmony_ci showProgress: () => showingProgress = true, 5341cb0ef41Sopenharmony_ci }, 5351cb0ef41Sopenharmony_ci }, 5361cb0ef41Sopenharmony_ci globals: { 5371cb0ef41Sopenharmony_ci 'console.log': (...args) => { 5381cb0ef41Sopenharmony_ci t.equal(showingProgress, false, 'should not be showing progress right now') 5391cb0ef41Sopenharmony_ci logs.push(args) 5401cb0ef41Sopenharmony_ci }, 5411cb0ef41Sopenharmony_ci 'console.error': (...args) => { 5421cb0ef41Sopenharmony_ci t.equal(showingProgress, false, 'should not be showing progress right now') 5431cb0ef41Sopenharmony_ci errors.push(args) 5441cb0ef41Sopenharmony_ci }, 5451cb0ef41Sopenharmony_ci }, 5461cb0ef41Sopenharmony_ci }) 5471cb0ef41Sopenharmony_ci npm.originalOutput('hello\x00world') 5481cb0ef41Sopenharmony_ci npm.originalOutputError('error\x00world') 5491cb0ef41Sopenharmony_ci 5501cb0ef41Sopenharmony_ci t.match(logs, [['hello^@world']]) 5511cb0ef41Sopenharmony_ci t.match(errors, [['error^@world']]) 5521cb0ef41Sopenharmony_ci}) 5531cb0ef41Sopenharmony_ci 5541cb0ef41Sopenharmony_cit.test('aliases and typos', async t => { 5551cb0ef41Sopenharmony_ci const { Npm } = await loadMockNpm(t, { init: false }) 5561cb0ef41Sopenharmony_ci t.throws(() => Npm.cmd('thisisnotacommand'), { code: 'EUNKNOWNCOMMAND' }) 5571cb0ef41Sopenharmony_ci t.throws(() => Npm.cmd(''), { code: 'EUNKNOWNCOMMAND' }) 5581cb0ef41Sopenharmony_ci t.throws(() => Npm.cmd('birthday'), { code: 'EUNKNOWNCOMMAND' }) 5591cb0ef41Sopenharmony_ci t.match(Npm.cmd('it').name, 'install-test') 5601cb0ef41Sopenharmony_ci t.match(Npm.cmd('installTe').name, 'install-test') 5611cb0ef41Sopenharmony_ci t.match(Npm.cmd('access').name, 'access') 5621cb0ef41Sopenharmony_ci t.match(Npm.cmd('auth').name, 'owner') 5631cb0ef41Sopenharmony_ci}) 5641cb0ef41Sopenharmony_ci 5651cb0ef41Sopenharmony_cit.test('explicit workspace rejection', async t => { 5661cb0ef41Sopenharmony_ci const mock = await loadMockNpm(t, { 5671cb0ef41Sopenharmony_ci prefixDir: { 5681cb0ef41Sopenharmony_ci packages: { 5691cb0ef41Sopenharmony_ci a: { 5701cb0ef41Sopenharmony_ci 'package.json': JSON.stringify({ 5711cb0ef41Sopenharmony_ci name: 'a', 5721cb0ef41Sopenharmony_ci version: '1.0.0', 5731cb0ef41Sopenharmony_ci scripts: { test: 'echo test a' }, 5741cb0ef41Sopenharmony_ci }), 5751cb0ef41Sopenharmony_ci }, 5761cb0ef41Sopenharmony_ci }, 5771cb0ef41Sopenharmony_ci 'package.json': JSON.stringify({ 5781cb0ef41Sopenharmony_ci name: 'root', 5791cb0ef41Sopenharmony_ci version: '1.0.0', 5801cb0ef41Sopenharmony_ci workspaces: ['./packages/a'], 5811cb0ef41Sopenharmony_ci }), 5821cb0ef41Sopenharmony_ci }, 5831cb0ef41Sopenharmony_ci globals: { 5841cb0ef41Sopenharmony_ci 'process.argv': [ 5851cb0ef41Sopenharmony_ci process.execPath, 5861cb0ef41Sopenharmony_ci process.argv[1], 5871cb0ef41Sopenharmony_ci '--color', 'false', 5881cb0ef41Sopenharmony_ci '--workspace', './packages/a', 5891cb0ef41Sopenharmony_ci ], 5901cb0ef41Sopenharmony_ci }, 5911cb0ef41Sopenharmony_ci }) 5921cb0ef41Sopenharmony_ci await t.rejects( 5931cb0ef41Sopenharmony_ci mock.npm.exec('ping', []), 5941cb0ef41Sopenharmony_ci /This command does not support workspaces/ 5951cb0ef41Sopenharmony_ci ) 5961cb0ef41Sopenharmony_ci}) 5971cb0ef41Sopenharmony_ci 5981cb0ef41Sopenharmony_cit.test('implicit workspace rejection', async t => { 5991cb0ef41Sopenharmony_ci const mock = await loadMockNpm(t, { 6001cb0ef41Sopenharmony_ci prefixDir: { 6011cb0ef41Sopenharmony_ci packages: { 6021cb0ef41Sopenharmony_ci a: { 6031cb0ef41Sopenharmony_ci 'package.json': JSON.stringify({ 6041cb0ef41Sopenharmony_ci name: 'a', 6051cb0ef41Sopenharmony_ci version: '1.0.0', 6061cb0ef41Sopenharmony_ci scripts: { test: 'echo test a' }, 6071cb0ef41Sopenharmony_ci }), 6081cb0ef41Sopenharmony_ci }, 6091cb0ef41Sopenharmony_ci }, 6101cb0ef41Sopenharmony_ci 'package.json': JSON.stringify({ 6111cb0ef41Sopenharmony_ci name: 'root', 6121cb0ef41Sopenharmony_ci version: '1.0.0', 6131cb0ef41Sopenharmony_ci workspaces: ['./packages/a'], 6141cb0ef41Sopenharmony_ci }), 6151cb0ef41Sopenharmony_ci }, 6161cb0ef41Sopenharmony_ci chdir: ({ prefix }) => join(prefix, 'packages', 'a'), 6171cb0ef41Sopenharmony_ci globals: { 6181cb0ef41Sopenharmony_ci 'process.argv': [ 6191cb0ef41Sopenharmony_ci process.execPath, 6201cb0ef41Sopenharmony_ci process.argv[1], 6211cb0ef41Sopenharmony_ci '--color', 'false', 6221cb0ef41Sopenharmony_ci '--workspace', './packages/a', 6231cb0ef41Sopenharmony_ci ], 6241cb0ef41Sopenharmony_ci }, 6251cb0ef41Sopenharmony_ci }) 6261cb0ef41Sopenharmony_ci await t.rejects( 6271cb0ef41Sopenharmony_ci mock.npm.exec('team', []), 6281cb0ef41Sopenharmony_ci /This command does not support workspaces/ 6291cb0ef41Sopenharmony_ci ) 6301cb0ef41Sopenharmony_ci}) 6311cb0ef41Sopenharmony_ci 6321cb0ef41Sopenharmony_cit.test('implicit workspace accept', async t => { 6331cb0ef41Sopenharmony_ci const mock = await loadMockNpm(t, { 6341cb0ef41Sopenharmony_ci prefixDir: { 6351cb0ef41Sopenharmony_ci packages: { 6361cb0ef41Sopenharmony_ci a: { 6371cb0ef41Sopenharmony_ci 'package.json': JSON.stringify({ 6381cb0ef41Sopenharmony_ci name: 'a', 6391cb0ef41Sopenharmony_ci version: '1.0.0', 6401cb0ef41Sopenharmony_ci scripts: { test: 'echo test a' }, 6411cb0ef41Sopenharmony_ci }), 6421cb0ef41Sopenharmony_ci }, 6431cb0ef41Sopenharmony_ci }, 6441cb0ef41Sopenharmony_ci 'package.json': JSON.stringify({ 6451cb0ef41Sopenharmony_ci name: 'root', 6461cb0ef41Sopenharmony_ci version: '1.0.0', 6471cb0ef41Sopenharmony_ci workspaces: ['./packages/a'], 6481cb0ef41Sopenharmony_ci }), 6491cb0ef41Sopenharmony_ci }, 6501cb0ef41Sopenharmony_ci chdir: ({ prefix }) => join(prefix, 'packages', 'a'), 6511cb0ef41Sopenharmony_ci globals: { 6521cb0ef41Sopenharmony_ci 'process.argv': [ 6531cb0ef41Sopenharmony_ci process.execPath, 6541cb0ef41Sopenharmony_ci process.argv[1], 6551cb0ef41Sopenharmony_ci '--color', 'false', 6561cb0ef41Sopenharmony_ci ], 6571cb0ef41Sopenharmony_ci }, 6581cb0ef41Sopenharmony_ci }) 6591cb0ef41Sopenharmony_ci await t.rejects(mock.npm.exec('org', []), /.*Usage/) 6601cb0ef41Sopenharmony_ci}) 6611cb0ef41Sopenharmony_ci 6621cb0ef41Sopenharmony_cit.test('usage', async t => { 6631cb0ef41Sopenharmony_ci t.test('with browser', async t => { 6641cb0ef41Sopenharmony_ci const { npm } = await loadMockNpm(t, { globals: { process: { platform: 'posix' } } }) 6651cb0ef41Sopenharmony_ci const usage = npm.usage 6661cb0ef41Sopenharmony_ci npm.config.set('viewer', 'browser') 6671cb0ef41Sopenharmony_ci const browserUsage = npm.usage 6681cb0ef41Sopenharmony_ci t.notMatch(usage, '(in a browser)') 6691cb0ef41Sopenharmony_ci t.match(browserUsage, '(in a browser)') 6701cb0ef41Sopenharmony_ci }) 6711cb0ef41Sopenharmony_ci 6721cb0ef41Sopenharmony_ci t.test('windows always uses browser', async t => { 6731cb0ef41Sopenharmony_ci const { npm } = await loadMockNpm(t, { globals: { process: { platform: 'win32' } } }) 6741cb0ef41Sopenharmony_ci const usage = npm.usage 6751cb0ef41Sopenharmony_ci npm.config.set('viewer', 'browser') 6761cb0ef41Sopenharmony_ci const browserUsage = npm.usage 6771cb0ef41Sopenharmony_ci t.match(usage, '(in a browser)') 6781cb0ef41Sopenharmony_ci t.match(browserUsage, '(in a browser)') 6791cb0ef41Sopenharmony_ci }) 6801cb0ef41Sopenharmony_ci 6811cb0ef41Sopenharmony_ci t.test('includes commands', async t => { 6821cb0ef41Sopenharmony_ci const { npm } = await loadMockNpm(t) 6831cb0ef41Sopenharmony_ci const usage = npm.usage 6841cb0ef41Sopenharmony_ci npm.config.set('long', true) 6851cb0ef41Sopenharmony_ci const longUsage = npm.usage 6861cb0ef41Sopenharmony_ci 6871cb0ef41Sopenharmony_ci const lastCmd = commands[commands.length - 1] 6881cb0ef41Sopenharmony_ci for (const cmd of commands) { 6891cb0ef41Sopenharmony_ci const isLast = cmd === lastCmd 6901cb0ef41Sopenharmony_ci const shortCmd = new RegExp(`\\s${cmd}${isLast ? '\\n' : ',[\\s\\n]'}`) 6911cb0ef41Sopenharmony_ci const longCmd = new RegExp(`^\\s+${cmd}\\s+\\w.*\n\\s+Usage:\\n`, 'm') 6921cb0ef41Sopenharmony_ci 6931cb0ef41Sopenharmony_ci t.match(usage, shortCmd, `usage includes ${cmd}`) 6941cb0ef41Sopenharmony_ci t.notMatch(usage, longCmd, `usage does not include long ${cmd}`) 6951cb0ef41Sopenharmony_ci 6961cb0ef41Sopenharmony_ci t.match(longUsage, longCmd, `long usage includes ${cmd}`) 6971cb0ef41Sopenharmony_ci if (!isLast) { 6981cb0ef41Sopenharmony_ci // long usage includes false positives for the last command since it is 6991cb0ef41Sopenharmony_ci // not followed by a comma 7001cb0ef41Sopenharmony_ci t.notMatch(longUsage, shortCmd, `long usage does not include short ${cmd}`) 7011cb0ef41Sopenharmony_ci } 7021cb0ef41Sopenharmony_ci } 7031cb0ef41Sopenharmony_ci }) 7041cb0ef41Sopenharmony_ci 7051cb0ef41Sopenharmony_ci t.test('set process.stdout.columns', async t => { 7061cb0ef41Sopenharmony_ci const { npm } = await loadMockNpm(t, { 7071cb0ef41Sopenharmony_ci config: { viewer: 'man' }, 7081cb0ef41Sopenharmony_ci }) 7091cb0ef41Sopenharmony_ci t.cleanSnapshot = str => 7101cb0ef41Sopenharmony_ci str.replace(npm.config.get('userconfig'), '{USERCONFIG}') 7111cb0ef41Sopenharmony_ci .replace(npm.npmRoot, '{NPMROOT}') 7121cb0ef41Sopenharmony_ci .replace(`npm@${npm.version}`, 'npm@{VERSION}') 7131cb0ef41Sopenharmony_ci 7141cb0ef41Sopenharmony_ci const widths = [0, 1, 10, 24, 40, 41, 75, 76, 90, 100] 7151cb0ef41Sopenharmony_ci for (const width of widths) { 7161cb0ef41Sopenharmony_ci t.test(`column width ${width}`, async t => { 7171cb0ef41Sopenharmony_ci mockGlobals(t, { 'process.stdout.columns': width }) 7181cb0ef41Sopenharmony_ci const usage = npm.usage 7191cb0ef41Sopenharmony_ci t.matchSnapshot(usage) 7201cb0ef41Sopenharmony_ci }) 7211cb0ef41Sopenharmony_ci } 7221cb0ef41Sopenharmony_ci }) 7231cb0ef41Sopenharmony_ci}) 724