11cb0ef41Sopenharmony_ciconst t = require('tap') 21cb0ef41Sopenharmony_ciconst fs = require('fs') 31cb0ef41Sopenharmony_ciconst path = require('path') 41cb0ef41Sopenharmony_ciconst { load: loadMockNpm } = require('../../fixtures/mock-npm') 51cb0ef41Sopenharmony_ci 61cb0ef41Sopenharmony_ciconst completionScript = fs 71cb0ef41Sopenharmony_ci .readFileSync(path.resolve(__dirname, '../../../lib/utils/completion.sh'), { encoding: 'utf8' }) 81cb0ef41Sopenharmony_ci .replace(/^#!.*?\n/, '') 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ciconst loadMockCompletion = async (t, o = {}) => { 111cb0ef41Sopenharmony_ci const { globals = {}, windows, ...options } = o 121cb0ef41Sopenharmony_ci const res = await loadMockNpm(t, { 131cb0ef41Sopenharmony_ci command: 'completion', 141cb0ef41Sopenharmony_ci ...options, 151cb0ef41Sopenharmony_ci globals: (dirs) => ({ 161cb0ef41Sopenharmony_ci 'process.platform': windows ? 'win32' : 'posix', 171cb0ef41Sopenharmony_ci 'process.env.term': 'notcygwin', 181cb0ef41Sopenharmony_ci 'process.env.msystem': 'nogmingw', 191cb0ef41Sopenharmony_ci ...(typeof globals === 'function' ? globals(dirs) : globals), 201cb0ef41Sopenharmony_ci }), 211cb0ef41Sopenharmony_ci }) 221cb0ef41Sopenharmony_ci return { 231cb0ef41Sopenharmony_ci resetGlobals: res.mockedGlobals.reset, 241cb0ef41Sopenharmony_ci ...res, 251cb0ef41Sopenharmony_ci } 261cb0ef41Sopenharmony_ci} 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ciconst loadMockCompletionComp = async (t, word, line) => 291cb0ef41Sopenharmony_ci loadMockCompletion(t, { 301cb0ef41Sopenharmony_ci globals: { 311cb0ef41Sopenharmony_ci 'process.env.COMP_CWORD': word, 321cb0ef41Sopenharmony_ci 'process.env.COMP_LINE': line, 331cb0ef41Sopenharmony_ci 'process.env.COMP_POINT': line.length, 341cb0ef41Sopenharmony_ci }, 351cb0ef41Sopenharmony_ci }) 361cb0ef41Sopenharmony_ci 371cb0ef41Sopenharmony_cit.test('completion', async t => { 381cb0ef41Sopenharmony_ci t.test('completion completion', async t => { 391cb0ef41Sopenharmony_ci const { outputs, completion } = await loadMockCompletion(t, { 401cb0ef41Sopenharmony_ci prefixDir: { 411cb0ef41Sopenharmony_ci '.bashrc': 'aaa', 421cb0ef41Sopenharmony_ci '.zshrc': 'aaa', 431cb0ef41Sopenharmony_ci }, 441cb0ef41Sopenharmony_ci globals: ({ prefix }) => ({ 451cb0ef41Sopenharmony_ci 'process.env.HOME': prefix, 461cb0ef41Sopenharmony_ci }), 471cb0ef41Sopenharmony_ci }) 481cb0ef41Sopenharmony_ci 491cb0ef41Sopenharmony_ci await completion.completion({ w: 2 }) 501cb0ef41Sopenharmony_ci t.matchSnapshot(outputs, 'both shells') 511cb0ef41Sopenharmony_ci }) 521cb0ef41Sopenharmony_ci 531cb0ef41Sopenharmony_ci t.test('completion completion no known shells', async t => { 541cb0ef41Sopenharmony_ci const { outputs, completion } = await loadMockCompletion(t, { 551cb0ef41Sopenharmony_ci globals: ({ prefix }) => ({ 561cb0ef41Sopenharmony_ci 'process.env.HOME': prefix, 571cb0ef41Sopenharmony_ci }), 581cb0ef41Sopenharmony_ci }) 591cb0ef41Sopenharmony_ci 601cb0ef41Sopenharmony_ci await completion.completion({ w: 2 }) 611cb0ef41Sopenharmony_ci t.matchSnapshot(outputs, 'no responses') 621cb0ef41Sopenharmony_ci }) 631cb0ef41Sopenharmony_ci 641cb0ef41Sopenharmony_ci t.test('completion completion wrong word count', async t => { 651cb0ef41Sopenharmony_ci const { outputs, completion } = await loadMockCompletion(t) 661cb0ef41Sopenharmony_ci 671cb0ef41Sopenharmony_ci await completion.completion({ w: 3 }) 681cb0ef41Sopenharmony_ci t.matchSnapshot(outputs, 'no responses') 691cb0ef41Sopenharmony_ci }) 701cb0ef41Sopenharmony_ci 711cb0ef41Sopenharmony_ci t.test('dump script when completion is not being attempted', async t => { 721cb0ef41Sopenharmony_ci let errorHandler, data 731cb0ef41Sopenharmony_ci const { completion, resetGlobals } = await loadMockCompletion(t, { 741cb0ef41Sopenharmony_ci globals: { 751cb0ef41Sopenharmony_ci 'process.stdout.on': (event, handler) => { 761cb0ef41Sopenharmony_ci errorHandler = handler 771cb0ef41Sopenharmony_ci resetGlobals['process.stdout.on']() 781cb0ef41Sopenharmony_ci }, 791cb0ef41Sopenharmony_ci 'process.stdout.write': (chunk, callback) => { 801cb0ef41Sopenharmony_ci data = chunk 811cb0ef41Sopenharmony_ci process.nextTick(() => { 821cb0ef41Sopenharmony_ci callback() 831cb0ef41Sopenharmony_ci errorHandler({ errno: 'EPIPE' }) 841cb0ef41Sopenharmony_ci }) 851cb0ef41Sopenharmony_ci resetGlobals['process.stdout.write']() 861cb0ef41Sopenharmony_ci }, 871cb0ef41Sopenharmony_ci }, 881cb0ef41Sopenharmony_ci }) 891cb0ef41Sopenharmony_ci 901cb0ef41Sopenharmony_ci await completion.exec() 911cb0ef41Sopenharmony_ci t.equal(data, completionScript, 'wrote the completion script') 921cb0ef41Sopenharmony_ci }) 931cb0ef41Sopenharmony_ci 941cb0ef41Sopenharmony_ci t.test('dump script exits correctly when EPIPE is emitted on stdout', async t => { 951cb0ef41Sopenharmony_ci let errorHandler, data 961cb0ef41Sopenharmony_ci const { completion, resetGlobals } = await loadMockCompletion(t, { 971cb0ef41Sopenharmony_ci globals: { 981cb0ef41Sopenharmony_ci 'process.stdout.on': (event, handler) => { 991cb0ef41Sopenharmony_ci if (event === 'error') { 1001cb0ef41Sopenharmony_ci errorHandler = handler 1011cb0ef41Sopenharmony_ci } 1021cb0ef41Sopenharmony_ci resetGlobals['process.stdout.on']() 1031cb0ef41Sopenharmony_ci }, 1041cb0ef41Sopenharmony_ci 'process.stdout.write': (chunk, callback) => { 1051cb0ef41Sopenharmony_ci data = chunk 1061cb0ef41Sopenharmony_ci process.nextTick(() => { 1071cb0ef41Sopenharmony_ci errorHandler({ errno: 'EPIPE' }) 1081cb0ef41Sopenharmony_ci callback() 1091cb0ef41Sopenharmony_ci }) 1101cb0ef41Sopenharmony_ci resetGlobals['process.stdout.write']() 1111cb0ef41Sopenharmony_ci }, 1121cb0ef41Sopenharmony_ci }, 1131cb0ef41Sopenharmony_ci }) 1141cb0ef41Sopenharmony_ci 1151cb0ef41Sopenharmony_ci await completion.exec() 1161cb0ef41Sopenharmony_ci t.equal(data, completionScript, 'wrote the completion script') 1171cb0ef41Sopenharmony_ci }) 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_ci t.test('single command name', async t => { 1201cb0ef41Sopenharmony_ci const { outputs, completion } = await loadMockCompletionComp(t, 1, 'npm conf') 1211cb0ef41Sopenharmony_ci 1221cb0ef41Sopenharmony_ci await completion.exec(['npm', 'conf']) 1231cb0ef41Sopenharmony_ci t.matchSnapshot(outputs, 'single command name') 1241cb0ef41Sopenharmony_ci }) 1251cb0ef41Sopenharmony_ci 1261cb0ef41Sopenharmony_ci t.test('multiple command names', async t => { 1271cb0ef41Sopenharmony_ci const { outputs, completion } = await loadMockCompletionComp(t, 1, 'npm a') 1281cb0ef41Sopenharmony_ci 1291cb0ef41Sopenharmony_ci await completion.exec(['npm', 'a']) 1301cb0ef41Sopenharmony_ci t.matchSnapshot(outputs, 'multiple command names') 1311cb0ef41Sopenharmony_ci }) 1321cb0ef41Sopenharmony_ci 1331cb0ef41Sopenharmony_ci t.test('completion of invalid command name does nothing', async t => { 1341cb0ef41Sopenharmony_ci const { outputs, completion } = await loadMockCompletionComp(t, 1, 'npm compute') 1351cb0ef41Sopenharmony_ci 1361cb0ef41Sopenharmony_ci await completion.exec(['npm', 'compute']) 1371cb0ef41Sopenharmony_ci t.matchSnapshot(outputs, 'no results') 1381cb0ef41Sopenharmony_ci }) 1391cb0ef41Sopenharmony_ci 1401cb0ef41Sopenharmony_ci t.test('subcommand completion', async t => { 1411cb0ef41Sopenharmony_ci const { outputs, completion } = await loadMockCompletionComp(t, 2, 'npm access ') 1421cb0ef41Sopenharmony_ci 1431cb0ef41Sopenharmony_ci await completion.exec(['npm', 'access', '']) 1441cb0ef41Sopenharmony_ci t.matchSnapshot(outputs, 'subcommands') 1451cb0ef41Sopenharmony_ci }) 1461cb0ef41Sopenharmony_ci 1471cb0ef41Sopenharmony_ci t.test('filtered subcommands', async t => { 1481cb0ef41Sopenharmony_ci const { outputs, completion } = await loadMockCompletionComp(t, 2, 'npm access p') 1491cb0ef41Sopenharmony_ci 1501cb0ef41Sopenharmony_ci await completion.exec(['npm', 'access', 'p']) 1511cb0ef41Sopenharmony_ci t.matchSnapshot(outputs, 'filtered subcommands') 1521cb0ef41Sopenharmony_ci }) 1531cb0ef41Sopenharmony_ci 1541cb0ef41Sopenharmony_ci t.test('commands with no completion', async t => { 1551cb0ef41Sopenharmony_ci const { outputs, completion } = await loadMockCompletionComp(t, 2, 'npm adduser ') 1561cb0ef41Sopenharmony_ci 1571cb0ef41Sopenharmony_ci // quotes around adduser are to ensure coverage when unescaping commands 1581cb0ef41Sopenharmony_ci await completion.exec(['npm', "'adduser'", '']) 1591cb0ef41Sopenharmony_ci t.matchSnapshot(outputs, 'no results') 1601cb0ef41Sopenharmony_ci }) 1611cb0ef41Sopenharmony_ci 1621cb0ef41Sopenharmony_ci t.test('flags', async t => { 1631cb0ef41Sopenharmony_ci const { outputs, completion } = await loadMockCompletionComp(t, 2, 'npm install --v') 1641cb0ef41Sopenharmony_ci 1651cb0ef41Sopenharmony_ci await completion.exec(['npm', 'install', '--v']) 1661cb0ef41Sopenharmony_ci t.matchSnapshot(outputs, 'flags') 1671cb0ef41Sopenharmony_ci }) 1681cb0ef41Sopenharmony_ci 1691cb0ef41Sopenharmony_ci t.test('--no- flags', async t => { 1701cb0ef41Sopenharmony_ci const { outputs, completion } = await loadMockCompletionComp(t, 2, 'npm install --no-v') 1711cb0ef41Sopenharmony_ci 1721cb0ef41Sopenharmony_ci await completion.exec(['npm', 'install', '--no-v']) 1731cb0ef41Sopenharmony_ci t.matchSnapshot(outputs, 'flags') 1741cb0ef41Sopenharmony_ci }) 1751cb0ef41Sopenharmony_ci 1761cb0ef41Sopenharmony_ci t.test('double dashes escape from flag completion', async t => { 1771cb0ef41Sopenharmony_ci const { outputs, completion } = await loadMockCompletionComp(t, 2, 'npm -- install --') 1781cb0ef41Sopenharmony_ci 1791cb0ef41Sopenharmony_ci await completion.exec(['npm', '--', 'install', '--']) 1801cb0ef41Sopenharmony_ci t.matchSnapshot(outputs, 'full command list') 1811cb0ef41Sopenharmony_ci }) 1821cb0ef41Sopenharmony_ci 1831cb0ef41Sopenharmony_ci t.test('completion cannot complete options that take a value in mid-command', async t => { 1841cb0ef41Sopenharmony_ci const { outputs, completion } = await loadMockCompletionComp(t, 2, 'npm --registry install') 1851cb0ef41Sopenharmony_ci 1861cb0ef41Sopenharmony_ci await completion.exec(['npm', '--registry', 'install']) 1871cb0ef41Sopenharmony_ci t.matchSnapshot(outputs, 'does not try to complete option arguments in the middle of a command') 1881cb0ef41Sopenharmony_ci }) 1891cb0ef41Sopenharmony_ci}) 1901cb0ef41Sopenharmony_ci 1911cb0ef41Sopenharmony_cit.test('windows without bash', async t => { 1921cb0ef41Sopenharmony_ci const { outputs, completion } = await loadMockCompletion(t, { windows: true }) 1931cb0ef41Sopenharmony_ci await t.rejects( 1941cb0ef41Sopenharmony_ci completion.exec(), 1951cb0ef41Sopenharmony_ci { code: 'ENOTSUP', message: /completion supported only in MINGW/ }, 1961cb0ef41Sopenharmony_ci 'returns the correct error' 1971cb0ef41Sopenharmony_ci ) 1981cb0ef41Sopenharmony_ci t.matchSnapshot(outputs, 'no output') 1991cb0ef41Sopenharmony_ci}) 200