11cb0ef41Sopenharmony_ciconst t = require('tap')
21cb0ef41Sopenharmony_ciconst mockNpm = require('../../fixtures/mock-npm')
31cb0ef41Sopenharmony_ciconst { cleanCwd } = require('../../fixtures/clean-snapshot')
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ciconst mockExplore = async (t, exec, {
61cb0ef41Sopenharmony_ci  PJ_ERROR = null,
71cb0ef41Sopenharmony_ci  RUN_SCRIPT_ERROR = null,
81cb0ef41Sopenharmony_ci  RUN_SCRIPT_EXIT_CODE = 0,
91cb0ef41Sopenharmony_ci  RUN_SCRIPT_SIGNAL = null,
101cb0ef41Sopenharmony_ci} = {}) => {
111cb0ef41Sopenharmony_ci  let PJ_CALLED = ''
121cb0ef41Sopenharmony_ci  const mockPJ = {
131cb0ef41Sopenharmony_ci    normalize: async path => {
141cb0ef41Sopenharmony_ci      if (PJ_ERROR) {
151cb0ef41Sopenharmony_ci        throw PJ_ERROR
161cb0ef41Sopenharmony_ci      }
171cb0ef41Sopenharmony_ci      PJ_CALLED = cleanCwd(path)
181cb0ef41Sopenharmony_ci      return { content: { some: 'package' } }
191cb0ef41Sopenharmony_ci    },
201cb0ef41Sopenharmony_ci  }
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ci  let RUN_SCRIPT_EXEC = null
231cb0ef41Sopenharmony_ci  const mockRunScript = ({ pkg, event }) => {
241cb0ef41Sopenharmony_ci    if (event !== '_explore') {
251cb0ef41Sopenharmony_ci      throw new Error('got wrong event name')
261cb0ef41Sopenharmony_ci    }
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_ci    RUN_SCRIPT_EXEC = pkg.scripts._explore
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ci    if (RUN_SCRIPT_ERROR) {
311cb0ef41Sopenharmony_ci      return Promise.reject(RUN_SCRIPT_ERROR)
321cb0ef41Sopenharmony_ci    }
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ci    if (RUN_SCRIPT_EXIT_CODE || RUN_SCRIPT_SIGNAL) {
351cb0ef41Sopenharmony_ci      return Promise.reject(Object.assign(new Error('command failed'), {
361cb0ef41Sopenharmony_ci        code: RUN_SCRIPT_EXIT_CODE,
371cb0ef41Sopenharmony_ci        signal: RUN_SCRIPT_SIGNAL,
381cb0ef41Sopenharmony_ci      }))
391cb0ef41Sopenharmony_ci    }
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_ci    return Promise.resolve({ code: 0, signal: null })
421cb0ef41Sopenharmony_ci  }
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_ci  const mock = await mockNpm(t, {
451cb0ef41Sopenharmony_ci    mocks: {
461cb0ef41Sopenharmony_ci      '@npmcli/package-json': mockPJ,
471cb0ef41Sopenharmony_ci      '@npmcli/run-script': mockRunScript,
481cb0ef41Sopenharmony_ci    },
491cb0ef41Sopenharmony_ci    config: {
501cb0ef41Sopenharmony_ci      shell: 'shell-command',
511cb0ef41Sopenharmony_ci    },
521cb0ef41Sopenharmony_ci  })
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_ci  await mock.npm.exec('explore', exec)
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ci  return {
571cb0ef41Sopenharmony_ci    ...mock,
581cb0ef41Sopenharmony_ci    PJ_CALLED,
591cb0ef41Sopenharmony_ci    RUN_SCRIPT_EXEC,
601cb0ef41Sopenharmony_ci    output: cleanCwd(mock.joinedOutput()).trim(),
611cb0ef41Sopenharmony_ci  }
621cb0ef41Sopenharmony_ci}
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_cit.test('basic interactive', async t => {
651cb0ef41Sopenharmony_ci  const {
661cb0ef41Sopenharmony_ci    output,
671cb0ef41Sopenharmony_ci    PJ_CALLED,
681cb0ef41Sopenharmony_ci    RUN_SCRIPT_EXEC,
691cb0ef41Sopenharmony_ci  } = await mockExplore(t, ['pkg'])
701cb0ef41Sopenharmony_ci
711cb0ef41Sopenharmony_ci  t.ok(PJ_CALLED.endsWith('/pkg'))
721cb0ef41Sopenharmony_ci  t.strictSame(RUN_SCRIPT_EXEC, 'shell-command')
731cb0ef41Sopenharmony_ci  t.match(output, /Exploring \{CWD\}\/[\w-_/]+\nType 'exit' or \^D when finished/)
741cb0ef41Sopenharmony_ci})
751cb0ef41Sopenharmony_ci
761cb0ef41Sopenharmony_cit.test('interactive tracks exit code', async t => {
771cb0ef41Sopenharmony_ci  t.test('code', async t => {
781cb0ef41Sopenharmony_ci    const {
791cb0ef41Sopenharmony_ci      output,
801cb0ef41Sopenharmony_ci      PJ_CALLED,
811cb0ef41Sopenharmony_ci      RUN_SCRIPT_EXEC,
821cb0ef41Sopenharmony_ci    } = await mockExplore(t, ['pkg'], { RUN_SCRIPT_EXIT_CODE: 99 })
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ci    t.ok(PJ_CALLED.endsWith('/pkg'))
851cb0ef41Sopenharmony_ci    t.strictSame(RUN_SCRIPT_EXEC, 'shell-command')
861cb0ef41Sopenharmony_ci    t.match(output, /Exploring \{CWD\}\/[\w-_/]+\nType 'exit' or \^D when finished/)
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_ci    t.equal(process.exitCode, 99)
891cb0ef41Sopenharmony_ci  })
901cb0ef41Sopenharmony_ci
911cb0ef41Sopenharmony_ci  t.test('spawn fail', async t => {
921cb0ef41Sopenharmony_ci    const RUN_SCRIPT_ERROR = Object.assign(new Error('glorb'), {
931cb0ef41Sopenharmony_ci      code: 33,
941cb0ef41Sopenharmony_ci    })
951cb0ef41Sopenharmony_ci    await t.rejects(
961cb0ef41Sopenharmony_ci      mockExplore(t, ['pkg'], { RUN_SCRIPT_ERROR }),
971cb0ef41Sopenharmony_ci      { message: 'glorb', code: 33 }
981cb0ef41Sopenharmony_ci    )
991cb0ef41Sopenharmony_ci    t.equal(process.exitCode, 33)
1001cb0ef41Sopenharmony_ci  })
1011cb0ef41Sopenharmony_ci
1021cb0ef41Sopenharmony_ci  t.test('spawn fail, 0 exit code', async t => {
1031cb0ef41Sopenharmony_ci    const RUN_SCRIPT_ERROR = Object.assign(new Error('glorb'), {
1041cb0ef41Sopenharmony_ci      code: 0,
1051cb0ef41Sopenharmony_ci    })
1061cb0ef41Sopenharmony_ci    await t.rejects(
1071cb0ef41Sopenharmony_ci      mockExplore(t, ['pkg'], { RUN_SCRIPT_ERROR }),
1081cb0ef41Sopenharmony_ci      { message: 'glorb', code: 0 }
1091cb0ef41Sopenharmony_ci    )
1101cb0ef41Sopenharmony_ci    t.equal(process.exitCode, 1)
1111cb0ef41Sopenharmony_ci  })
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ci  t.test('spawn fail, no exit code', async t => {
1141cb0ef41Sopenharmony_ci    const RUN_SCRIPT_ERROR = Object.assign(new Error('command failed'), {
1151cb0ef41Sopenharmony_ci      code: 'EPROBLEM',
1161cb0ef41Sopenharmony_ci    })
1171cb0ef41Sopenharmony_ci    await t.rejects(
1181cb0ef41Sopenharmony_ci      mockExplore(t, ['pkg'], { RUN_SCRIPT_ERROR }),
1191cb0ef41Sopenharmony_ci      { message: 'command failed', code: 'EPROBLEM' }
1201cb0ef41Sopenharmony_ci    )
1211cb0ef41Sopenharmony_ci    t.equal(process.exitCode, 1)
1221cb0ef41Sopenharmony_ci  })
1231cb0ef41Sopenharmony_ci})
1241cb0ef41Sopenharmony_ci
1251cb0ef41Sopenharmony_cit.test('basic non-interactive', async t => {
1261cb0ef41Sopenharmony_ci  const {
1271cb0ef41Sopenharmony_ci    output,
1281cb0ef41Sopenharmony_ci    PJ_CALLED,
1291cb0ef41Sopenharmony_ci    RUN_SCRIPT_EXEC,
1301cb0ef41Sopenharmony_ci  } = await mockExplore(t, ['pkg', 'ls'])
1311cb0ef41Sopenharmony_ci
1321cb0ef41Sopenharmony_ci  t.ok(PJ_CALLED.endsWith('/pkg'))
1331cb0ef41Sopenharmony_ci  t.strictSame(RUN_SCRIPT_EXEC, 'ls')
1341cb0ef41Sopenharmony_ci
1351cb0ef41Sopenharmony_ci  t.strictSame(output, '')
1361cb0ef41Sopenharmony_ci})
1371cb0ef41Sopenharmony_ci
1381cb0ef41Sopenharmony_cit.test('signal fails non-interactive', async t => {
1391cb0ef41Sopenharmony_ci  await t.rejects(
1401cb0ef41Sopenharmony_ci    mockExplore(t, ['pkg', 'ls'], { RUN_SCRIPT_SIGNAL: 'SIGPROBLEM' }),
1411cb0ef41Sopenharmony_ci    {
1421cb0ef41Sopenharmony_ci      message: 'command failed',
1431cb0ef41Sopenharmony_ci      signal: 'SIGPROBLEM',
1441cb0ef41Sopenharmony_ci    }
1451cb0ef41Sopenharmony_ci  )
1461cb0ef41Sopenharmony_ci})
1471cb0ef41Sopenharmony_ci
1481cb0ef41Sopenharmony_cit.test('usage if no pkg provided', async t => {
1491cb0ef41Sopenharmony_ci  const noPkg = [
1501cb0ef41Sopenharmony_ci    [],
1511cb0ef41Sopenharmony_ci    ['foo/../..'],
1521cb0ef41Sopenharmony_ci    ['asdf/..'],
1531cb0ef41Sopenharmony_ci    ['.'],
1541cb0ef41Sopenharmony_ci    ['..'],
1551cb0ef41Sopenharmony_ci    ['../..'],
1561cb0ef41Sopenharmony_ci  ]
1571cb0ef41Sopenharmony_ci
1581cb0ef41Sopenharmony_ci  for (const args of noPkg) {
1591cb0ef41Sopenharmony_ci    t.test(JSON.stringify(args), async t => {
1601cb0ef41Sopenharmony_ci      await t.rejects(
1611cb0ef41Sopenharmony_ci        mockExplore(t, args),
1621cb0ef41Sopenharmony_ci        'Usage:'
1631cb0ef41Sopenharmony_ci      )
1641cb0ef41Sopenharmony_ci    })
1651cb0ef41Sopenharmony_ci  }
1661cb0ef41Sopenharmony_ci})
1671cb0ef41Sopenharmony_ci
1681cb0ef41Sopenharmony_cit.test('pkg not installed', async t => {
1691cb0ef41Sopenharmony_ci  const PJ_ERROR = new Error('plurple')
1701cb0ef41Sopenharmony_ci
1711cb0ef41Sopenharmony_ci  await t.rejects(
1721cb0ef41Sopenharmony_ci    mockExplore(t, ['pkg', 'ls'], { PJ_ERROR }),
1731cb0ef41Sopenharmony_ci    { message: 'plurple' }
1741cb0ef41Sopenharmony_ci  )
1751cb0ef41Sopenharmony_ci})
176