diff --git a/internal/formatters/fmt_ast.go b/internal/formatters/fmt_ast.go index 20c2c42..bd5174d 100644 --- a/internal/formatters/fmt_ast.go +++ b/internal/formatters/fmt_ast.go @@ -3,7 +3,9 @@ package formatters import ( "fmt" "io" + "os" "sort" + "strconv" "strings" "unicode/utf8" @@ -11,6 +13,8 @@ import ( "git.golang1.ru/softonik/godog/colors" "git.golang1.ru/softonik/godog/formatters" + "git.golang1.ru/softonik/godog/internal/models" + "git.golang1.ru/softonik/godog/internal/utils" ) func ASTRegister() { @@ -224,11 +228,124 @@ func (f *AST) Summary() { fmt.Fprintln(f.out, s(f.indent)+red(scenarioDesc)+line(feature.Uri, astScenario.Location)) fmt.Fprintln(f.out, s(f.indent*2)+red(stepDesc)+line(feature.Uri, astStep.Location)) - fmt.Fprintln(f.out, s(f.indent*3)+red("Error: ")+redb(fmt.Sprintf("%+v", fail.Err))+"\n") + fmt.Fprint(f.out, s(f.indent*3)+redb(fmt.Sprintf("%+v", fail.Err))) } } - f.Base.Summary() + f.SummaryBottom() +} +func (f *AST) SummaryBottom() { + var totalSc, passedSc, undefinedSc int + var totalSt, passedSt, failedSt, skippedSt, pendingSt, undefinedSt, ambiguousSt int + + pickleResults := f.Storage.MustGetPickleResults() + for _, pr := range pickleResults { + var prStatus models.StepResultStatus + totalSc++ + + pickleStepResults := f.Storage.MustGetPickleStepResultsByPickleID(pr.PickleID) + + if len(pickleStepResults) == 0 { + prStatus = undefined + } + + for _, sr := range pickleStepResults { + totalSt++ + + switch sr.Status { + case passed: + passedSt++ + case failed: + prStatus = failed + failedSt++ + case ambiguous: + prStatus = ambiguous + ambiguousSt++ + case skipped: + skippedSt++ + case undefined: + prStatus = undefined + undefinedSt++ + case pending: + prStatus = pending + pendingSt++ + } + } + + if prStatus == passed { + passedSc++ + } else if prStatus == undefined { + undefinedSc++ + } + } + + var steps, parts, scenarios []string + if passedSt > 0 { + steps = append(steps, green(fmt.Sprintf("%d passed", passedSt))) + } + if failedSt > 0 { + parts = append(parts, red(fmt.Sprintf("%d failed", failedSt))) + steps = append(steps, red(fmt.Sprintf("%d failed", failedSt))) + } + if pendingSt > 0 { + parts = append(parts, yellow(fmt.Sprintf("%d pending", pendingSt))) + steps = append(steps, yellow(fmt.Sprintf("%d pending", pendingSt))) + } + if ambiguousSt > 0 { + parts = append(parts, yellow(fmt.Sprintf("%d ambiguous", ambiguousSt))) + steps = append(steps, yellow(fmt.Sprintf("%d ambiguous", ambiguousSt))) + } + if undefinedSt > 0 { + parts = append(parts, yellow(fmt.Sprintf("%d undefined", undefinedSc))) + steps = append(steps, yellow(fmt.Sprintf("%d undefined", undefinedSt))) + } else if undefinedSc > 0 { + // there may be some scenarios without steps + parts = append(parts, yellow(fmt.Sprintf("%d undefined", undefinedSc))) + } + if skippedSt > 0 { + steps = append(steps, cyan(fmt.Sprintf("%d skipped", skippedSt))) + } + if passedSc > 0 { + scenarios = append(scenarios, green(fmt.Sprintf("%d passed", passedSc))) + } + scenarios = append(scenarios, parts...) + + testRunStartedAt := f.Storage.MustGetTestRunStarted().StartedAt + elapsed := utils.TimeNowFunc().Sub(testRunStartedAt) + + fmt.Fprintln(f.out, "") + + if totalSc == 0 { + fmt.Fprintln(f.out, "No scenarios") + } else { + fmt.Fprintf(f.out, "%d scenarios (%s), ", totalSc, strings.Join(scenarios, ", ")) + } + + if totalSt == 0 { + fmt.Fprintln(f.out, "No steps") + } else { + fmt.Fprintf(f.out, "%d steps (%s)\n", totalSt, strings.Join(steps, ", ")) + } + + elapsedString := elapsed.String() + if elapsed.Nanoseconds() == 0 { + // go 1.5 and 1.6 prints 0 instead of 0s, if duration is zero. + elapsedString = "0s" + } + fmt.Fprintln(f.out, elapsedString) + + // prints used randomization seed + seed, err := strconv.ParseInt(os.Getenv("GODOG_SEED"), 10, 64) + if err == nil && seed != 0 { + fmt.Fprintln(f.out, "") + fmt.Fprintln(f.out, "Randomized with seed:", colors.Yellow(seed)) + } + + if text := f.Snippets(); text != "" { + fmt.Fprintln(f.out, "") + fmt.Fprintln(f.out, yellow("You can implement step definitions for undefined steps with these snippets:")) + fmt.Fprintln(f.out, yellow(text)) + } } func (f *AST) printOutlineExample(pickle *messages.Pickle, step *messages.PickleStep, backgroundSteps int) {