Skip to content

Commit

Permalink
fix: freeze was not resetting configObjects to initial state; address…
Browse files Browse the repository at this point in the history
…ed performance issue raised by @nexdrew. (#670)
  • Loading branch information
bcoe committed Oct 15, 2016
1 parent 6a88f83 commit ae4bcd4
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 2 deletions.
52 changes: 52 additions & 0 deletions test/yargs.js
Expand Up @@ -851,6 +851,40 @@ describe('yargs dsl tests', function () {
r2.logs[0].should.match(/--help.*Show help.*\[boolean\]/)
})

it('resets error state between calls to parse', function () {
var y = yargs()
.demand(2)

var err1 = null
var out1 = null
var argv1 = null
y.parse('foo', function (err, argv, output) {
err1 = err
argv1 = argv
out1 = output
})

err1.message.should.match(/Not enough non-option arguments/)
argv1._.should.include('foo')
out1.should.match(/Not enough non-option arguments/)

var err2 = null
var argv2 = null
var out2 = null
y.parse('foo bar', function (err, argv, output) {
err2 = err
argv2 = argv
out2 = output
})

expect(err2).to.equal(null)
argv2._.should.deep.equal([
'foo',
'bar'
])
expect(out2).to.equal('')
})

describe('commands', function () {
it('does not invoke command handler if output is populated', function () {
var err = null
Expand Down Expand Up @@ -904,6 +938,24 @@ describe('yargs dsl tests', function () {
argv.what.should.equal(true)
})

it('overwrites the prior context object, when parse is called multiple times', function () {
var argv = null
var parser = yargs()
.command('batman <api-token>', 'batman command', function () {}, function (_argv) {})

parser.parse('batman robin --what', {
state: 'grumpy but rich'
}, function (_err, _argv, _output) {})

parser.parse('batman robin --what', {
state: 'the hero we need'
}, function (_err, _argv, _output) {
argv = _argv
})

argv.state.should.equal('the hero we need')
})

it('populates argv appropriately when parse is called multiple times', function () {
var parser = yargs()
.command('batman <api-token>', 'batman command', function () {}, function (_argv) {})
Expand Down
17 changes: 15 additions & 2 deletions yargs.js
Expand Up @@ -138,18 +138,28 @@ function Yargs (processArgs, cwd, parentRequire) {
function freeze () {
frozen = {}
frozen.options = options
frozen.configObjects = options.configObjects.slice(0)
frozen.exitProcess = exitProcess
frozen.groups = groups
usage.freeze()
validation.freeze()
command.freeze()
frozen.strict = strict
frozen.completionCommand = completionCommand
frozen.output = output
frozen.exitError = exitError
frozen.hasOutput = hasOutput
frozen.parsed = self.parsed
}
function unfreeze () {
options = frozen.options
options.configObjects = frozen.configObjects
exitProcess = frozen.exitProcess
groups = frozen.groups
output = frozen.output
exitError = frozen.exitError
hasOutput = frozen.hasOutput
self.parsed = frozen.parsed
usage.unfreeze()
validation.unfreeze()
command.unfreeze()
Expand Down Expand Up @@ -413,10 +423,12 @@ function Yargs (processArgs, cwd, parentRequire) {

var parseFn = null
self.parse = function (args, shortCircuit, _parseFn) {
var config = null

// a context object can optionally be provided, this allows
// additional information to be passed to a command handler.
if (typeof shortCircuit === 'object') {
self.config(shortCircuit)
config = shortCircuit
shortCircuit = _parseFn
}

Expand All @@ -435,10 +447,11 @@ function Yargs (processArgs, cwd, parentRequire) {
freeze()
exitProcess = false
}
if (config) self.config(config)

var parsed = parseArgs(args, shortCircuit)
if (parseFn) {
parseFn(exitError, parsed, output)
self.reset()
unfreeze()
parseFn = null
}
Expand Down

0 comments on commit ae4bcd4

Please sign in to comment.