Repository: getgauge/gauge (go)

Issue:
Error while using multiple data tables in single spec
I am reporting this as bug, as suggested by shrikant. See https://groups.google.com/forum/m/#!topic/getgauge/dXYqv6e_ZvA

Hello, 
I am trying to run simple specification Gauge and Taiko, but getting error

organisation.spec:9 Multiple data table present, ignoring table

------------- SPEC File (Organisation.spec)  ----------------
# Organisationsverwaltung 

table: logindata.csv

* Als Benutzer <users> mit Passwort <pwd> anmelden

## Organisation auswählen 

table: orgdata.csv

* Gehe zu Partnerdaten
* Suche Organisation mit Organisationanummer <Organisationanummer>
* Eine Organisation mit Name <Organisationsname> wird angezeigt
----------------------------------------------------------------

Gauge version: 1.1.1
Commit Hash: 6e0d83f

Plugins
-------
html-report (4.0.12)
java (0.7.9)
js (2.3.12)
screenshot (0.0.1)
spectacle (0.1.4)

---------------------------------------------

Can someone help me on this or any workaround ?

Thanks
Sanjay 


Pull request description:
External table support for scenario
Fixes #1714 

Patch:
diff --git a/gauge/scenario.go b/gauge/scenario.go
index 52f39a1f..00f6a9ad 100644
--- a/gauge/scenario.go
+++ b/gauge/scenario.go
@@ -49,6 +49,10 @@ func (scenario *Scenario) AddTags(tags *Tags) {
 	scenario.AddItem(tags)
 }
 
