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