github.com/getgauge/gauge@v1.6.9/gauge/protoConverters.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 gauge 8 9 import ( 10 "time" 11 12 "github.com/getgauge/gauge-proto/go/gauge_messages" 13 "github.com/getgauge/gauge/execution/result" 14 ) 15 16 func ConvertToProtoItem(item Item) *gauge_messages.ProtoItem { 17 switch item.Kind() { 18 case ScenarioKind: 19 return convertToProtoScenarioItem(item.(*Scenario)) 20 case StepKind: 21 return convertToProtoStepItem(item.(*Step)) 22 case CommentKind: 23 return convertToProtoCommentItem(item.(*Comment)) 24 case DataTableKind: 25 return convertToProtoDataTableItem(item.(*DataTable)) 26 case TagKind: 27 return convertToProtoTagItem(item.(*Tags)) 28 case TearDownKind: 29 teardown := item.(*TearDown) 30 return convertToProtoCommentItem(&Comment{LineNo: teardown.LineNo, Value: teardown.Value}) 31 } 32 return nil 33 } 34 35 func convertToProtoTagItem(tags *Tags) *gauge_messages.ProtoItem { 36 return &gauge_messages.ProtoItem{ItemType: gauge_messages.ProtoItem_Tags, Tags: convertToProtoTags(tags)} 37 } 38 39 func convertToProtoStepItem(step *Step) *gauge_messages.ProtoItem { 40 if step.IsConcept { 41 return convertToProtoConcept(step) 42 } 43 return &gauge_messages.ProtoItem{ItemType: gauge_messages.ProtoItem_Step, Step: convertToProtoStep(step)} 44 } 45 46 func convertToProtoStepItems(steps []*Step) []*gauge_messages.ProtoItem { 47 protoItems := make([]*gauge_messages.ProtoItem, 0) 48 for _, step := range steps { 49 protoItems = append(protoItems, convertToProtoStepItem(step)) 50 } 51 return protoItems 52 } 53 54 func convertToProtoScenarioItem(scenario *Scenario) *gauge_messages.ProtoItem { 55 scenarioItems := make([]*gauge_messages.ProtoItem, 0) 56 for _, item := range scenario.Items { 57 scenarioItems = append(scenarioItems, ConvertToProtoItem(item)) 58 } 59 protoScenario := NewProtoScenario(scenario) 60 protoScenario.ScenarioItems = scenarioItems 61 return &gauge_messages.ProtoItem{ItemType: gauge_messages.ProtoItem_Scenario, Scenario: protoScenario} 62 } 63 64 func convertToProtoConcept(concept *Step) *gauge_messages.ProtoItem { 65 protoConcept := &gauge_messages.ProtoConcept{ConceptStep: convertToProtoStep(concept), Steps: convertToProtoStepItems(concept.ConceptSteps)} 66 protoConceptItem := &gauge_messages.ProtoItem{ItemType: gauge_messages.ProtoItem_Concept, Concept: protoConcept} 67 return protoConceptItem 68 } 69 70 func convertToProtoStep(step *Step) *gauge_messages.ProtoStep { 71 return &gauge_messages.ProtoStep{ActualText: step.LineText, ParsedText: step.Value, Fragments: makeFragmentsCopy(step.Fragments)} 72 } 73 74 func convertToProtoTags(tags *Tags) *gauge_messages.ProtoTags { 75 return &gauge_messages.ProtoTags{Tags: tags.Values()} 76 } 77 78 func makeFragmentsCopy(fragments []*gauge_messages.Fragment) []*gauge_messages.Fragment { 79 copiedFragments := make([]*gauge_messages.Fragment, 0) 80 for _, fragment := range fragments { 81 copiedFragments = append(copiedFragments, makeFragmentCopy(fragment)) 82 } 83 return copiedFragments 84 } 85 86 func makeFragmentCopy(fragment *gauge_messages.Fragment) *gauge_messages.Fragment { 87 if fragment.GetFragmentType() == gauge_messages.Fragment_Text { 88 return &gauge_messages.Fragment{FragmentType: gauge_messages.Fragment_Text, Text: fragment.GetText()} 89 } else { 90 return &gauge_messages.Fragment{FragmentType: gauge_messages.Fragment_Parameter, Parameter: makeParameterCopy(fragment.Parameter)} 91 } 92 } 93 94 func makeParameterCopy(parameter *gauge_messages.Parameter) *gauge_messages.Parameter { 95 switch parameter.GetParameterType() { 96 case gauge_messages.Parameter_Static: 97 return &gauge_messages.Parameter{ParameterType: gauge_messages.Parameter_Static, Value: parameter.GetValue(), Name: parameter.GetName()} 98 case gauge_messages.Parameter_Dynamic: 99 return &gauge_messages.Parameter{ParameterType: gauge_messages.Parameter_Dynamic, Value: parameter.GetValue(), Name: parameter.GetName()} 100 case gauge_messages.Parameter_Table: 101 return &gauge_messages.Parameter{ParameterType: gauge_messages.Parameter_Table, Table: makeTableCopy(parameter.GetTable()), Name: parameter.GetName()} 102 case gauge_messages.Parameter_Special_String: 103 return &gauge_messages.Parameter{ParameterType: gauge_messages.Parameter_Special_String, Value: parameter.GetValue(), Name: parameter.GetName()} 104 case gauge_messages.Parameter_Special_Table: 105 return &gauge_messages.Parameter{ParameterType: gauge_messages.Parameter_Special_Table, Table: makeTableCopy(parameter.GetTable()), Name: parameter.GetName()} 106 } 107 return parameter 108 } 109 110 func makeTableCopy(table *gauge_messages.ProtoTable) *gauge_messages.ProtoTable { 111 copiedTable := &gauge_messages.ProtoTable{} 112 copiedTable.Headers = makeProtoTableRowCopy(table.GetHeaders()) 113 114 copiedRows := make([]*gauge_messages.ProtoTableRow, 0) 115 for _, tableRow := range table.GetRows() { 116 copiedRows = append(copiedRows, makeProtoTableRowCopy(tableRow)) 117 } 118 copiedTable.Rows = copiedRows 119 return copiedTable 120 } 121 122 func makeProtoTableRowCopy(tableRow *gauge_messages.ProtoTableRow) *gauge_messages.ProtoTableRow { 123 copiedCells := make([]string, 0) 124 return &gauge_messages.ProtoTableRow{Cells: append(copiedCells, tableRow.GetCells()...)} 125 } 126 127 func convertToProtoCommentItem(comment *Comment) *gauge_messages.ProtoItem { 128 return &gauge_messages.ProtoItem{ItemType: gauge_messages.ProtoItem_Comment, Comment: &gauge_messages.ProtoComment{Text: comment.Value}} 129 } 130 131 func convertToProtoDataTableItem(dataTable *DataTable) *gauge_messages.ProtoItem { 132 return &gauge_messages.ProtoItem{ItemType: gauge_messages.ProtoItem_Table, Table: ConvertToProtoTable(dataTable.Table)} 133 } 134 135 func convertToProtoParameter(arg *StepArg) *gauge_messages.Parameter { 136 switch arg.ArgType { 137 case Static: 138 return &gauge_messages.Parameter{ParameterType: gauge_messages.Parameter_Static, Value: arg.Value, Name: arg.Name} 139 case Dynamic: 140 return &gauge_messages.Parameter{ParameterType: gauge_messages.Parameter_Dynamic, Value: arg.Value, Name: arg.Name} 141 case TableArg: 142 return &gauge_messages.Parameter{ParameterType: gauge_messages.Parameter_Table, Table: ConvertToProtoTable(&arg.Table), Name: arg.Name} 143 case SpecialString: 144 return &gauge_messages.Parameter{ParameterType: gauge_messages.Parameter_Special_String, Value: arg.Value, Name: arg.Name} 145 case SpecialTable: 146 return &gauge_messages.Parameter{ParameterType: gauge_messages.Parameter_Special_Table, Table: ConvertToProtoTable(&arg.Table), Name: arg.Name} 147 } 148 return nil 149 } 150 151 func ConvertToProtoTable(table *Table) *gauge_messages.ProtoTable { 152 if table == nil { 153 return nil 154 } 155 protoTableParam := &gauge_messages.ProtoTable{Rows: make([]*gauge_messages.ProtoTableRow, 0)} 156 protoTableParam.Headers = &gauge_messages.ProtoTableRow{Cells: table.Headers} 157 for _, row := range table.Rows() { // nolint 158 protoTableParam.Rows = append(protoTableParam.Rows, &gauge_messages.ProtoTableRow{Cells: row}) 159 } 160 return protoTableParam 161 } 162 163 func ConvertToProtoSuiteResult(suiteResult *result.SuiteResult) *gauge_messages.ProtoSuiteResult { 164 protoSuiteResult := &gauge_messages.ProtoSuiteResult{ 165 PreHookFailure: suiteResult.PreSuite, 166 PostHookFailure: suiteResult.PostSuite, 167 Failed: suiteResult.IsFailed, 168 SpecsFailedCount: int32(suiteResult.SpecsFailedCount), 169 ExecutionTime: suiteResult.ExecutionTime, 170 SpecResults: convertToProtoSpecResults(suiteResult.SpecResults), 171 SuccessRate: getSuccessRate(len(suiteResult.SpecResults), suiteResult.SpecsFailedCount+suiteResult.SpecsSkippedCount), 172 Environment: suiteResult.Environment, 173 Tags: suiteResult.Tags, 174 ProjectName: suiteResult.ProjectName, 175 Timestamp: suiteResult.Timestamp, 176 SpecsSkippedCount: int32(suiteResult.SpecsSkippedCount), 177 PreHookMessages: suiteResult.PreHookMessages, 178 PostHookMessages: suiteResult.PostHookMessages, 179 PreHookScreenshotFiles: suiteResult.PreHookScreenshotFiles, 180 PostHookScreenshotFiles: suiteResult.PostHookScreenshotFiles, 181 PreHookScreenshots: suiteResult.PreHookScreenshots, 182 PostHookScreenshots: suiteResult.PostHookScreenshots, 183 } 184 return protoSuiteResult 185 } 186 187 func ConvertToProtoSpecResult(specResult *result.SpecResult) *gauge_messages.ProtoSpecResult { 188 return convertToProtoSpecResult(specResult) 189 } 190 191 func ConvertToProtoScenarioResult(scenarioResult *result.ScenarioResult) *gauge_messages.ProtoScenarioResult { 192 return &gauge_messages.ProtoScenarioResult{ 193 ProtoItem: &gauge_messages.ProtoItem{ 194 ItemType: gauge_messages.ProtoItem_Scenario, 195 Scenario: scenarioResult.ProtoScenario, 196 }, 197 ExecutionTime: scenarioResult.ExecTime(), 198 Timestamp: time.Now().Format(time.RFC3339), 199 } 200 } 201 202 func ConvertToProtoStepResult(stepResult *result.StepResult) *gauge_messages.ProtoStepResult { 203 return &gauge_messages.ProtoStepResult{ 204 ProtoItem: &gauge_messages.ProtoItem{ 205 ItemType: gauge_messages.ProtoItem_Step, 206 Step: stepResult.ProtoStep, 207 }, 208 ExecutionTime: stepResult.ExecTime(), 209 Timestamp: time.Now().Format(time.RFC3339), 210 } 211 } 212 213 func getSuccessRate(totalSpecs int, failedSpecs int) float32 { 214 if totalSpecs == 0 { 215 return 0 216 } 217 return (float32)(100.0 * (totalSpecs - failedSpecs) / totalSpecs) 218 } 219 220 func convertToProtoSpecResult(specResult *result.SpecResult) *gauge_messages.ProtoSpecResult { 221 return &gauge_messages.ProtoSpecResult{ 222 ProtoSpec: specResult.ProtoSpec, 223 ScenarioCount: int32(specResult.ScenarioCount), 224 ScenarioFailedCount: int32(specResult.ScenarioFailedCount), 225 Failed: specResult.IsFailed, 226 FailedDataTableRows: specResult.FailedDataTableRows, 227 ExecutionTime: specResult.ExecutionTime, 228 Skipped: specResult.Skipped, 229 ScenarioSkippedCount: int32(specResult.ScenarioSkippedCount), 230 Errors: specResult.Errors, 231 Timestamp: time.Now().Format(time.RFC3339), 232 } 233 } 234 235 func convertToProtoSpecResults(specResults []*result.SpecResult) []*gauge_messages.ProtoSpecResult { 236 protoSpecResults := make([]*gauge_messages.ProtoSpecResult, 0) 237 for _, specResult := range specResults { 238 protoSpecResults = append(protoSpecResults, convertToProtoSpecResult(specResult)) 239 } 240 return protoSpecResults 241 } 242 243 func ConvertToProtoSpec(spec *Specification) *gauge_messages.ProtoSpec { 244 protoSpec := newProtoSpec(spec) 245 if spec.DataTable.IsInitialized() { 246 protoSpec.IsTableDriven = true 247 } 248 var protoItems []*gauge_messages.ProtoItem 249 for _, item := range spec.Items { 250 protoItems = append(protoItems, ConvertToProtoItem(item)) 251 } 252 protoSpec.Items = protoItems 253 return protoSpec 254 } 255 256 func ConvertToProtoStepValue(stepValue *StepValue) *gauge_messages.ProtoStepValue { 257 return &gauge_messages.ProtoStepValue{ 258 StepValue: stepValue.StepValue, 259 ParameterizedStepValue: stepValue.ParameterizedStepValue, 260 Parameters: stepValue.Args, 261 } 262 } 263 264 func newProtoSpec(specification *Specification) *gauge_messages.ProtoSpec { 265 return &gauge_messages.ProtoSpec{ 266 Items: make([]*gauge_messages.ProtoItem, 0), 267 SpecHeading: specification.Heading.Value, 268 IsTableDriven: specification.DataTable.IsInitialized(), 269 FileName: specification.FileName, 270 Tags: getTags(specification.Tags), 271 } 272 273 } 274 275 func NewSpecResult(specification *Specification) *result.SpecResult { 276 return &result.SpecResult{ 277 ProtoSpec: newProtoSpec(specification), 278 FailedDataTableRows: make([]int32, 0), 279 } 280 } 281 282 func NewProtoScenario(scenario *Scenario) *gauge_messages.ProtoScenario { 283 return &gauge_messages.ProtoScenario{ 284 ScenarioHeading: scenario.Heading.Value, 285 Failed: false, 286 Skipped: false, 287 Tags: getTags(scenario.Tags), 288 Contexts: make([]*gauge_messages.ProtoItem, 0), 289 ExecutionTime: 0, 290 TearDownSteps: make([]*gauge_messages.ProtoItem, 0), 291 SkipErrors: make([]string, 0), 292 Span: &gauge_messages.Span{Start: int64(scenario.Span.Start), End: int64(scenario.Span.End)}, 293 ExecutionStatus: gauge_messages.ExecutionStatus_NOTEXECUTED, 294 } 295 } 296 297 func getTags(tags *Tags) []string { 298 if tags != nil { 299 return tags.Values() 300 } 301 return make([]string, 0) 302 } 303 304 func ConvertToProtoExecutionArg(args []*ExecutionArg) []*gauge_messages.ExecutionArg { 305 execArgs := []*gauge_messages.ExecutionArg{} 306 for _, arg := range args { 307 execArgs = append(execArgs, &gauge_messages.ExecutionArg{ 308 FlagName: arg.Name, 309 FlagValue: arg.Value, 310 }) 311 } 312 return execArgs 313 }