github.com/ezbuy/gauge@v0.9.4-0.20171013092048-7ac5bd3931cd/parser/dataTableSpecs.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 parser
    19  
    20  import "github.com/getgauge/gauge/gauge"
    21  
    22  // Creates a spec for each data table row
    23  func GetSpecsForDataTableRows(s []*gauge.Specification, errMap *gauge.BuildErrors) (specs []*gauge.Specification) {
    24  	for _, spec := range s {
    25  		if spec.DataTable.IsInitialized() {
    26  			if spec.UsesArgsInContextTeardown(spec.DataTable.Table.Headers...) {
    27  				specs = append(specs, createSpecsForTableRows(spec, spec.Scenarios, errMap)...)
    28  			} else {
    29  				nonTableRelatedScenarios, tableRelatedScenarios := FilterTableRelatedScenarios(spec.Scenarios, func(scenario *gauge.Scenario) bool {
    30  					return scenario.UsesArgsInSteps(spec.DataTable.Table.Headers...)
    31  				})
    32  				if len(tableRelatedScenarios) > 0 {
    33  					s := createSpecsForTableRows(spec, tableRelatedScenarios, errMap)
    34  					s[0].Scenarios = append(s[0].Scenarios, nonTableRelatedScenarios...)
    35  					specs = append(specs, s...)
    36  				} else {
    37  					specs = append(specs, createSpec(copyScenarios(nonTableRelatedScenarios, gauge.Table{}, 0, errMap), &gauge.Table{}, spec, errMap))
    38  				}
    39  			}
    40  		} else {
    41  			specs = append(specs, spec)
    42  		}
    43  	}
    44  	return
    45  }
    46  
    47  func createSpecsForTableRows(spec *gauge.Specification, scns []*gauge.Scenario, errMap *gauge.BuildErrors) (specs []*gauge.Specification) {
    48  	for i := range spec.DataTable.Table.Rows() {
    49  		t := getTableWithOneRow(spec.DataTable.Table, i)
    50  		newSpec := createSpec(copyScenarios(scns, *t, i, errMap), t, spec, errMap)
    51  		specs = append(specs, newSpec)
    52  	}
    53  	return
    54  }
    55  
    56  func createSpec(scns []*gauge.Scenario, table *gauge.Table, spec *gauge.Specification, errMap *gauge.BuildErrors) *gauge.Specification {
    57  	dt := &gauge.DataTable{Table: *table, Value: spec.DataTable.Value, LineNo: spec.DataTable.LineNo, IsExternal: spec.DataTable.IsExternal}
    58  	s := &gauge.Specification{DataTable: *dt, FileName: spec.FileName, Heading: spec.Heading, Scenarios: scns, Contexts: spec.Contexts, TearDownSteps: spec.TearDownSteps, Tags: spec.Tags}
    59  	index := 0
    60  	for _, item := range spec.Items {
    61  		if item.Kind() == gauge.DataTableKind {
    62  			item = dt
    63  		} else if item.Kind() == gauge.ScenarioKind {
    64  			if len(scns) <= index {
    65  				continue
    66  			}
    67  			item = scns[index]
    68  			index++
    69  		}
    70  		s.Items = append(s.Items, item)
    71  	}
    72  	for i := index; i < len(scns); i++ {
    73  		s.Items = append(s.Items, scns[i])
    74  	}
    75  	if len(errMap.SpecErrs[spec]) > 0 {
    76  		errMap.SpecErrs[s] = errMap.SpecErrs[spec]
    77  	}
    78  	return s
    79  }
    80  
    81  func copyScenarios(scenarios []*gauge.Scenario, table gauge.Table, i int, errMap *gauge.BuildErrors) (scns []*gauge.Scenario) {
    82  	for _, scn := range scenarios {
    83  		newScn := &gauge.Scenario{
    84  			Steps:             scn.Steps,
    85  			Items:             scn.Items,
    86  			Heading:           scn.Heading,
    87  			DataTableRow:      table,
    88  			DataTableRowIndex: i,
    89  			Tags:              scn.Tags,
    90  			Comments:          scn.Comments,
    91  			Span:              scn.Span,
    92  		}
    93  		if len(errMap.ScenarioErrs[scn]) > 0 {
    94  			errMap.ScenarioErrs[newScn] = errMap.ScenarioErrs[scn]
    95  		}
    96  		scns = append(scns, newScn)
    97  	}
    98  	return
    99  }
   100  
   101  func getTableWithOneRow(t gauge.Table, i int) *gauge.Table {
   102  	var row [][]gauge.TableCell
   103  	for _, c := range t.Columns {
   104  		row = append(row, []gauge.TableCell{c[i]})
   105  	}
   106  	return gauge.NewTable(t.Headers, row, t.LineNo)
   107  }
   108  
   109  func FilterTableRelatedScenarios(scenarios []*gauge.Scenario, fun func(*gauge.Scenario) bool) (otherScenarios, tableRelatedScenarios []*gauge.Scenario) {
   110  	for _, scenario := range scenarios {
   111  		if fun(scenario) {
   112  			tableRelatedScenarios = append(tableRelatedScenarios, scenario)
   113  		} else {
   114  			otherScenarios = append(otherScenarios, scenario)
   115  		}
   116  	}
   117  	return
   118  }