140 lines
3.3 KiB
Go
140 lines
3.3 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
func evaluateFile(path string, results []CommandResult, fileError string) TestResult {
|
|
if fileError != "" {
|
|
return TestResult{
|
|
Path: path,
|
|
Passed: false,
|
|
CommandCount: len(results),
|
|
Error: fileError,
|
|
}
|
|
}
|
|
|
|
var failures []FailedCommand
|
|
|
|
for _, r := range results {
|
|
cmd := r.Command
|
|
outputMatches := matchOutput(cmd.Expected, r.Actual)
|
|
|
|
var exitCodeMismatch bool
|
|
switch cmd.ExitCodeType {
|
|
case ExitCodeNone:
|
|
exitCodeMismatch = r.ExitCode != 0
|
|
case ExitCodeWildcard:
|
|
exitCodeMismatch = r.ExitCode == 0
|
|
case ExitCodeExact:
|
|
exitCodeMismatch = r.ExitCode != cmd.ExitCodeValue
|
|
}
|
|
|
|
if !outputMatches || exitCodeMismatch {
|
|
var diffLines []DiffLine
|
|
if !outputMatches {
|
|
diffLines = diff(cmd.Expected, r.Actual)
|
|
}
|
|
failures = append(failures, FailedCommand{
|
|
Result: r,
|
|
DiffLines: diffLines,
|
|
ExitCodeMismatch: exitCodeMismatch,
|
|
})
|
|
}
|
|
}
|
|
|
|
return TestResult{
|
|
Path: path,
|
|
Passed: len(failures) == 0,
|
|
CommandCount: len(results),
|
|
Failures: failures,
|
|
}
|
|
}
|
|
|
|
func formatFailure(t TestResult) string {
|
|
var lines []string
|
|
|
|
lines = append(lines, red("FAIL "+t.Path))
|
|
|
|
if t.Error != "" {
|
|
lines = append(lines, " "+red(t.Error))
|
|
return strings.Join(lines, "\n")
|
|
}
|
|
|
|
for _, f := range t.Failures {
|
|
lines = append(lines, "")
|
|
lines = append(lines, " "+dim("$")+" "+f.Result.Command.Cmd)
|
|
|
|
if len(f.DiffLines) > 0 {
|
|
lines = append(lines, red(" expected:"))
|
|
for _, dl := range f.DiffLines {
|
|
switch dl.Kind {
|
|
case "expected":
|
|
lines = append(lines, red(" > ")+dl.Text)
|
|
case "equal":
|
|
lines = append(lines, " "+dl.Text)
|
|
case "context":
|
|
lines = append(lines, " "+dim(dl.Text))
|
|
}
|
|
}
|
|
lines = append(lines, green(" actual:"))
|
|
for _, dl := range f.DiffLines {
|
|
switch dl.Kind {
|
|
case "actual":
|
|
lines = append(lines, green(" > ")+dl.Text)
|
|
case "equal":
|
|
lines = append(lines, " "+dl.Text)
|
|
case "context":
|
|
lines = append(lines, " "+dim(dl.Text))
|
|
}
|
|
}
|
|
}
|
|
|
|
if f.ExitCodeMismatch {
|
|
cmd := f.Result.Command
|
|
var expectedStr string
|
|
switch cmd.ExitCodeType {
|
|
case ExitCodeNone:
|
|
expectedStr = "0"
|
|
case ExitCodeWildcard:
|
|
expectedStr = "non-zero"
|
|
case ExitCodeExact:
|
|
expectedStr = fmt.Sprintf("%d", cmd.ExitCodeValue)
|
|
}
|
|
lines = append(lines, red(fmt.Sprintf(" expected exit code: %s", expectedStr)))
|
|
lines = append(lines, green(fmt.Sprintf(" actual exit code: %d", f.Result.ExitCode)))
|
|
}
|
|
}
|
|
|
|
return strings.Join(lines, "\n")
|
|
}
|
|
|
|
func formatSummary(results []TestResult, elapsed time.Duration) string {
|
|
totalCommands := 0
|
|
failedCommands := 0
|
|
for _, r := range results {
|
|
totalCommands += r.CommandCount
|
|
failedCommands += len(r.Failures)
|
|
}
|
|
passedCommands := totalCommands - failedCommands
|
|
|
|
var parts []string
|
|
if passedCommands > 0 {
|
|
parts = append(parts, green(fmt.Sprintf("%d passed", passedCommands)))
|
|
}
|
|
if failedCommands > 0 {
|
|
parts = append(parts, red(fmt.Sprintf("%d failed", failedCommands)))
|
|
}
|
|
|
|
var timeStr string
|
|
if elapsed < time.Second {
|
|
timeStr = fmt.Sprintf("%dms", elapsed.Milliseconds())
|
|
} else {
|
|
timeStr = fmt.Sprintf("%.1fs", elapsed.Seconds())
|
|
}
|
|
|
|
return fmt.Sprintf("%s in %s", strings.Join(parts, ", "), timeStr)
|
|
}
|