Skip to content

Commit

Permalink
Added code robustness when options values provided mismatch expected …
Browse files Browse the repository at this point in the history
…type
  • Loading branch information
Akaryatrh committed Sep 11, 2016
1 parent 3095ec1 commit 1266064
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 26 deletions.
6 changes: 3 additions & 3 deletions src/logger.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,17 @@ module.exports = class Logger
### OUTPUT ###

# Warning log
if @shared.options?.logLevels.indexOf("warning") > -1
if @shared.options?.logLevels?.indexOf("warning") > -1
for warning in @shared.logs.warnings
logOutput += @coloringOutput 'warning', warning

# Info log
if @shared.options?.logLevels.indexOf("info") > -1
if @shared.options?.logLevels?.indexOf("info") > -1
for info in @shared.logs.infos
logOutput += @coloringOutput 'info', info

# Global error log
if @shared.options?.logLevels.indexOf("error") > -1
if @shared.options?.logLevels?.indexOf("error") > -1
for error in @shared.logs.errors.globalMessages
logOutput += @coloringOutput 'error', error

Expand Down
60 changes: 37 additions & 23 deletions src/options-manager.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,13 @@ module.exports = class OptionsManager
else
@shared.logs.warnings.push "No options found -> defaults options have been used instead"


@shared.options.logLevels = @checkOptionsWithDefaults 'logLevels'
@shared.options.templatesExt = @checkOptionsWithDefaults 'templatesExt', true
@shared.options.assetsExt = @checkOptionsWithDefaults 'assetsExt', true
# deactivated for now --> @shared.options.matchTags = @checkOptionsWithDefaults 'matchTags'
@shared.options.preserveRoot ?= @shared.defaultOptions.preserveRoot

unless @shared.options.directory
unless @shared.options.directory and typeof @shared.options.directory is 'string'
prefix = 'No directory specified -> '
if @shared.options.preserveRoot
@shared.logs.errors.globalMessages.push "#{ prefix }processing aborted"
Expand All @@ -40,7 +39,7 @@ module.exports = class OptionsManager
@shared.logs.warnings.push "#{prefix}the root of your project has been used to find <svga> tags"


unless @shared.options.assets
unless @shared.options.assets and typeof @shared.options.assets is 'string'
prefix = 'No assets folder specified -> '
if @shared.options.preserveRoot
@shared.logs.errors.globalMessages.push "#{ prefix }processing aborted"
Expand All @@ -51,7 +50,7 @@ module.exports = class OptionsManager
@shared.logs.warnings.push "#{prefix}the root of your project has been used to find matching files"


unless @shared.options.outputDirectory
unless @shared.options.outputDirectory and typeof @shared.options.outputDirectory is 'string'
@shared.logs.warnings.push """
No output directory specified -> template source files will be replaced
"""
Expand All @@ -61,43 +60,58 @@ module.exports = class OptionsManager


#Check validity of specific options towards default ones
checkOptionsWithDefaults : (options, acceptAny) ->
switch
checkOptionsWithDefaults : (option, acceptAny) ->

sharedOptions = @shared.options[option]
defaultOptions = @shared.defaultOptions[option]
optionIsString = typeof sharedOptions is 'string'
optionIsBoolean = typeof sharedOptions is 'boolean'
optionIsNumber = !isNaN parseFloat(sharedOptions) and isFinite sharedOptions
optionIsArray = Array.isArray sharedOptions
defaultOptionIsArray = Array.isArray defaultOptions
optionsToMatch = if optionIsString then [sharedOptions] else sharedOptions
arrayValuesMatch = @checkArrayMatch optionsToMatch, defaultOptions

switch true
# is a string and accept any value
when typeof @shared.options[options] is 'string' and acceptAny
then [@shared.options[options]]
when optionIsString and acceptAny
then optionsToMatch

# is a string and part of authorized values
when typeof @shared.options[options] is 'string' and
@checkArrayMatch([@shared.options[options]], @shared.defaultOptions[options])
then [@shared.options[options]]
when optionIsString and arrayValuesMatch
then optionsToMatch

# is a string but not part of authorized values
when typeof @shared.options[options] is 'string' and
!@checkArrayMatch(@shared.options[options], @shared.defaultOptions[options])
then @returnOptionsAndWarning options
when optionIsString and !arrayValuesMatch
then @returnOptionsAndWarning option

# is a an array and accept any values
when Array.isArray(@shared.options[options]) and acceptAny
then @shared.options[options]
when optionIsArray and acceptAny
then sharedOptions

# is a an array but no values part of authorized values
when Array.isArray(@shared.options[options]) and
!@checkArrayMatch(@shared.options[options], @shared.defaultOptions[options])
then @returnOptionsAndWarning options
when optionIsArray and !arrayValuesMatch
then @returnOptionsAndWarning option

# is boolean or numeric value but an array is expected
when (optionIsBoolean or optionIsNumber) and defaultOptionIsArray and !arrayValuesMatch
@returnOptionsAndWarning option

when !@shared.options[options]?
then @shared.defaultOptions[options]
when !sharedOptions?
defaultOptions

else @shared.options[options]
else
sharedOptions


#loop for values in array and check that all values matches
checkArrayMatch : (values, matches) ->
check = false
if !values?.length
return check
for value in values
check = true if matches.indexOf(value) > -1
check
return check

# Warn and return defaults options
returnOptionsAndWarning : (options) ->
Expand Down
23 changes: 23 additions & 0 deletions test/options-managerTest.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,11 @@ module.exports = run: ->
defaultOptions = ['preserveRoot']
expect(optionsManager.checkArrayMatch(options, defaultOptions)).to.equal false

it 'should return false when option provided is not an array', ->
options = true
defaultOptions = ['preserveRoot']
expect(optionsManager.checkArrayMatch(options, defaultOptions)).to.equal false


describe '@checkOptionsWithDefaults', ->

Expand Down Expand Up @@ -203,5 +208,23 @@ module.exports = run: ->
returnedValues = ['warning', 'error', 'info']
expect(optionsManager.checkOptionsWithDefaults(option)).to.deep.members returnedValues

it 'when option has a boolean value but shouldn\'t,
it should return default values instead', ->
option = 'logLevels'
optionsManager.shared.options = {
logLevels: false
}
returnedValues = ['warning', 'error', 'info']
expect(optionsManager.checkOptionsWithDefaults(option)).to.deep.members returnedValues

it 'when option has a numeric value but shouldn\'t,
it should return default values instead', ->
option = 'logLevels'
optionsManager.shared.options = {
logLevels: 1.5
}
returnedValues = ['warning', 'error', 'info']
expect(optionsManager.checkOptionsWithDefaults(option)).to.deep.members returnedValues


return

0 comments on commit 1266064

Please sign in to comment.