Skip to content
This repository was archived by the owner on Aug 22, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
"author": "Jeff Dickey @jdxcode",
"bugs": "https://github.com/oclif/command/issues",
"dependencies": {
"@oclif/config": "^1",
"@oclif/config": "^1.15.1",
"@oclif/errors": "^1.2.2",
"@oclif/parser": "^3.8.3",
"@oclif/plugin-help": "^2",
"@oclif/plugin-help": "^3",
"debug": "^4.1.1",
"semver": "^5.6.0"
},
Expand All @@ -27,12 +27,12 @@
"fancy-test": "^1.4.3",
"globby": "^9.0.0",
"mocha": "^6.0.2",
"ts-node": "^8.0.3",
"typescript": "^3.3.3333"
"sinon": "^9.0.1",
"ts-node": "^8.8.2",
"typescript": "^3.8.3"
},
"peerDependencies": {
"@oclif/config": "^1",
"@oclif/plugin-help": "^2"
"@oclif/config": "^1"
},
"engines": {
"node": ">=8.0.0"
Expand Down
7 changes: 4 additions & 3 deletions src/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ const pjson = require('../package.json')
import * as Config from '@oclif/config'
import * as Errors from '@oclif/errors'
import * as Parser from '@oclif/parser'
import Help from '@oclif/plugin-help'
import {HelpBase} from '@oclif/plugin-help'
import {format, inspect} from 'util'

import * as flags from './flags'
import {sortBy, uniqBy} from './util'
import {getHelpClass} from '@oclif/plugin-help'

/**
* swallows stdout epipe errors
Expand Down Expand Up @@ -186,8 +187,8 @@ export default abstract class Command {
}

protected _help() {
const HHelp: typeof Help = require('@oclif/plugin-help').default
const help = new HHelp(this.config)
const HelpClass = getHelpClass(this.config)
const help: HelpBase = new HelpClass(this.config)
const cmd = Config.Command.toCached(this.ctor as any as Config.Command.Class)
if (!cmd.id) cmd.id = ''
let topics = this.config.topics
Expand Down
7 changes: 4 additions & 3 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import * as Config from '@oclif/config'
import Help from '@oclif/plugin-help'
import {HelpBase} from '@oclif/plugin-help'

import {Command} from '.'
import {getHelpClass} from '@oclif/plugin-help'

export class Main extends Command {
static run(argv = process.argv.slice(2), options?: Config.LoadOptions) {
Expand Down Expand Up @@ -36,8 +37,8 @@ export class Main extends Command {
}

protected _help() {
const HHelp: typeof Help = require('@oclif/plugin-help').default
const help = new HHelp(this.config)
const HelpClass = getHelpClass(this.config)
const help: HelpBase = new HelpClass(this.config)
help.showHelp(this.argv)
return this.exit(0)
}
Expand Down
142 changes: 142 additions & 0 deletions test/command.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import * as Config from '@oclif/config'
import {expect, fancy} from 'fancy-test'

import Base, {flags} from '../src'
import {TestHelpClassConfig} from './helpers/test-help-in-src/src/test-help-plugin'
import * as PluginHelp from '@oclif/plugin-help'

const originalgetHelpClass = PluginHelp.getHelpClass

// const pjson = require('../package.json')

Expand Down Expand Up @@ -267,6 +271,144 @@ USAGE

`)
})

fancy
.stdout()
.add('config', async () => {
const config: TestHelpClassConfig = await Config.load()
config.pjson.oclif.helpClass = 'help-class-does-not-exist'
return config
})
.do(async ({config}) => {
class CMD extends Command {
config = config
}
await CMD.run(['-h'])
})
.catch((error: Error) => expect(error.message).to.contain('Unable to load configured help class "help-class-does-not-exist", failed with message:\n'))
.it('shows useful error message when configured help class cannot be loaded')

fancy
.stdout()
.stub(PluginHelp, 'getHelpClass', function (config: any) {
return originalgetHelpClass(config, '')
})
.add('config', async () => {
const config: TestHelpClassConfig = await Config.load()
config.pjson.oclif.helpClass = undefined
return config
})
.do(async ({config}) => {
class CMD extends Command {
config = config
}
await CMD.run(['-h'])
})
.catch((error: Error) => expect(error.message).to.contain('Could not load a help class, consider installing the @oclif/plugin-help package, failed with message:\n'))
.it('shows useful error message when no help class has been configured and the default cannot be loaded')

describe('from a help class', () => {
fancy
.stdout()
.stub(PluginHelp, 'getHelpClass', function (config: Config.IConfig) {
const patchedConfig = {
...config,
root: `${__dirname}/helpers/test-help-in-lib/`,
}

return originalgetHelpClass(patchedConfig)
})
.add('config', async () => {
const config: TestHelpClassConfig = await Config.load()
config.pjson.oclif.helpClass = './lib/test-help-plugin'
return config
})
.do(async ({config}) => {
class CMD extends Command {
static id = 'test-command-for-help-plugin'

config = config
}
await CMD.run(['-h'])
})
.catch(/EEXIT: 0/)
.it('-h via a plugin in lib dir (compiled to js)', ctx => {
expect(ctx.stdout).to.equal('hello from test-help-plugin #showCommandHelp in the lib folder and in compiled javascript\n')
expect(ctx.config.showCommandHelpSpy!.getCalls().length).to.equal(1)
expect(ctx.config.showHelpSpy!.getCalls().length).to.equal(0)
const [Command, Topics] = ctx.config.showCommandHelpSpy!.firstCall.args
expect(Command.id).to.deep.equal('test-command-for-help-plugin')
expect(Topics).to.be.an('array')
})

fancy
.stdout()
.stub(PluginHelp, 'getHelpClass', function (config: Config.IConfig) {
const patchedConfig = {
...config,
root: `${__dirname}/helpers/test-help-in-src/`,
}

return originalgetHelpClass(patchedConfig)
})
.add('config', async () => {
const config: TestHelpClassConfig = await Config.load()
config.pjson.oclif.helpClass = './lib/test-help-plugin'
return config
})
.do(async ({config}) => {
class CMD extends Command {
static id = 'test-command-for-help-plugin'

config = config
}
await CMD.run(['-h'])
})
.catch(/EEXIT: 0/)
.it('-h via a plugin in src dir (source in ts)', ctx => {
expect(ctx.stdout).to.equal('hello from test-help-plugin #showCommandHelp\n')
expect(ctx.config.showCommandHelpSpy!.getCalls().length).to.equal(1)
expect(ctx.config.showHelpSpy!.getCalls().length).to.equal(0)
const [Command, Topics] = ctx.config.showCommandHelpSpy!.firstCall.args
expect(Command.id).to.deep.equal('test-command-for-help-plugin')
expect(Topics).to.be.an('array')
})

fancy
.stdout()
.stub(PluginHelp, 'getHelpClass', function (config: Config.IConfig) {
const patchedConfig = {
...config,
root: `${__dirname}/helpers/test-help-in-src/`,
}

return originalgetHelpClass(patchedConfig)
})
.add('config', async () => {
const config: TestHelpClassConfig = await Config.load()
config.pjson.oclif.helpClass = './lib/test-help-plugin'
return config
})
.do(async ({config}) => {
class CMD extends Command {
static id = 'test-command-for-help-plugin'

config = config

static flags = {help: flags.help()}
}
return CMD.run(['--help'])
})
.catch(/EEXIT: 0/)
.it('--help via a plugin in src dir (source in ts)', ctx => {
expect(ctx.stdout).to.equal('hello from test-help-plugin #showCommandHelp\n')
expect(ctx.config.showCommandHelpSpy!.getCalls().length).to.equal(1)
expect(ctx.config.showHelpSpy!.getCalls().length).to.equal(0)
const [Command, Topics] = ctx.config.showCommandHelpSpy!.firstCall.args
expect(Command.id).to.deep.equal('test-command-for-help-plugin')
expect(Topics).to.be.an('array')
})
})
})

describe('.log()', () => {
Expand Down
20 changes: 20 additions & 0 deletions test/helpers/test-help-in-lib/lib/test-help-plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/* eslint-disable */
'use strict';
Object.defineProperty (exports, '__esModule', {value: true});
const sinon_1 = require ('sinon');
class default_1 {
constructor (config, opts) {
this.showCommandHelp = sinon_1.spy (() => {
console.log ('hello from test-help-plugin #showCommandHelp in the lib folder and in compiled javascript');
});
this.showHelp = sinon_1.spy (() => {
console.log ('hello showHelp');
});
config.showCommandHelpSpy = this.showCommandHelp;
config.showHelpSpy = this.showHelp;
}
command () {
throw new Error ('not needed for testing @oclif/command');
}
}
exports.default = default_1;
25 changes: 25 additions & 0 deletions test/helpers/test-help-in-src/src/test-help-plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import {HelpBase} from '@oclif/plugin-help'
import {spy, SinonSpy} from 'sinon'
import {IConfig} from '@oclif/config'

export type TestHelpClassConfig = IConfig & { showCommandHelpSpy?: SinonSpy; showHelpSpy?: SinonSpy }

export default class extends HelpBase {
constructor(config: any, opts: any) {
super(config, opts)
config.showCommandHelpSpy = this.showCommandHelp
config.showHelpSpy = this.showHelp
}

showCommandHelp = spy(() => {
console.log('hello from test-help-plugin #showCommandHelp')
})

showHelp = spy(() => {
console.log('hello showHelp')
})

getCommandHelpForReadme(): string {
throw new Error('not needed for testing @oclif/command')
}
}
6 changes: 6 additions & 0 deletions test/helpers/test-help-in-src/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"compilerOptions": {
"rootDir": "./src",
"outDir": "./lib"
}
}
65 changes: 65 additions & 0 deletions test/main.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import {expect, fancy} from 'fancy-test'

