go-shout/format.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)
}