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  }