import {Main} from '../src/main'
import * as PluginHelp from '@oclif/plugin-help'
import * as Config from '@oclif/config'
import {TestHelpClassConfig} from './helpers/test-help-in-src/src/test-help-plugin'

const pjson = require('../package.json')
const version = `@oclif/command/${pjson.version} ${process.platform}-${process.arch} node-${process.version}`
const originalgetHelpClass = PluginHelp.getHelpClass

describe('main', () => {
fancy
Expand Down Expand Up @@ -31,10 +35,71 @@ VERSION
USAGE
$ @oclif/command [COMMAND]

TOPICS
plugins list installed plugins

COMMANDS
help display help for @oclif/command
plugins list installed plugins

`))
.it('runs -h')

describe('with an alternative help class', async () => {
const getMainWithHelpClass = async () => {
const config: TestHelpClassConfig = await Config.load()
config.pjson.oclif.helpClass = './lib/test-help-plugin'

class MainWithHelpClass extends Main {
config = config
}

return MainWithHelpClass
}

fancy
.stdout()
.stub(PluginHelp, 'getHelpClass', function (config: Config.IConfig) {
const patchedConfig = {
...config,
root: `${__dirname}/helpers/test-help-in-src/`,
}

return originalgetHelpClass(patchedConfig)
})
.do(async () => (await getMainWithHelpClass()).run(['-h']))
.catch('EEXIT: 0')
.do(output => expect(output.stdout).to.equal('hello showHelp\n'))
.it('works with -h')

fancy
.stdout()
.stub(PluginHelp, 'getHelpClass', function (config: Config.IConfig) {
const patchedConfig = {
...config,
root: `${__dirname}/helpers/test-help-in-src/`,
}

return originalgetHelpClass(patchedConfig)
})
.do(async () => (await getMainWithHelpClass()).run(['--help']))
.catch('EEXIT: 0')
.do(output => expect(output.stdout).to.equal('hello showHelp\n'))
.it('works with --help')

fancy
.stdout()
.stub(PluginHelp, 'getHelpClass', function (config: Config.IConfig) {
const patchedConfig = {
...config,
root: `${__dirname}/helpers/test-help-in-src/`,
}

return originalgetHelpClass(patchedConfig)
})
.do(async () => (await getMainWithHelpClass()).run(['help']))
.catch('EEXIT: 0')
.do(output => expect(output.stdout).to.equal('hello showHelp\n'))
.it('works with help')
})
})
Loading