Skip to content

Commit

Permalink
Handling default and type assignment.
Browse files Browse the repository at this point in the history
  • Loading branch information
relistan committed Dec 1, 2012
1 parent 59ce482 commit 2011163
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 9 deletions.
27 changes: 25 additions & 2 deletions lib/troll.coffee
Expand Up @@ -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']]
Expand All @@ -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
Expand Down
45 changes: 38 additions & 7 deletions spec/options.spec.coffee
Expand Up @@ -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')

0 comments on commit 2011163

Please sign in to comment.