gitee.com/mirrors/gauge@v1.0.6/reporter/verboseColoredConsole.go (about) 1 // Copyright 2015 ThoughtWorks, Inc. 2 3 // This file is part of Gauge. 4 5 // Gauge is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 10 // Gauge is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 15 // You should have received a copy of the GNU General Public License 16 // along with Gauge. If not, see <http://www.gnu.org/licenses/>. 17 18 package reporter 19 20 import ( 21 "bytes" 22 "fmt" 23 "io" 24 "strings" 25 26 "github.com/apoorvam/goterminal" 27 ct "github.com/daviddengcn/go-colortext" 28 "github.com/getgauge/gauge/execution/result" 29 "github.com/getgauge/gauge/gauge" 30 "github.com/getgauge/gauge/gauge_messages" 31 "github.com/getgauge/gauge/logger" 32 ) 33 34 type verboseColoredConsole struct { 35 writer *goterminal.Writer 36 headingBuffer bytes.Buffer 37 pluginMessagesBuffer bytes.Buffer 38 errorMessagesBuffer bytes.Buffer 39 indentation int 40 } 41 42 func newVerboseColoredConsole(out io.Writer) *verboseColoredConsole { 43 return &verboseColoredConsole{writer: goterminal.New(out)} 44 } 45 46 func (c *verboseColoredConsole) SuiteStart() { 47 } 48 49 func (c *verboseColoredConsole) SpecStart(spec *gauge.Specification, res result.Result) { 50 if res.(*result.SpecResult).Skipped { 51 return 52 } 53 msg := formatSpec(spec.Heading.Value) 54 logger.Info(false, msg) 55 c.displayMessage(msg+newline, ct.Cyan) 56 c.writer.Reset() 57 } 58 59 func (c *verboseColoredConsole) SpecEnd(spec *gauge.Specification, res result.Result) { 60 if res.(*result.SpecResult).Skipped { 61 return 62 } 63 printHookFailureVCC(c, res, res.GetPreHook) 64 printHookFailureVCC(c, res, res.GetPostHook) 65 c.displayMessage(newline, ct.None) 66 c.writer.Reset() 67 } 68 69 func (c *verboseColoredConsole) ScenarioStart(scenario *gauge.Scenario, i gauge_messages.ExecutionInfo, res result.Result) { 70 if res.(*result.ScenarioResult).ProtoScenario.ExecutionStatus == gauge_messages.ExecutionStatus_SKIPPED { 71 return 72 } 73 c.indentation += scenarioIndentation 74 msg := formatScenario(scenario.Heading.Value) 75 logger.Info(false, msg) 76 77 indentedText := indent(msg+"\t", c.indentation) 78 c.displayMessage(indentedText+newline, ct.Yellow) 79 c.writer.Reset() 80 } 81 82 func (c *verboseColoredConsole) ScenarioEnd(scenario *gauge.Scenario, res result.Result, i gauge_messages.ExecutionInfo) { 83 if res.(*result.ScenarioResult).ProtoScenario.ExecutionStatus == gauge_messages.ExecutionStatus_SKIPPED { 84 return 85 } 86 printHookFailureVCC(c, res, res.GetPreHook) 87 printHookFailureVCC(c, res, res.GetPostHook) 88 89 c.writer.Reset() 90 c.indentation -= scenarioIndentation 91 } 92 93 func (c *verboseColoredConsole) StepStart(stepText string) { 94 c.resetBuffers() 95 c.writer.Reset() 96 97 c.indentation += stepIndentation 98 logger.Debug(false, stepText) 99 c.headingBuffer.WriteString(indent(strings.TrimSpace(stepText), c.indentation)) 100 c.displayMessage(c.headingBuffer.String()+newline, ct.None) 101 } 102 103 func (c *verboseColoredConsole) StepEnd(step gauge.Step, res result.Result, execInfo gauge_messages.ExecutionInfo) { 104 stepRes := res.(*result.StepResult) 105 c.writer.Clear() 106 if !(hookFailed(res.GetPreHook) || hookFailed(res.GetPostHook)) { 107 if stepRes.GetStepFailed() { 108 c.displayMessage(c.headingBuffer.String()+"\t ...[FAIL]\n", ct.Red) 109 } else { 110 c.displayMessage(c.headingBuffer.String()+"\t ...[PASS]\n", ct.Green) 111 } 112 } else { 113 c.displayMessage(c.headingBuffer.String()+newline, ct.None) 114 } 115 printHookFailureVCC(c, res, res.GetPreHook) 116 c.displayMessage(c.pluginMessagesBuffer.String(), ct.None) 117 c.displayMessage(c.errorMessagesBuffer.String(), ct.Red) 118 if stepRes.GetStepFailed() { 119 stepText := prepStepMsg(step.LineText) 120 logger.Error(false, stepText) 121 errMsg := prepErrorMessage(stepRes.ProtoStepExecResult().GetExecutionResult().GetErrorMessage()) 122 logger.Error(false, errMsg) 123 specInfo := prepSpecInfo(execInfo.GetCurrentSpec().GetFileName(), step.LineNo, step.InConcept()) 124 logger.Error(false, specInfo) 125 stacktrace := prepStacktrace(stepRes.ProtoStepExecResult().GetExecutionResult().GetStackTrace()) 126 logger.Error(false, stacktrace) 127 128 msg := formatErrorFragment(stepText, c.indentation) + formatErrorFragment(specInfo, c.indentation) + formatErrorFragment(errMsg, c.indentation) + formatErrorFragment(stacktrace, c.indentation) 129 130 c.displayMessage(msg, ct.Red) 131 } 132 printHookFailureVCC(c, res, res.GetPostHook) 133 c.indentation -= stepIndentation 134 c.writer.Reset() 135 c.resetBuffers() 136 } 137 138 func (c *verboseColoredConsole) ConceptStart(conceptHeading string) { 139 c.indentation += stepIndentation 140 logger.Debug(false, conceptHeading) 141 c.displayMessage(indent(strings.TrimSpace(conceptHeading), c.indentation)+newline, ct.Magenta) 142 c.writer.Reset() 143 } 144 145 func (c *verboseColoredConsole) ConceptEnd(res result.Result) { 146 c.indentation -= stepIndentation 147 } 148 149 func (c *verboseColoredConsole) SuiteEnd(res result.Result) { 150 suiteRes := res.(*result.SuiteResult) 151 printHookFailureVCC(c, res, res.GetPreHook) 152 printHookFailureVCC(c, res, res.GetPostHook) 153 for _, e := range suiteRes.UnhandledErrors { 154 logger.Error(false, e.Error()) 155 c.displayMessage(indent(e.Error(), c.indentation+errorIndentation)+newline, ct.Red) 156 } 157 } 158 159 func (c *verboseColoredConsole) DataTable(table string) { 160 logger.Debug(false, table) 161 c.displayMessage(table, ct.Yellow) 162 c.writer.Reset() 163 } 164 165 func (c *verboseColoredConsole) Errorf(text string, args ...interface{}) { 166 msg := fmt.Sprintf(text, args...) 167 logger.Error(false, msg) 168 msg = indent(msg, c.indentation+errorIndentation) + newline 169 c.displayMessage(msg, ct.Red) 170 c.errorMessagesBuffer.WriteString(msg) 171 } 172 173 // Write writes the bytes to console via goterminal's writer. 174 // This is called when any sysouts are to be printed on console. 175 func (c *verboseColoredConsole) Write(b []byte) (int, error) { 176 text := string(b) 177 c.pluginMessagesBuffer.WriteString(text) 178 c.displayMessage(text, ct.None) 179 return len(b), nil 180 } 181 182 func (c *verboseColoredConsole) displayMessage(msg string, color ct.Color) { 183 ct.Foreground(color, false) 184 defer ct.ResetColor() 185 fmt.Fprint(c.writer, msg) 186 c.writer.Print() 187 } 188 189 func (c *verboseColoredConsole) resetBuffers() { 190 c.headingBuffer.Reset() 191 c.pluginMessagesBuffer.Reset() 192 c.errorMessagesBuffer.Reset() 193 } 194 195 func printHookFailureVCC(c *verboseColoredConsole, res result.Result, hookFailure func() []*gauge_messages.ProtoHookFailure) bool { 196 if hookFailed(hookFailure) { 197 errMsg := prepErrorMessage(hookFailure()[0].GetErrorMessage()) 198 logger.Error(false, errMsg) 199 stacktrace := prepStacktrace(hookFailure()[0].GetStackTrace()) 200 logger.Error(false, stacktrace) 201 c.displayMessage(formatErrorFragment(errMsg, c.indentation)+formatErrorFragment(stacktrace, c.indentation), ct.Red) 202 return false 203 } 204 return true 205 } 206 207 func hookFailed(hookFailure func() []*gauge_messages.ProtoHookFailure) bool { 208 return len(hookFailure()) > 0 209 }