Skip to content

Commit

Permalink
tests for npm help
Browse files Browse the repository at this point in the history
PR-URL: #2348
Credit: @nlf
Close: #2348
Reviewed-by: @ruyadorno
  • Loading branch information
nlf committed Dec 15, 2020
1 parent 3ba5de4 commit 6caf19f
Show file tree
Hide file tree
Showing 2 changed files with 368 additions and 1 deletion.
7 changes: 6 additions & 1 deletion lib/help.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,12 @@ function viewMan (man, cb) {
break

case 'browser':
openUrl(htmlMan(man), 'help available at the following URL', cb)
try {
var url = htmlMan(man)
} catch (err) {
return cb(err)
}
openUrl(url, 'help available at the following URL', cb)
break

default:
Expand Down
362 changes: 362 additions & 0 deletions test/lib/help.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,362 @@
const { test } = require('tap')
const requireInject = require('require-inject')
const { EventEmitter } = require('events')

let npmUsageArg = null
const npmUsage = (arg) => {
npmUsageArg = arg
}

const npmConfig = {
usage: false,
viewer: undefined,
loglevel: undefined,
}

let helpSearchArgs = null
const npm = {
config: {
get: (key) => npmConfig[key],
set: (key, value) => {
npmConfig[key] = value
},
parsedArgv: {
cooked: [],
},
},
commands: {
'help-search': (args, cb) => {
helpSearchArgs = args
return cb()
},
help: {
usage: 'npm help <term>',
},
},
deref: (cmd) => {},
}

const OUTPUT = []
const output = (msg) => {
OUTPUT.push(msg)
}

const globDefaults = [
'/root/man/man1/npm-whoami.1',
'/root/man/man5/npmrc.5',
'/root/man/man7/disputes.7',
]

let globErr = null
let globResult = globDefaults
const glob = (p, cb) => {
return cb(globErr, globResult)
}

let spawnBin = null
let spawnArgs = null
const spawn = (bin, args) => {
spawnBin = bin
spawnArgs = args
const spawnEmitter = new EventEmitter()
process.nextTick(() => {
spawnEmitter.emit('close', 0)
})
return spawnEmitter
}

let openUrlArg = null
const openUrl = (url, msg, cb) => {
openUrlArg = url
return cb()
}

const help = requireInject('../../lib/help.js', {
'../../lib/npm.js': npm,
'../../lib/utils/npm-usage.js': npmUsage,
'../../lib/utils/open-url.js': openUrl,
'../../lib/utils/output.js': output,
'../../lib/utils/spawn.js': spawn,
glob,
})

test('npm help', t => {
t.teardown(() => {
npmUsageArg = null
})

return help([], (err) => {
if (err)
throw err

t.equal(npmUsageArg, false, 'called npmUsage')
t.end()
})
})

test('npm help completion', async t => {
t.teardown(() => {
globErr = null
})
const completion = (opts) => new Promise((resolve, reject) => {
help.completion(opts, (err, res) => {
if (err)
return reject(err)
return resolve(res)
})
})

const noArgs = await completion({ conf: { argv: { remain: [] } } })
t.strictSame(noArgs, ['help', 'whoami', 'npmrc', 'disputes'], 'outputs available help pages')
const threeArgs = await completion({ conf: { argv: { remain: ['one', 'two', 'three'] } } })
t.strictSame(threeArgs, [], 'outputs no results when more than 2 args are provided')
globErr = new Error('glob failed')
t.rejects(completion({ conf: { argv: { remain: [] } } }), /glob failed/, 'glob errors propagate')
})

test('npm help -h', t => {
npmConfig.usage = true
t.teardown(() => {
npmConfig.usage = false
OUTPUT.length = 0
})

return help(['help'], (err) => {
if (err)
throw err

t.strictSame(OUTPUT, ['npm help <term>'], 'outputs usage information for command')
t.end()
})
})

test('npm help multiple args calls search', t => {
t.teardown(() => {
helpSearchArgs = null
})

return help(['run', 'script'], (err) => {
if (err)
throw err

t.strictSame(helpSearchArgs, ['run', 'script'], 'passed the args to help-search')
t.end()
})
})

test('npm help no matches calls search', t => {
globResult = []
t.teardown(() => {
helpSearchArgs = null
globResult = globDefaults
})

return help(['asdfasdf'], (err) => {
if (err)
throw err

t.strictSame(helpSearchArgs, ['asdfasdf'], 'passed the args to help-search')
t.end()
})
})

test('npm help glob errors propagate', t => {
globErr = new Error('glob failed')
t.teardown(() => {
globErr = null
spawnBin = null
spawnArgs = null
})

return help(['whoami'], (err) => {
t.match(err, /glob failed/, 'glob error propagates')
t.end()
})
})

test('npm help whoami', t => {
globResult = ['/root/man/man1/npm-whoami.1.xz']
t.teardown(() => {
globResult = globDefaults
spawnBin = null
spawnArgs = null
})

return help(['whoami'], (err) => {
if (err)
throw err

t.equal(spawnBin, 'man', 'calls man by default')
t.strictSame(spawnArgs, ['1', 'npm-whoami'], 'passes the correct arguments')
t.end()
})
})

test('npm help 1 install', t => {
npmConfig.viewer = 'browser'
globResult = [
'/root/man/man5/install.5',
'/root/man/man1/npm-install.1',
]

t.teardown(() => {
npmConfig.viewer = undefined
globResult = globDefaults
spawnBin = null
spawnArgs = null
})

return help(['1', 'install'], (err) => {
if (err)
throw err

t.match(openUrlArg, /commands(\/|\\)npm-install.html$/, 'attempts to open the correct url')
t.end()
})
})

test('npm help 5 install', t => {
npmConfig.viewer = 'browser'
globResult = [
'/root/man/man5/install.5',
'/root/man/man1/npm-install.1',
]

t.teardown(() => {
npmConfig.viewer = undefined
globResult = globDefaults
spawnBin = null
spawnArgs = null
})

return help(['5', 'install'], (err) => {
if (err)
throw err

t.match(openUrlArg, /configuring-npm(\/|\\)install.html$/, 'attempts to open the correct url')
t.end()
})
})

test('npm help 7 config', t => {
npmConfig.viewer = 'browser'
globResult = [
'/root/man/man1/npm-config.1',
'/root/man/man7/config.7',
]
t.teardown(() => {
npmConfig.viewer = undefined
globResult = globDefaults
spawnBin = null
spawnArgs = null
})

return help(['7', 'config'], (err) => {
if (err)
throw err

t.match(openUrlArg, /using-npm(\/|\\)config.html$/, 'attempts to open the correct url')
t.end()
})
})

test('npm help with browser viewer and invalid section throws', t => {
npmConfig.viewer = 'browser'
globResult = [
'/root/man/man1/npm-config.1',
'/root/man/man7/config.7',
'/root/man/man9/config.9',
]
t.teardown(() => {
npmConfig.viewer = undefined
globResult = globDefaults
spawnBin = null
spawnArgs = null
})

return help(['9', 'config'], (err) => {
t.match(err, /invalid man section: 9/, 'throws appropriate error')
t.end()
})
})

test('npm help global redirects to folders', t => {
globResult = ['/root/man/man5/folders.5']
t.teardown(() => {
globResult = globDefaults
spawnBin = null
spawnArgs = null
})

return help(['global'], (err) => {
if (err)
throw err

t.equal(spawnBin, 'man', 'calls man by default')
t.strictSame(spawnArgs, ['5', 'folders'], 'passes the correct arguments')
t.end()
})
})

test('npm help package.json redirects to package-json', t => {
globResult = ['/root/man/man5/package-json.5']
t.teardown(() => {
globResult = globDefaults
spawnBin = null
spawnArgs = null
})

return help(['package.json'], (err) => {
if (err)
throw err

t.equal(spawnBin, 'man', 'calls man by default')
t.strictSame(spawnArgs, ['5', 'package-json'], 'passes the correct arguments')
t.end()
})
})

test('npm help ?(un)star', t => {
npmConfig.viewer = 'woman'
globResult = [
'/root/man/man1/npm-star.1',
'/root/man/man1/npm-unstar.1',
]
t.teardown(() => {
npmConfig.viewer = undefined
globResult = globDefaults
spawnBin = null
spawnArgs = null
})

return help(['?(un)star'], (err) => {
if (err)
throw err

t.equal(spawnBin, 'emacsclient', 'maps woman to emacs correctly')
t.strictSame(spawnArgs, ['-e', `(woman-find-file '/root/man/man1/npm-unstar.1')`], 'passes the correct arguments')
t.end()
})
})

test('npm help un*', t => {
globResult = [
'/root/man/man1/npm-unstar.1',
'/root/man/man1/npm-uninstall.1',
'/root/man/man1/npm-unpublish.1',
]
t.teardown(() => {
globResult = globDefaults
spawnBin = null
spawnArgs = null
})

return help(['un*'], (err) => {
if (err)
throw err

t.equal(spawnBin, 'man', 'calls man by default')
t.strictSame(spawnArgs, ['1', 'npm-unstar'], 'passes the correct arguments')
t.end()
})
})

0 comments on commit 6caf19f

Please sign in to comment.