diff --git a/src/help/util.ts b/src/help/util.ts index 0c7c2fce1..be04d0f58 100644 --- a/src/help/util.ts +++ b/src/help/util.ts @@ -44,18 +44,19 @@ function collateSpacedCmdIDFromArgs(argv: string[], config: IConfig): string[] { const final: string[] = [] const idPresent = (id: string) => ids.includes(id) const isFlag = (s: string) => s.startsWith('-') + const isArgWithValue = (s: string) => s.includes('=') const finalizeId = (s?: string) => s ? [...final, s].join(':') : final.join(':') const hasSubCommandsWithArgs = () => { const subCommands = config.commands.filter(c => (c.id).startsWith(finalizeId())) - return Boolean(subCommands.find(cmd => cmd.strict === false || cmd.args.length > 0)) + return Boolean(subCommands.find(cmd => cmd.strict === false || cmd.args?.length > 0)) } for (const arg of argv) { if (idPresent(finalizeId(arg))) final.push(arg) // If the parent topic has a command that expects positional arguments, then we cannot // assume that any subsequent string could be part of the command name - else if (isFlag(arg) || hasSubCommandsWithArgs()) break + else if (isArgWithValue(arg) || isFlag(arg) || hasSubCommandsWithArgs()) break else final.push(arg) } diff --git a/test/help/util.test.ts b/test/help/util.test.ts index 7c1e7914a..914474ac7 100644 --- a/test/help/util.test.ts +++ b/test/help/util.test.ts @@ -90,6 +90,18 @@ describe('util', () => { expect(actual).to.deep.equal(['foo:bar', 'baz']) }) + test + .stub(Config.prototype, 'commandIDs', () => ['foo', 'foo:bar']) + .it('should return standardized id when topic separator is a space and has variable arguments and flags', () => { + config.topicSeparator = ' ' + config.commands.push({ + id: 'foo:bar', + strict: false, + } as any) + const actual = standardizeIDFromArgv(['foo', 'bar', 'baz', '--hello'], config) + expect(actual).to.deep.equal(['foo:bar', 'baz', '--hello']) + }) + test .stub(Config.prototype, 'commandIDs', () => ['foo', 'foo:bar']) .it('should return full id when topic separator is a space and does not have arguments', () => { @@ -102,5 +114,45 @@ describe('util', () => { const actual = standardizeIDFromArgv(['foo', 'bar', 'baz'], config) expect(actual).to.deep.equal(['foo:bar:baz']) }) + + test + .stub(Config.prototype, 'commandIDs', () => ['foo', 'foo:bar']) + .it('should return standardized id when topic separator is a space and has arg with value', () => { + config.topicSeparator = ' ' + config.commands.push({id: 'foo:bar'} as any) + const actual = standardizeIDFromArgv(['foo', 'bar', 'hello=world'], config) + expect(actual).to.deep.equal(['foo:bar', 'hello=world']) + }) + + test + .stub(Config.prototype, 'commandIDs', () => ['foo', 'foo:bar']) + .it('should return standardized id when topic separator is a space and has variable args with value', () => { + config.topicSeparator = ' ' + config.commands.push({id: 'foo:bar', strict: false} as any) + const actual = standardizeIDFromArgv(['foo', 'bar', 'hello=world', 'my-arg=value'], config) + expect(actual).to.deep.equal(['foo:bar', 'hello=world', 'my-arg=value']) + }) + + test + .stub(Config.prototype, 'commandIDs', () => ['foo', 'foo:bar']) + .it('should return standardized id when topic separator is a space and has flags', () => { + config.topicSeparator = ' ' + config.commands.push({id: 'foo:bar'} as any) + const actual = standardizeIDFromArgv(['foo', 'bar', '--baz'], config) + expect(actual).to.deep.equal(['foo:bar', '--baz']) + }) + + test + .stub(Config.prototype, 'commandIDs', () => ['foo', 'foo:bar']) + .it('should return standardized id when topic separator is a space and has flags, arg, and arg with value', () => { + config.topicSeparator = ' ' + config.commands.push({ + id: 'foo:bar', + args: [{name: 'my-arg'}], + strict: true, + } as any) + const actual = standardizeIDFromArgv(['foo', 'bar', 'my-arg', 'hello=world', '--baz'], config) + expect(actual).to.deep.equal(['foo:bar', 'my-arg', 'hello=world', '--baz']) + }) }) })