diff --git a/app/module_validator.go b/app/module_validator.go index b5ebf7dc..cee8bce2 100644 --- a/app/module_validator.go +++ b/app/module_validator.go @@ -5,11 +5,17 @@ import ( "os" "github.com/logrusorgru/aurora" + "github.com/wtfutil/wtf/cfg" "github.com/wtfutil/wtf/wtf" ) type ModuleValidator struct{} +type widgetError struct { + name string + validationErrors []cfg.Validatable +} + func NewModuleValidator() *ModuleValidator { return &ModuleValidator{} } @@ -17,42 +23,57 @@ func NewModuleValidator() *ModuleValidator { // Validate rolls through all the enabled widgets and looks for configuration errors. // If it finds any it stringifies them, writes them to the console, and kills the app gracefully func (val *ModuleValidator) Validate(widgets []wtf.Wtfable) { - var errStr string - hasErrors := false + validationErrors := validate(widgets) - for _, widget := range widgets { - var widgetErrStr string - - for _, val := range widget.CommonSettings().Validations() { - if val.HasError() { - hasErrors = true - widgetErrStr += fmt.Sprintf(" - %s\t%s %v\n", val, aurora.Red("Error:"), val.Error()) + if len(validationErrors) > 0 { + fmt.Println() + for _, error := range validationErrors { + for _, message := range error.errorMessages() { + fmt.Println(message) } } - - if widgetErrStr != "" { - errStr += fmt.Sprintf( - "%s\n", - fmt.Sprintf( - "%s in %s configuration", - aurora.Red("Errors"), - aurora.Yellow( - fmt.Sprintf( - "%s.position", - widget.Name(), - ), - ), - ), - ) - - errStr += widgetErrStr + "\n" - } - } - - if hasErrors { fmt.Println() - fmt.Println(errStr) os.Exit(1) } } + +func validate(widgets []wtf.Wtfable) (widgetErrors []widgetError) { + for _, widget := range widgets { + error := widgetError{name: widget.Name()} + + for _, val := range widget.CommonSettings().Validations() { + if val.HasError() { + error.validationErrors = append(error.validationErrors, val) + } + } + + if len(error.validationErrors) > 0 { + widgetErrors = append(widgetErrors, error) + } + } + + return widgetErrors +} + +func (err widgetError) errorMessages() (messages []string) { + widgetMessage := fmt.Sprintf( + "%s in %s configuration", + aurora.Red("Errors"), + aurora.Yellow( + fmt.Sprintf( + "%s.position", + err.name, + ), + ), + ) + messages = append(messages, widgetMessage) + + for _, e := range err.validationErrors { + configMessage := fmt.Sprintf(" - %s\t%s %v", e.String(), aurora.Red("Error:"), e.Error()) + + messages = append(messages, configMessage) + } + + return messages +} diff --git a/app/module_validator_test.go b/app/module_validator_test.go index 39914bd1..83108e6b 100644 --- a/app/module_validator_test.go +++ b/app/module_validator_test.go @@ -1,11 +1,102 @@ package app import ( + "fmt" "testing" + "github.com/logrusorgru/aurora" + "github.com/olebedev/config" "github.com/stretchr/testify/assert" + "github.com/wtfutil/wtf/wtf" +) + +const ( + valid = ` +wtf: + mods: + clocks: + enabled: true + position: + top: 0 + left: 0 + height: 1 + width: 1 + refreshInterval: 30` + + invalid = ` +wtf: + mods: + clocks: + enabled: true + position: + top: abc + left: 0 + height: 1 + width: 1 + refreshInterval: 30` ) func Test_NewModuleValidator(t *testing.T) { assert.IsType(t, &ModuleValidator{}, NewModuleValidator()) } + +func Test_validate(t *testing.T) { + tests := []struct { + name string + moduleName string + config *config.Config + expected []string + }{ + { + name: "valid config", + moduleName: "clocks", + config: func() *config.Config { + cfg, _ := config.ParseYaml(valid) + return cfg + }(), + expected: []string{}, + }, + { + name: "invalid config", + moduleName: "clocks", + config: func() *config.Config { + cfg, _ := config.ParseYaml(invalid) + return cfg + }(), + expected: []string{ + fmt.Sprintf("%s in %s configuration", aurora.Red("Errors"), aurora.Yellow("clocks.position")), + fmt.Sprintf( + " - Invalid value for %s: 0 %s strconv.ParseInt: parsing \"abc\": invalid syntax", + aurora.Yellow("top"), + aurora.Red("Error:"), + ), + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + widget := MakeWidget(nil, nil, tt.moduleName, tt.config) + + if widget == nil { + t.Logf("Failed to create widget %s", tt.moduleName) + t.FailNow() + } + + errs := validate([]wtf.Wtfable{widget}) + + if len(tt.expected) == 0 { + assert.Empty(t, errs) + } else { + assert.NotEmpty(t, errs) + + var actual []string + for _, err := range errs { + actual = append(actual, err.errorMessages()...) + } + + assert.Equal(t, tt.expected, actual) + } + }) + } +}