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 }