github.com/getgauge/gauge@v1.6.9/reporter/simpleConsole.go (about) 1 /*---------------------------------------------------------------- 2 * Copyright (c) ThoughtWorks, Inc. 3 * Licensed under the Apache License, Version 2.0 4 * See LICENSE in the project root for license information. 5 *----------------------------------------------------------------*/ 6 7 package reporter 8 9 import ( 10 "fmt" 11 "io" 12 "strings" 13 "sync" 14 15 "github.com/getgauge/gauge-proto/go/gauge_messages" 16 "github.com/getgauge/gauge/execution/result" 17 "github.com/getgauge/gauge/gauge" 18 "github.com/getgauge/gauge/logger" 19 ) 20 21 type simpleConsole struct { 22 mu *sync.Mutex 23 indentation int 24 writer io.Writer 25 } 26 27 func newSimpleConsole(out io.Writer) *simpleConsole { 28 return &simpleConsole{mu: &sync.Mutex{}, writer: out} 29 } 30 31 func (sc *simpleConsole) SuiteStart() { 32 } 33 34 func (sc *simpleConsole) SpecStart(spec *gauge.Specification, res result.Result) { 35 if res.(*result.SpecResult).Skipped { 36 return 37 } 38 sc.mu.Lock() 39 defer sc.mu.Unlock() 40 formattedHeading := formatSpec(spec.Heading.Value) 41 logger.Info(false, formattedHeading) 42 fmt.Fprintf(sc.writer, "%s%s", formattedHeading, newline) 43 } 44 45 func (sc *simpleConsole) SpecEnd(spec *gauge.Specification, res result.Result) { 46 if res.(*result.SpecResult).Skipped { 47 return 48 } 49 sc.mu.Lock() 50 defer sc.mu.Unlock() 51 printHookFailureSC(sc, res, res.GetPreHook) 52 printHookFailureSC(sc, res, res.GetPostHook) 53 fmt.Fprintln(sc.writer) 54 } 55 56 func (sc *simpleConsole) ScenarioStart(scenario *gauge.Scenario, i *gauge_messages.ExecutionInfo, res result.Result) { 57 if res.(*result.ScenarioResult).ProtoScenario.ExecutionStatus == gauge_messages.ExecutionStatus_SKIPPED { 58 return 59 } 60 sc.mu.Lock() 61 defer sc.mu.Unlock() 62 sc.indentation += scenarioIndentation 63 formattedHeading := formatScenario(scenario.Heading.Value) 64 logger.Info(false, formattedHeading) 65 fmt.Fprintf(sc.writer, "%s%s", indent(formattedHeading, sc.indentation), newline) 66 } 67 68 func (sc *simpleConsole) ScenarioEnd(scenario *gauge.Scenario, res result.Result, i *gauge_messages.ExecutionInfo) { 69 if res.(*result.ScenarioResult).ProtoScenario.ExecutionStatus == gauge_messages.ExecutionStatus_SKIPPED { 70 return 71 } 72 sc.mu.Lock() 73 defer sc.mu.Unlock() 74 printHookFailureSC(sc, res, res.GetPreHook) 75 printHookFailureSC(sc, res, res.GetPostHook) 76 sc.indentation -= scenarioIndentation 77 } 78 79 func (sc *simpleConsole) StepStart(stepText string) { 80 sc.mu.Lock() 81 defer sc.mu.Unlock() 82 sc.indentation += stepIndentation 83 logger.Debug(false, stepText) 84 if Verbose { 85 fmt.Fprintf(sc.writer, "%s%s", indent(strings.TrimSpace(stepText), sc.indentation), newline) 86 } 87 } 88 89 func (sc *simpleConsole) StepEnd(step gauge.Step, res result.Result, execInfo *gauge_messages.ExecutionInfo) { 90 sc.mu.Lock() 91 defer sc.mu.Unlock() 92 printHookFailureSC(sc, res, res.GetPreHook) 93 stepRes := res.(*result.StepResult) 94 if stepRes.GetStepFailed() { 95 stepText := prepStepMsg(step.LineText) 96 logger.Error(false, stepText) 97 98 specInfo := prepSpecInfo(execInfo.GetCurrentSpec().GetFileName(), step.LineNo, step.InConcept()) 99 logger.Error(false, specInfo) 100 101 errMsg := prepErrorMessage(stepRes.ProtoStepExecResult().GetExecutionResult().GetErrorMessage()) 102 logger.Error(false, errMsg) 103 stacktrace := prepStacktrace(stepRes.ProtoStepExecResult().GetExecutionResult().GetStackTrace()) 104 logger.Error(false, stacktrace) 105 106 msg := formatErrorFragment(stepText, sc.indentation) + formatErrorFragment(specInfo, sc.indentation) + formatErrorFragment(errMsg, sc.indentation) + formatErrorFragment(stacktrace, sc.indentation) 107 fmt.Fprint(sc.writer, msg) 108 } 109 printHookFailureSC(sc, res, res.GetPostHook) 110 sc.indentation -= stepIndentation 111 } 112 113 func (sc *simpleConsole) ConceptStart(conceptHeading string) { 114 sc.mu.Lock() 115 defer sc.mu.Unlock() 116 sc.indentation += stepIndentation 117 logger.Debug(false, conceptHeading) 118 if Verbose { 119 fmt.Fprintf(sc.writer, "%s%s", indent(strings.TrimSpace(conceptHeading), sc.indentation), newline) 120 } 121 } 122 123 func (sc *simpleConsole) ConceptEnd(res result.Result) { 124 sc.mu.Lock() 125 defer sc.mu.Unlock() 126 sc.indentation -= stepIndentation 127 } 128 129 func (sc *simpleConsole) SuiteEnd(res result.Result) { 130 sc.mu.Lock() 131 defer sc.mu.Unlock() 132 printHookFailureSC(sc, res, res.GetPreHook) 133 printHookFailureSC(sc, res, res.GetPostHook) 134 suiteRes := res.(*result.SuiteResult) 135 for _, e := range suiteRes.UnhandledErrors { 136 logger.Error(false, e.Error()) 137 fmt.Fprint(sc.writer, indent(e.Error(), sc.indentation+errorIndentation)+newline) 138 } 139 } 140 141 func (sc *simpleConsole) DataTable(table string) { 142 sc.mu.Lock() 143 defer sc.mu.Unlock() 144 logger.Debug(false, table) 145 fmt.Fprint(sc.writer, table) 146 } 147 148 func (sc *simpleConsole) Errorf(err string, args ...interface{}) { 149 sc.mu.Lock() 150 defer sc.mu.Unlock() 151 errorMessage := fmt.Sprintf(err, args...) 152 logger.Error(false, errorMessage) 153 errorString := indent(errorMessage, sc.indentation+errorIndentation) 154 fmt.Fprintf(sc.writer, "%s%s", errorString, newline) 155 } 156 157 func (sc *simpleConsole) Write(b []byte) (int, error) { 158 sc.mu.Lock() 159 defer sc.mu.Unlock() 160 fmt.Fprint(sc.writer, string(b)) 161 return len(b), nil 162 } 163 164 func printHookFailureSC(sc *simpleConsole, res result.Result, hookFailure func() []*gauge_messages.ProtoHookFailure) { 165 if len(hookFailure()) > 0 { 166 errMsg := prepErrorMessage(hookFailure()[0].GetErrorMessage()) 167 logger.Error(false, errMsg) 168 stacktrace := prepStacktrace(hookFailure()[0].GetStackTrace()) 169 logger.Error(false, stacktrace) 170 fmt.Fprint(sc.writer, formatErrorFragment(errMsg, sc.indentation), formatErrorFragment(stacktrace, sc.indentation)) 171 } 172 }