From 2011163786e440612e946826590d003e9a23322e Mon Sep 17 00:00:00 2001 From: Karl Matthias Date: Sat, 1 Dec 2012 12:52:45 +0000 Subject: [PATCH] Handling default and type assignment. --- lib/troll.coffee | 27 ++++++++++++++++++++++-- spec/options.spec.coffee | 45 +++++++++++++++++++++++++++++++++------- 2 files changed, 63 insertions(+), 9 deletions(-) diff --git a/lib/troll.coffee b/lib/troll.coffee index 02d9247..561bf7f 100644 --- a/lib/troll.coffee +++ b/lib/troll.coffee @@ -14,7 +14,11 @@ class Options opt: (name, description, opts) -> _.extend opts, 'desc': description - @parsedOpts[name] = opts + + # Figure out whether the default type needs a value passed + opts = @processDefaultFor(opts) + # Figure out if this is a flag or an option with an arg + @parsedOpts[name] = @processFlagOrOptFor(opts) if _.has(opts, 'short') previousKey = @shortOpts[opts['short']] @@ -29,11 +33,30 @@ class Options @parsedOpts[name]['short'] = short # ----- Private + processDefaultFor: (opts) -> + if _.has(opts, 'default') + throw new Error('type defined when default was provided') if opts['type'] + if _.contains([true, false], opts.default) + opts['type'] = 'Boolean' + else + opts['type'] = opts['default'].constructor.name + + opts + + processFlagOrOptFor: (opts) -> + if _.has(opts, 'type') and opts.type != 'Boolean' + opts['takesValue'] = true + else + opts['takesValue'] = false + + opts + + findShortFor: (name) -> char = @nextAvailableCharacter(name) return char if char - return @nextAvailableCharacter('abcdefghijklmnopqrstuvwxyz') + @nextAvailableCharacter('abcdefghijklmnopqrstuvwxyz') nextAvailableCharacter: (list) -> for letter in list diff --git a/spec/options.spec.coffee b/spec/options.spec.coffee index 0eeeb3d..14bda03 100644 --- a/spec/options.spec.coffee +++ b/spec/options.spec.coffee @@ -32,23 +32,54 @@ describe 'Options', -> @opts = new Options() it 'capitalizes the character if the lower case is not available', -> - @opts.getShortOpts()['h'] = 'foo' + @opts.getShortOpts().h = 'foo' @opts.opt 'header', 'Add a new header', default: 'X-Shakespeare' expect(_.has @opts.getShortOpts(), 'H').toBe true it 'finds the next available character when the first is not available', -> - @opts.getShortOpts()['h'] = 'foo' - @opts.getShortOpts()['H'] = 'foo' + @opts.getShortOpts().h = 'foo' + @opts.getShortOpts().H = 'foo' @opts.opt 'header', 'Add a new header', default: 'X-Shakespeare' expect(_.has @opts.getShortOpts(), 'e').toBe true it 'tries multiple options when earlier options are not available', -> - @opts.getShortOpts()['h'] = 'foo' - @opts.getShortOpts()['H'] = 'foo' - @opts.getShortOpts()['e'] = 'foo' - @opts.getShortOpts()['E'] = 'foo' + @opts.getShortOpts().h = 'foo' + @opts.getShortOpts().H = 'foo' + @opts.getShortOpts().e = 'foo' + @opts.getShortOpts().E = 'foo' @opts.opt 'header', 'Add a new header', default: 'X-Shakespeare' expect(_.has @opts.getShortOpts(), 'a').toBe true + + describe 'validates the passed arguments', -> + beforeEach -> + @opts = new Options() + + it 'requires an argument if type is defined', -> + @opts.opt 'header', 'Add a header', type: 'str' + expect(@opts.getParsedOpts().header.takesValue).toBe true + + it 'does not require an argument if type is undefined and default is a boolean', -> + @opts.opt 'silent', 'Enable silent mode', default: false + expect(@opts.getParsedOpts().silent.takesValue).toBe false + + it 'requires an argument if type is undefined and default is not a boolean', -> + @opts.opt 'header', 'Add a header', default: 'X-Something' + expect(@opts.getParsedOpts().header.takesValue).toBe true + + it 'sets the right type based on the provided default', -> + @opts.opt 'header', 'Add a header', default: 'X-Something' + expect(@opts.getParsedOpts().header.type).toEqual 'String' + + @opts.opt 'silent', 'Enable silent mode', default: false + expect(@opts.getParsedOpts().silent.type).toEqual 'Boolean' + + it 'raises when the type was set and a default was provided', -> + expect( -> + opts = new Options() + opts.opt 'header', 'Add a header', + default: 'X-Something', + type: 'String' + ).toThrow('type defined when default was provided')