commander-cli/commander

View on GitHub
pkg/runtime/validator.go

Summary

Maintainability
A
2 hrs
Test Coverage
A
100%
package runtime

import (
    "fmt"
    "log"
    "strings"

    "github.com/commander-cli/commander/v2/pkg/matcher"
)

// ValidationResult will be returned after the validation was executed
type ValidationResult struct {
    Success bool
    Diff    string
}

func newValidationResult(m matcher.MatcherResult) ValidationResult {
    return ValidationResult{
        Success: m.Success,
        Diff:    m.Diff,
    }
}

// Validate validates the test results with the expected values
// The test should hold the result and expected to validate the result
func Validate(test TestCase) TestResult {
    equalMatcher := matcher.NewMatcher(matcher.Equal)

    log.Println("title: '"+test.Title+"'", " Stdout-Expected: ", test.Expected.Stdout)
    matcherResult := validateExpectedOut(test.Result.Stdout, test.Expected.Stdout)
    log.Println("title: '"+test.Title+"'", " Stdout-Result: ", matcherResult.Success)
    if !matcherResult.Success {
        return TestResult{
            ValidationResult: newValidationResult(matcherResult),
            TestCase:         test,
            FailedProperty:   Stdout,
        }
    }

    log.Println("title: '"+test.Title+"'", " Stderr-Expected: ", test.Expected.Stderr)
    matcherResult = validateExpectedOut(test.Result.Stderr, test.Expected.Stderr)
    log.Println("title: '"+test.Title+"'", " Stderr-Result: ", matcherResult.Success)
    if !matcherResult.Success {
        return TestResult{
            ValidationResult: newValidationResult(matcherResult),
            TestCase:         test,
            FailedProperty:   Stderr,
        }
    }

    log.Println("title: '"+test.Title+"'", " Exit-Expected: ", test.Expected.ExitCode)
    matcherResult = equalMatcher.Match(test.Result.ExitCode, test.Expected.ExitCode)
    log.Println("title: '"+test.Title+"'", " Exit-Result: ", matcherResult.Success)
    if !matcherResult.Success {
        return TestResult{
            ValidationResult: newValidationResult(matcherResult),
            TestCase:         test,
            FailedProperty:   ExitCode,
        }
    }

    return TestResult{
        ValidationResult: newValidationResult(matcherResult),
        TestCase:         test,
    }
}

func validateExpectedOut(got string, expected ExpectedOut) matcher.MatcherResult {
    var m matcher.Matcher
    var result matcher.MatcherResult
    result.Success = true

    if expected.Exactly != "" {
        m = matcher.NewMatcher(matcher.Text)
        if result = m.Match(got, expected.Exactly); !result.Success {
            return result
        }
    }

    m = matcher.NewMatcher(matcher.Contains)
    for _, c := range expected.Contains {
        if result = m.Match(got, c); !result.Success {
            return result
        }
    }

    if expected.LineCount != 0 {
        result = validateExpectedLineCount(got, expected)
        if !result.Success {
            return result
        }
    }

    if len(expected.Lines) > 0 {
        result = validateExpectedLines(got, expected)
        if !result.Success {
            return result
        }
    }

    m = matcher.NewMatcher(matcher.NotContains)
    for _, c := range expected.NotContains {
        if result = m.Match(got, c); !result.Success {
            return result
        }
    }

    m = matcher.NewMatcher(matcher.JSON)
    for i, v := range expected.JSON {
        if result = m.Match(got, map[string]string{i: v}); !result.Success {
            return result
        }
    }

    m = matcher.NewMatcher(matcher.XML)
    for i, v := range expected.XML {
        if result = m.Match(got, map[string]string{i: v}); !result.Success {
            return result
        }
    }

    if expected.File != "" {
        m = matcher.NewMatcher(matcher.File)
        if result = m.Match(got, expected.File); !result.Success {
            return result
        }
    }

    return result
}

func validateExpectedLineCount(got string, expected ExpectedOut) matcher.MatcherResult {
    m := matcher.NewMatcher(matcher.Equal)
    count := strings.Count(got, getLineBreak()) + 1

    if got == "" {
        count = 0
    }

    return m.Match(count, expected.LineCount)
}

func validateExpectedLines(got string, expected ExpectedOut) matcher.MatcherResult {
    m := matcher.NewMatcher(matcher.Equal)
    actualLines := strings.Split(got, getLineBreak())
    result := matcher.MatcherResult{Success: true}

    for key, expectedLine := range expected.Lines {
        // line number 0 or below 0
        if key <= 0 {
            panic(fmt.Sprintf("Invalid line number given %d", key))
        }

        // line number exceeds result set
        if key > len(actualLines) {
            return matcher.MatcherResult{
                Success: false,
                Diff: fmt.Sprintf(
                    "Line number %d does not exists in result: \n\n%s",
                    key,
                    strings.Join(actualLines, "\n"),
                ),
            }
        }

        if result = m.Match(actualLines[key-1], expectedLine); !result.Success {
            return result
        }
    }

    return result
}

func getLineBreak() string {
    return "\n"
}