+func (scenario *Scenario) AddExternalDataTable(externalTable *DataTable) {
+	scenario.DataTable = *externalTable
+	scenario.AddItem(externalTable)
+}
 func (scenario *Scenario) NTags() int {
 	if scenario.Tags == nil {
 		return 0
diff --git a/parser/convert.go b/parser/convert.go
index 9e18a133..74a1e2cc 100644
--- a/parser/convert.go
+++ b/parser/convert.go
@@ -143,7 +143,21 @@ func (parser *SpecParser) initializeConverters() []func(*Token, *int, *gauge.Spe
 			e := ParseError{FileName: spec.FileName, LineNo: token.LineNo, LineText: token.LineText(), Message: fmt.Sprintf("Could not resolve table from %s", token.LineText())}
 			return ParseResult{ParseErrors: []ParseError{e}, Ok: false}
 		}
-		if isInState(*state, specScope) && !spec.DataTable.IsInitialized() {
+		if isInAnyState(*state, scenarioScope) {
+			scn := spec.LatestScenario()
+			if !scn.DataTable.IsInitialized() && env.AllowScenarioDatatable() {
+				externalTable := &gauge.DataTable{}
+				externalTable.Table = resolvedArg.Table
+				externalTable.LineNo = token.LineNo
+				externalTable.Value = token.Value
+				externalTable.IsExternal = true
+				scn.AddExternalDataTable(externalTable)
+			} else {
+				value := "Multiple data table present, ignoring table"
+				scn.AddComment(&gauge.Comment{Value: token.LineText(), LineNo: token.LineNo})
+				return ParseResult{Ok: false, Warnings: []*Warning{&Warning{spec.FileName, token.LineNo, token.SpanEnd, value}}}
+			}
+		} else if isInState(*state, specScope) && !spec.DataTable.IsInitialized() {
 			externalTable := &gauge.DataTable{}
 			externalTable.Table = resolvedArg.Table
 			externalTable.LineNo = token.LineNo
@@ -155,11 +169,11 @@ func (parser *SpecParser) initializeConverters() []func(*Token, *int, *gauge.Spe
 			spec.AddComment(&gauge.Comment{Value: token.LineText(), LineNo: token.LineNo})
 			return ParseResult{Ok: false, Warnings: []*Warning{&Warning{spec.FileName, token.LineNo, token.SpanEnd, value}}}
 		} else {
-			value := "Data table not associated with spec"
+			value := "Data table not associated with spec or scenario"
 			spec.AddComment(&gauge.Comment{Value: token.LineText(), LineNo: token.LineNo})
 			return ParseResult{Ok: false, Warnings: []*Warning{&Warning{spec.FileName, token.LineNo, token.SpanEnd, value}}}
 		}
-		retainStates(state, specScope)
+		retainStates(state, specScope, scenarioScope)
 		addStates(state, keywordScope)
 		return ParseResult{Ok: true}
 	})


Test patch:
diff --git a/parser/lex_test.go b/parser/lex_test.go
index 03c3a487..5c996ea5 100644
--- a/parser/lex_test.go
+++ b/parser/lex_test.go
@@ -547,6 +547,18 @@ func (s *MySuite) TestParsingSimpleScenarioDataTable(c *C) {
 
 }
 
+func (s *MySuite) TestParsingExternalScenarioDataTable(c *C) {
+	parser := new(SpecParser)
+	specText := newSpecBuilder().specHeading("Spec heading").
+		scenarioHeading("Scenario Heading").
+		text("table:data/foo.csv").String()
+
+	tokens, err := parser.GenerateTokens(specText, "")
+	c.Assert(err, IsNil)
+	c.Assert(len(tokens), Equals, 3)
+	c.Assert(tokens[2].Kind, Equals, gauge.DataTableKind)
+}
+
 func (s *MySuite) TestParsingStepWIthNewlineAndTableParam(c *C) {
 	parser := new(SpecParser)
 	specText := newSpecBuilder().
diff --git a/parser/specparser_test.go b/parser/specparser_test.go
index ee9cb48e..8983ec6d 100644
--- a/parser/specparser_test.go
+++ b/parser/specparser_test.go
@@ -1156,6 +1156,49 @@ func TestParseScenarioWithDataTable(t *testing.T) {
 	})
 }
 
+func TestParseScenarioWithExternalDataTable(t *testing.T) {
+	p := new(SpecParser)
+	var subject = func() *gauge.Scenario {
+		spec, _, err := p.Parse(`Specification Heading
+=====================
+* Vowels in English language are "aeiou".
+
+Vowel counts in single word
+---------------------------
+table:testdata/data.csv
+
+* The word <Word> has <Vowel Count> vowels.
+
+`, gauge.NewConceptDictionary(), "")
+		if err != nil {
+			t.Error(err)
+		}
+		return spec.Scenarios[0]
+	}
+
+	t.Run("Parse Scenario with external datatable when AllowScenarioDatatable=True", func(t *testing.T) {
+		env.AllowScenarioDatatable = func() bool { return true }
+		s := subject()
+		v := len(s.DataTable.Table.Rows())
+		if v != 5 {
+			t.Errorf("expected scenario to have 5 rows, got %d", v)
+		}
+		v = len(s.DataTable.Table.Columns)
+		if v != 2 {
+			t.Errorf("expected scenario to have 2 columns, got %d", v)
+		}
+	})
+
+	t.Run("Parse Scenario with datatable when AllowScenarioDatatable=False", func(t *testing.T) {
+		env.AllowScenarioDatatable = func() bool { return false }
+		s := subject()
+		v := len(s.DataTable.Table.Rows())
+		if v != 0 {
+			t.Errorf("expected scenario to have no rows, got %d", v)
+		}
+	})
+}
+
 func (s *MySuite) TestParsingWhenTearDownHAsOnlyTable(c *C) {
 	p := new(SpecParser)
 
diff --git a/parser/testdata/data.csv b/parser/testdata/data.csv
new file mode 100644
index 00000000..fd0a5fcf
--- /dev/null
+++ b/parser/testdata/data.csv
@@ -0,0 +1,6 @@
+Word,Vowel Count
+Gauge,3
+Mingle,2
+Snap,1
+GoCD,1
+Rhythm,0
\ No newline at end of file