From 9c1b3bfb59bf98bf9ad494befc43ce4de093ccf0 Mon Sep 17 00:00:00 2001 From: Dipak Acharya Date: Thu, 10 Jun 2021 18:26:39 +0545 Subject: [PATCH] Fix parsing scenarios with multiple table with tags --- parser/parser.go | 58 +++++++++++----------------- parser/parser_test.go | 90 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+), 36 deletions(-) diff --git a/parser/parser.go b/parser/parser.go index e84e47c..62b1aff 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -294,56 +294,42 @@ func (p *Parser) ParseScenarioTypeSet() []object.ScenarioType { scenarios := []object.ScenarioType{} lastTags := []string{} for p.curTokenIs(token.SCENARIO) || p.curTokenIs(token.TAG) { - scenarios = append(scenarios, p.ParseScenarioType(lastTags)) + lastScenario := p.ParseScenarioType(lastTags) + if lastScenario == nil { + return nil + } + scenarios = append(scenarios, lastScenario) p.skipNewLines() - var extraTable object.Table - for { - if !(p.curTokenIs(token.TAG) || p.curTokenIs(token.EXAMPLES)) { - break - } - if p.curTokenIs(token.TAG) { - lastTags = p.ParseTags() - } - p.skipNewLines() - - if !p.curTokenIs(token.EXAMPLES) { - break - } - - if !p.expectPeek(token.COLON) { - p.peekError(token.COLON) + lastOutline, ok := lastScenario.(*object.ScenarioOutline) + if !ok { + lastTags = []string{} + continue + } + if len(lastOutline.TableTags) != len(lastOutline.Tables) { + if len(lastOutline.TableTags) != len(lastOutline.Tables)+1 { return nil } - p.nextToken() - p.skipNewLines() - itable := p.ParseTable().GetRows() - - extraTable.Append(itable[1:]) - // TODO: dont ignore tags here + lastTags = lastOutline.TableTags[len(lastOutline.TableTags)-1] + lastOutline.TableTags = lastOutline.TableTags[:len(lastOutline.TableTags)-1] + } else { lastTags = []string{} - p.skipNewLines() - - lastScenario := scenarios[len(scenarios)-1] - lastOutline, ok := lastScenario.(*object.ScenarioOutline) - if !ok { - panic("invalid type") - } - lastOutline.Tables[len(lastOutline.Tables)-1].Append(extraTable.GetRows()) } - } - p.skipNewLines() + return scenarios } // ParseScenarioType parses a ScenarioType from the current position in the parser func (p *Parser) ParseScenarioType(lastTags []string) object.ScenarioType { - tags := []string{} + tags := lastTags p.skipNewLines() if p.curTokenIs(token.TAG) { tags = p.ParseTags() + if len(lastTags) > 0 { + return nil + } if tags == nil { return nil } @@ -396,10 +382,10 @@ func (p *Parser) ParseScenarioType(lastTags []string) object.ScenarioType { } else { tableTags = append(tableTags, []string{}) } + p.skipNewLines() if !p.curTokenIs(token.EXAMPLES) { - p.peekError(token.EXAMPLES) - return nil + break } if !p.expectPeek(token.COLON) { p.peekError(token.COLON) diff --git a/parser/parser_test.go b/parser/parser_test.go index f30e42c..2df747a 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -7,6 +7,7 @@ import ( "github.com/dpakach/gorkin/lexer" "github.com/dpakach/gorkin/object" "github.com/dpakach/gorkin/token" + "github.com/dpakach/gorkin/utils" ) type stepDataType struct { @@ -698,7 +699,96 @@ func TestParsingFeature(t *testing.T) { for i, data := range expected { assertBlockStepsEqual(t, stepDataProvider[data.dataProviderKey], scenarios[i].(*object.Scenario).Steps) } +} +func TestParsingFeature2(t *testing.T) { + input := fmt.Sprintf(` + @coolFeature + Feature: This is a feature + Some description about the feature + Also some more description + Plus to top it off some extra description + + Background: + %v + + Scenario: scenario case + %v + + @tag42 + Scenario Outline: test new + %v + Examples: + | data | + | row | + + @newTag + Examples: + | data | + | row1 | + + @hello + Scenario: test new simple + %v + `, stepInput1, stepInput1, stepInput2, stepInput3) + + l := lexer.New(input) + p := New(l) + + feature := p.ParseFeature() + checkParserErrors(t, p) + + expectedTitle := "This is a feature" + if feature.Title != expectedTitle { + t.Fatalf("Title mismatch, expected %v, got %v", expectedTitle, feature.Title) + } + + expectedTags := []string{"coolFeature"} + + if !areArrayEqual(expectedTags, feature.Tags) { + t.Fatalf("Tags mismatch, expected %v, got %v", expectedTags, feature.Tags) + } + + if feature.Background == nil { + t.Fatal("Expected background to not be null but got nil") + } + + expected := []struct { + title string + tags []string + }{ + { + title: "scenario case", + tags: []string{}, + }, + { + title: "test new", + tags: []string{"tag42"}, + }, + { + title: "test new", + tags: []string{"tag42", "newTag"}, + }, + { + title: "test new simple", + tags: []string{"hello"}, + }, + } + + sc := []object.Scenario{} + for _, s := range feature.Scenarios { + sc = append(sc, s.GetScenarios()...) + } + + for i, s := range expected { + if s.title != sc[i].ScenarioText { + t.Fatalf("Title mismatch, expected %s, got %v", s.title, sc[i].ScenarioText) + } + + if !utils.AreArrayEqual(s.tags, sc[i].Tags) { + t.Fatalf("Tags mismatch, expected %v, got %v", s.tags, sc[i].Tags) + } + } } func TestParsingFeatureSet(t *testing.T) {