Skip to content

Commit

Permalink
fix(perf): address slow parse when using unknown-options-as-args (#394)
Browse files Browse the repository at this point in the history
  • Loading branch information
bcoe committed Jun 20, 2021
1 parent fb22816 commit 441f059
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 1 deletion.
4 changes: 3 additions & 1 deletion lib/yargs-parser.ts
Expand Up @@ -210,6 +210,7 @@ export class YargsParser {

for (let i = 0; i < args.length; i++) {
const arg = args[i]
const truncatedArg = arg.replace(/^-{3,}/, '---')
let broken: boolean
let key: string | undefined
let letters: string[]
Expand All @@ -221,7 +222,7 @@ export class YargsParser {
if (arg !== '--' && isUnknownOptionAsArg(arg)) {
pushPositional(arg)
// ---, ---=, ----, etc,
} else if (arg.match(/---+(=|$)/)) {
} else if (truncatedArg.match(/---+(=|$)/)) {
// options without key name are invalid.
pushPositional(arg)
continue
Expand Down Expand Up @@ -969,6 +970,7 @@ export class YargsParser {
}

function isUnknownOption (arg: string): boolean {
arg = arg.replace(/^-{3,}/, '--')
// ignore negative numbers
if (arg.match(negative)) { return false }
// if this is a short option group and all of them are configured, it isn't unknown
Expand Down
33 changes: 33 additions & 0 deletions test/yargs-parser.cjs
Expand Up @@ -3963,4 +3963,37 @@ describe('yargs-parser', function () {
}).to.throw(/yargs parser supports a minimum Node.js version of 55/)
delete process.env.YARGS_MIN_NODE_VERSION
})

// Refs: https://github.com/yargs/yargs-parser/issues/386
describe('perf', () => {
const i = 100000
describe('unknown-options-as-args', () => {
it('parses long chain of "-" with reasonable performance', function () {
this.timeout(500)
const s = (new Array(i).fill('-').join('')) + 'a'
const parsed = parser([s], { configuration: { 'unknown-options-as-args': true } })
parsed._[0].should.equal(s)
})
it('parses long chain of "-a-a" with reasonable performance', function () {
this.timeout(500)
const s = '-' + (new Array(i).fill('-a').join('')) + '=35'
const parsed = parser([s], { configuration: { 'unknown-options-as-args': true } })
parsed._[0].should.equal(s)
})
})
it('parses long chain of "-" with reasonable performance', function () {
this.timeout(500)
const s = (new Array(i).fill('-').join('')) + 'a'
const arg = (new Array(i - 2).fill('-').join('')) + 'a'
const parsed = parser([s])
parsed[arg].should.equal(true)
})
it('parses long chain of "-a-a" with reasonable performance', function () {
this.timeout(500)
const s = '-' + (new Array(i).fill('-a').join('')) + '=35'
const arg = 'a' + (new Array(i - 1).fill('A').join(''))
const parsed = parser([s])
parsed[arg].should.equal(35)
})
})
})

0 comments on commit 441f059

Please sign in to comment.