github.com/mattdotmatt/gauge@v0.3.2-0.20160421115137-425a4cdccb62/parser/specparser_test.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 (
    21  	"path/filepath"
    22  	"testing"
    23  
    24  	"github.com/getgauge/gauge/gauge"
    25  
    26  	. "gopkg.in/check.v1"
    27  )
    28  
    29  // Hook up gocheck into the "go test" runner.
    30  func Test(t *testing.T) { TestingT(t) }
    31  
    32  type MySuite struct{}
    33  
    34  var _ = Suite(&MySuite{})
    35  
    36  func (s *MySuite) TestParsingSpecHeading(c *C) {
    37  	parser := new(SpecParser)
    38  
    39  	specText := SpecBuilder().specHeading("Spec Heading").String()
    40  	tokens, err := parser.GenerateTokens(specText)
    41  
    42  	c.Assert(err, IsNil)
    43  	c.Assert(len(tokens), Equals, 1)
    44  	c.Assert(tokens[0].Kind, Equals, gauge.SpecKind)
    45  	c.Assert(tokens[0].Value, Equals, "Spec Heading")
    46  }
    47  
    48  func (s *MySuite) TestParsingASingleStep(c *C) {
    49  	parser := new(SpecParser)
    50  	tokens, err := parser.GenerateTokens("* test step \"arg\" ")
    51  
    52  	c.Assert(err, IsNil)
    53  	c.Assert(len(tokens), Equals, 1)
    54  	c.Assert(tokens[0].Kind, Equals, gauge.StepKind)
    55  }
    56  
    57  func (s *MySuite) TestParsingMultipleSpecHeading(c *C) {
    58  	parser := new(SpecParser)
    59  	specText := SpecBuilder().specHeading("Spec Heading").specHeading("Another Spec Heading").String()
    60  
    61  	tokens, err := parser.GenerateTokens(specText)
    62  
    63  	c.Assert(err, IsNil)
    64  	c.Assert(len(tokens), Equals, 2)
    65  	c.Assert(tokens[0].Kind, Equals, gauge.SpecKind)
    66  	c.Assert(tokens[0].Value, Equals, "Spec Heading")
    67  	c.Assert(tokens[1].Kind, Equals, gauge.SpecKind)
    68  	c.Assert(tokens[1].Value, Equals, "Another Spec Heading")
    69  }
    70  
    71  func (s *MySuite) TestParsingThrowErrorForEmptySpecHeading(c *C) {
    72  	parser := new(SpecParser)
    73  	specText := SpecBuilder().specHeading("").specHeading("Another Spec Heading").String()
    74  
    75  	_, err := parser.GenerateTokens(specText)
    76  
    77  	c.Assert(err, NotNil)
    78  	c.Assert(err.Error(), Equals, "line no: 1, Spec heading should have at least one character")
    79  }
    80  
    81  func (s *MySuite) TestParsingScenarioHeading(c *C) {
    82  	parser := new(SpecParser)
    83  	specText := SpecBuilder().specHeading("Spec Heading").scenarioHeading("First scenario").String()
    84  
    85  	tokens, err := parser.GenerateTokens(specText)
    86  
    87  	c.Assert(err, IsNil)
    88  	c.Assert(len(tokens), Equals, 2)
    89  	c.Assert(tokens[1].Kind, Equals, gauge.ScenarioKind)
    90  	c.Assert(tokens[1].Value, Equals, "First scenario")
    91  }
    92  
    93  func (s *MySuite) TestParsingThrowErrorForEmptyScenarioHeading(c *C) {
    94  	parser := new(SpecParser)
    95  	specText := SpecBuilder().specHeading("Spec Heading").scenarioHeading("").String()
    96  
    97  	_, err := parser.GenerateTokens(specText)
    98  
    99  	c.Assert(err, NotNil)
   100  	c.Assert(err.Error(), Equals, "line no: 2, Scenario heading should have at least one character")
   101  }
   102  
   103  func (s *MySuite) TestParsingScenarioWithoutSpecHeading(c *C) {
   104  	parser := new(SpecParser)
   105  	specText := SpecBuilder().scenarioHeading("Scenario Heading").String()
   106  
   107  	tokens, err := parser.GenerateTokens(specText)
   108  
   109  	c.Assert(err, IsNil)
   110  	c.Assert(len(tokens), Equals, 1)
   111  	c.Assert(tokens[0].Kind, Equals, gauge.ScenarioKind)
   112  }
   113  
   114  func (s *MySuite) TestParsingComments(c *C) {
   115  	parser := new(SpecParser)
   116  	specText := SpecBuilder().specHeading("Spec Heading").text("Hello i am a comment ").text("### A h3 comment").String()
   117  
   118  	tokens, err := parser.GenerateTokens(specText)
   119  
   120  	c.Assert(err, IsNil)
   121  	c.Assert(len(tokens), Equals, 3)
   122  
   123  	c.Assert(tokens[1].Kind, Equals, gauge.CommentKind)
   124  	c.Assert(tokens[1].Value, Equals, "Hello i am a comment")
   125  
   126  	c.Assert(tokens[2].Kind, Equals, gauge.CommentKind)
   127  	c.Assert(tokens[2].Value, Equals, "### A h3 comment")
   128  }
   129  
   130  func (s *MySuite) TestParsingSpecHeadingWithUnderlineOneChar(c *C) {
   131  	parser := new(SpecParser)
   132  	specText := SpecBuilder().text("Spec heading with underline ").text("=").String()
   133  
   134  	tokens, err := parser.GenerateTokens(specText)
   135  
   136  	c.Assert(err, IsNil)
   137  	c.Assert(len(tokens), Equals, 1)
   138  
   139  	c.Assert(tokens[0].Kind, Equals, gauge.SpecKind)
   140  	c.Assert(tokens[0].Value, Equals, "Spec heading with underline")
   141  
   142  }
   143  
   144  func (s *MySuite) TestParsingSpecHeadingWithUnderlineMultipleChar(c *C) {
   145  	parser := new(SpecParser)
   146  	specText := SpecBuilder().text("Spec heading with underline ").text("=====").String()
   147  
   148  	tokens, err := parser.GenerateTokens(specText)
   149  
   150  	c.Assert(err, IsNil)
   151  	c.Assert(len(tokens), Equals, 1)
   152  
   153  	c.Assert(tokens[0].Kind, Equals, gauge.SpecKind)
   154  	c.Assert(tokens[0].Value, Equals, "Spec heading with underline")
   155  
   156  }
   157  
   158  func (s *MySuite) TestParsingCommentWithUnderlineAndInvalidCharacters(c *C) {
   159  	parser := new(SpecParser)
   160  	specText := SpecBuilder().text("A comment that will be with invalid underline").text("===89s").String()
   161  
   162  	tokens, err := parser.GenerateTokens(specText)
   163  
   164  	c.Assert(err, IsNil)
   165  	c.Assert(len(tokens), Equals, 2)
   166  
   167  	c.Assert(tokens[0].Kind, Equals, gauge.CommentKind)
   168  	c.Assert(tokens[0].Value, Equals, "A comment that will be with invalid underline")
   169  
   170  	c.Assert(tokens[1].Kind, Equals, gauge.CommentKind)
   171  	c.Assert(tokens[1].Value, Equals, "===89s")
   172  }
   173  
   174  func (s *MySuite) TestParsingScenarioHeadingWithUnderline(c *C) {
   175  	parser := new(SpecParser)
   176  	specText := SpecBuilder().text("Spec heading with underline ").text("=").text("Scenario heading with underline").text("-").String()
   177  
   178  	tokens, err := parser.GenerateTokens(specText)
   179  
   180  	c.Assert(err, IsNil)
   181  	c.Assert(len(tokens), Equals, 2)
   182  
   183  	c.Assert(tokens[0].Kind, Equals, gauge.SpecKind)
   184  	c.Assert(tokens[0].Value, Equals, "Spec heading with underline")
   185  
   186  	c.Assert(tokens[1].Kind, Equals, gauge.ScenarioKind)
   187  	c.Assert(tokens[1].Value, Equals, "Scenario heading with underline")
   188  
   189  }
   190  
   191  func (s *MySuite) TestParsingScenarioHeadingWithUnderlineMultipleChar(c *C) {
   192  	parser := new(SpecParser)
   193  	specText := SpecBuilder().text("Spec heading with underline ").text("=").text("Scenario heading with underline").text("----").String()
   194  
   195  	tokens, err := parser.GenerateTokens(specText)
   196  
   197  	c.Assert(err, IsNil)
   198  	c.Assert(len(tokens), Equals, 2)
   199  
   200  	c.Assert(tokens[0].Kind, Equals, gauge.SpecKind)
   201  	c.Assert(tokens[0].Value, Equals, "Spec heading with underline")
   202  
   203  	c.Assert(tokens[1].Kind, Equals, gauge.ScenarioKind)
   204  	c.Assert(tokens[1].Value, Equals, "Scenario heading with underline")
   205  
   206  }
   207  
   208  func (s *MySuite) TestParsingHeadingWithUnderlineAndHash(c *C) {
   209  	parser := new(SpecParser)
   210  	specText := SpecBuilder().specHeading("Spec heading with hash ").text("=====").scenarioHeading("Scenario heading with hash").text("----").String()
   211  
   212  	tokens, err := parser.GenerateTokens(specText)
   213  
   214  	c.Assert(err, IsNil)
   215  	c.Assert(len(tokens), Equals, 4)
   216  
   217  	c.Assert(tokens[0].Kind, Equals, gauge.SpecKind)
   218  	c.Assert(tokens[0].Value, Equals, "Spec heading with hash")
   219  
   220  	c.Assert(tokens[1].Kind, Equals, gauge.CommentKind)
   221  	c.Assert(tokens[1].Value, Equals, "=====")
   222  
   223  	c.Assert(tokens[2].Kind, Equals, gauge.ScenarioKind)
   224  	c.Assert(tokens[2].Value, Equals, "Scenario heading with hash")
   225  
   226  	c.Assert(tokens[3].Kind, Equals, gauge.CommentKind)
   227  	c.Assert(tokens[3].Value, Equals, "----")
   228  
   229  }
   230  
   231  func (s *MySuite) TestParseSpecTags(c *C) {
   232  	parser := new(SpecParser)
   233  	specText := SpecBuilder().specHeading("Spec heading with hash ").tags("tag1", "tag2").scenarioHeading("Scenario Heading").String()
   234  
   235  	tokens, err := parser.GenerateTokens(specText)
   236  
   237  	c.Assert(err, IsNil)
   238  	c.Assert(len(tokens), Equals, 3)
   239  
   240  	c.Assert(tokens[1].Kind, Equals, gauge.TagKind)
   241  	c.Assert(len(tokens[1].Args), Equals, 2)
   242  	c.Assert(tokens[1].Args[0], Equals, "tag1")
   243  	c.Assert(tokens[1].Args[1], Equals, "tag2")
   244  	c.Assert(tokens[1].LineText, Equals, "tags: tag1,tag2")
   245  	c.Assert(tokens[1].Value, Equals, "tag1,tag2")
   246  }
   247  
   248  func (s *MySuite) TestParseSpecTagsWithSpace(c *C) {
   249  	parser := new(SpecParser)
   250  	specText := SpecBuilder().specHeading("Spec heading with hash ").text(" tags :tag1,tag2").scenarioHeading("Scenario Heading").String()
   251  
   252  	tokens, err := parser.GenerateTokens(specText)
   253  
   254  	c.Assert(err, IsNil)
   255  	c.Assert(len(tokens), Equals, 3)
   256  
   257  	c.Assert(tokens[1].Kind, Equals, gauge.TagKind)
   258  	c.Assert(len(tokens[1].Args), Equals, 2)
   259  	c.Assert(tokens[1].Args[0], Equals, "tag1")
   260  	c.Assert(tokens[1].Args[1], Equals, "tag2")
   261  	c.Assert(tokens[1].LineText, Equals, " tags :tag1,tag2")
   262  	c.Assert(tokens[1].Value, Equals, "tag1,tag2")
   263  }
   264  
   265  func (s *MySuite) TestParseEmptyTags(c *C) {
   266  	parser := new(SpecParser)
   267  	specText := SpecBuilder().specHeading("Spec heading with hash ").tags("tag1", "", "tag2", "").scenarioHeading("Scenario Heading").String()
   268  	tokens, err := parser.GenerateTokens(specText)
   269  
   270  	c.Assert(err, IsNil)
   271  	c.Assert(len(tokens), Equals, 3)
   272  
   273  	c.Assert(tokens[1].Kind, Equals, gauge.TagKind)
   274  	c.Assert(len(tokens[1].Args), Equals, 2)
   275  	c.Assert(tokens[1].Args[0], Equals, "tag1")
   276  	c.Assert(tokens[1].Args[1], Equals, "tag2")
   277  	c.Assert(tokens[1].LineText, Equals, "tags: tag1,,tag2,")
   278  	c.Assert(tokens[1].Value, Equals, "tag1,,tag2,")
   279  }
   280  
   281  func (s *MySuite) TestParseScenarioTags(c *C) {
   282  	parser := new(SpecParser)
   283  	specText := SpecBuilder().specHeading("Spec heading with hash ").scenarioHeading("Scenario Heading").tags("tag1", "tag2").String()
   284  
   285  	tokens, err := parser.GenerateTokens(specText)
   286  
   287  	c.Assert(err, IsNil)
   288  	c.Assert(len(tokens), Equals, 3)
   289  
   290  	c.Assert(tokens[2].Kind, Equals, gauge.TagKind)
   291  	c.Assert(len(tokens[2].Args), Equals, 2)
   292  	c.Assert(tokens[2].Args[0], Equals, "tag1")
   293  	c.Assert(tokens[2].Args[1], Equals, "tag2")
   294  	c.Assert(tokens[2].LineText, Equals, "tags: tag1,tag2")
   295  	c.Assert(tokens[2].Value, Equals, "tag1,tag2")
   296  }
   297  
   298  func (s *MySuite) TestParseSpecTagsBeforeSpecHeading(c *C) {
   299  	parser := new(SpecParser)
   300  	specText := SpecBuilder().tags("tag1 ").specHeading("Spec heading with hash ").String()
   301  
   302  	tokens, err := parser.GenerateTokens(specText)
   303  
   304  	c.Assert(err, IsNil)
   305  	c.Assert(len(tokens), Equals, 2)
   306  
   307  	c.Assert(tokens[0].Kind, Equals, gauge.TagKind)
   308  	c.Assert(len(tokens[0].Args), Equals, 1)
   309  	c.Assert(tokens[0].Args[0], Equals, "tag1")
   310  	c.Assert(tokens[0].LineText, Equals, "tags: tag1 ")
   311  	c.Assert(tokens[0].Value, Equals, "tag1")
   312  }
   313  
   314  func (s *MySuite) TestParsingSimpleDataTable(c *C) {
   315  	parser := new(SpecParser)
   316  	specText := SpecBuilder().specHeading("Spec heading").text("|name|id|").text("|---|---|").text("|john|123|").text("|james|007|").String()
   317  
   318  	tokens, err := parser.GenerateTokens(specText)
   319  	c.Assert(err, IsNil)
   320  	c.Assert(len(tokens), Equals, 5)
   321  
   322  	c.Assert(tokens[1].Kind, Equals, gauge.TableHeader)
   323  	c.Assert(len(tokens[1].Args), Equals, 2)
   324  	c.Assert(tokens[1].Args[0], Equals, "name")
   325  	c.Assert(tokens[1].Args[1], Equals, "id")
   326  
   327  	c.Assert(tokens[2].Kind, Equals, gauge.TableRow)
   328  	c.Assert(len(tokens[2].Args), Equals, 2)
   329  	c.Assert(tokens[2].Args[0], Equals, "---")
   330  	c.Assert(tokens[2].Args[1], Equals, "---")
   331  
   332  	c.Assert(tokens[3].Kind, Equals, gauge.TableRow)
   333  	c.Assert(len(tokens[3].Args), Equals, 2)
   334  	c.Assert(tokens[3].Args[0], Equals, "john")
   335  	c.Assert(tokens[3].Args[1], Equals, "123")
   336  
   337  	c.Assert(tokens[4].Kind, Equals, gauge.TableRow)
   338  	c.Assert(len(tokens[4].Args), Equals, 2)
   339  	c.Assert(tokens[4].Args[0], Equals, "james")
   340  	c.Assert(tokens[4].Args[1], Equals, "007")
   341  
   342  }
   343  
   344  func (s *MySuite) TestParsingMultipleDataTable(c *C) {
   345  	parser := new(SpecParser)
   346  	specText := SpecBuilder().specHeading("Spec heading").text("|name|id|").text("|john|123|").text("|james|007|").step("Example step").text("|user|role|").text("|root | admin|").String()
   347  
   348  	tokens, err := parser.GenerateTokens(specText)
   349  	c.Assert(err, IsNil)
   350  	c.Assert(len(tokens), Equals, 7)
   351  
   352  	c.Assert(tokens[1].Kind, Equals, gauge.TableHeader)
   353  	c.Assert(len(tokens[1].Args), Equals, 2)
   354  	c.Assert(tokens[1].Args[0], Equals, "name")
   355  	c.Assert(tokens[1].Args[1], Equals, "id")
   356  
   357  	c.Assert(tokens[2].Kind, Equals, gauge.TableRow)
   358  	c.Assert(len(tokens[2].Args), Equals, 2)
   359  	c.Assert(tokens[2].Args[0], Equals, "john")
   360  	c.Assert(tokens[2].Args[1], Equals, "123")
   361  
   362  	c.Assert(tokens[3].Kind, Equals, gauge.TableRow)
   363  	c.Assert(len(tokens[3].Args), Equals, 2)
   364  	c.Assert(tokens[3].Args[0], Equals, "james")
   365  	c.Assert(tokens[3].Args[1], Equals, "007")
   366  
   367  	c.Assert(tokens[5].Kind, Equals, gauge.TableHeader)
   368  	c.Assert(len(tokens[5].Args), Equals, 2)
   369  	c.Assert(tokens[5].Args[0], Equals, "user")
   370  	c.Assert(tokens[5].Args[1], Equals, "role")
   371  
   372  	c.Assert(tokens[6].Kind, Equals, gauge.TableRow)
   373  	c.Assert(len(tokens[6].Args), Equals, 2)
   374  	c.Assert(tokens[6].Args[0], Equals, "root")
   375  	c.Assert(tokens[6].Args[1], Equals, "admin")
   376  }
   377  
   378  func (s *MySuite) TestParsingDataTableWithEmptyHeaderSeparatorRow(c *C) {
   379  	parser := new(SpecParser)
   380  	specText := SpecBuilder().specHeading("Spec heading").text("|name|id|").text("|||").text("|john|123|").String()
   381  
   382  	tokens, err := parser.GenerateTokens(specText)
   383  	c.Assert(err, IsNil)
   384  	c.Assert(len(tokens), Equals, 4)
   385  
   386  	c.Assert(tokens[1].Kind, Equals, gauge.TableHeader)
   387  	c.Assert(len(tokens[1].Args), Equals, 2)
   388  	c.Assert(tokens[1].Args[0], Equals, "name")
   389  	c.Assert(tokens[1].Args[1], Equals, "id")
   390  
   391  	c.Assert(tokens[2].Kind, Equals, gauge.TableRow)
   392  	c.Assert(len(tokens[2].Args), Equals, 2)
   393  	c.Assert(tokens[2].Args[0], Equals, "")
   394  	c.Assert(tokens[2].Args[1], Equals, "")
   395  
   396  	c.Assert(tokens[3].Kind, Equals, gauge.TableRow)
   397  	c.Assert(len(tokens[3].Args), Equals, 2)
   398  	c.Assert(tokens[3].Args[0], Equals, "john")
   399  	c.Assert(tokens[3].Args[1], Equals, "123")
   400  
   401  }
   402  
   403  func (s *MySuite) TestParsingDataTableRowEscapingPipe(c *C) {
   404  	parser := new(SpecParser)
   405  	specText := SpecBuilder().specHeading("Spec heading").text("| name|id | address| phone|").text("| escape \\| pipe |second|third|").String()
   406  
   407  	tokens, err := parser.GenerateTokens(specText)
   408  	c.Assert(err, IsNil)
   409  	c.Assert(len(tokens), Equals, 3)
   410  
   411  	c.Assert(tokens[1].Kind, Equals, gauge.TableHeader)
   412  	c.Assert(len(tokens[1].Args), Equals, 4)
   413  	c.Assert(tokens[1].Args[0], Equals, "name")
   414  	c.Assert(tokens[1].Args[1], Equals, "id")
   415  	c.Assert(tokens[1].Args[2], Equals, "address")
   416  	c.Assert(tokens[1].Args[3], Equals, "phone")
   417  
   418  	c.Assert(tokens[2].Kind, Equals, gauge.TableRow)
   419  	c.Assert(len(tokens[2].Args), Equals, 3)
   420  	c.Assert(tokens[2].Args[0], Equals, "escape | pipe")
   421  	c.Assert(tokens[2].Args[1], Equals, "second")
   422  	c.Assert(tokens[2].Args[2], Equals, "third")
   423  
   424  }
   425  
   426  func (s *MySuite) TestParsingDataTableThrowsErrorWithEmptyHeader(c *C) {
   427  	parser := new(SpecParser)
   428  	specText := SpecBuilder().specHeading("Spec heading").text("| name|id |||").text("| escape \\| pipe |second|third|second|").String()
   429  
   430  	_, err := parser.GenerateTokens(specText)
   431  	c.Assert(err, NotNil)
   432  	c.Assert(err.Error(), Equals, "line no: 2, Table header should not be blank")
   433  }
   434  
   435  func (s *MySuite) TestParsingDataTableThrowsErrorWithSameColumnHeader(c *C) {
   436  	parser := new(SpecParser)
   437  	specText := SpecBuilder().specHeading("Spec heading").text("| name|id|name|").text("|1|2|3|").String()
   438  
   439  	_, err := parser.GenerateTokens(specText)
   440  	c.Assert(err, NotNil)
   441  	c.Assert(err.Error(), Equals, "line no: 2, Table header cannot have repeated column values")
   442  }
   443  
   444  func (s *MySuite) TestParsingDataTableWithSeparatorAsHeader(c *C) {
   445  	parser := new(SpecParser)
   446  	specText := SpecBuilder().specHeading("Spec heading").text("|---|--|-|").text("|---|--|-|").text("|---|--|-|").text("| escape \\| pipe |second|third|").String()
   447  
   448  	tokens, err := parser.GenerateTokens(specText)
   449  	c.Assert(err, IsNil)
   450  	c.Assert(len(tokens), Equals, 5)
   451  
   452  	c.Assert(tokens[1].Kind, Equals, gauge.TableHeader)
   453  	c.Assert(len(tokens[1].Args), Equals, 3)
   454  	c.Assert(tokens[1].Args[0], Equals, "---")
   455  	c.Assert(tokens[1].Args[1], Equals, "--")
   456  	c.Assert(tokens[1].Args[2], Equals, "-")
   457  
   458  	c.Assert(tokens[2].Kind, Equals, gauge.TableRow)
   459  	c.Assert(len(tokens[2].Args), Equals, 3)
   460  	c.Assert(tokens[2].Args[0], Equals, "---")
   461  	c.Assert(tokens[2].Args[1], Equals, "--")
   462  	c.Assert(tokens[2].Args[2], Equals, "-")
   463  
   464  }
   465  
   466  func (s *MySuite) TestParsingSpecWithMultipleLines(c *C) {
   467  	parser := new(SpecParser)
   468  	specText := SpecBuilder().specHeading("A spec heading").
   469  		text("Hello, i am a comment").
   470  		text(" ").
   471  		step("Context step with \"param\" and <file:foo>").
   472  		text("|a|b|c|").
   473  		text("|--||").
   474  		text("|a1|a2|a3|").
   475  		tags("one", "two").
   476  		scenarioHeading("First flow").
   477  		tags("tag1", "tag2").
   478  		step("first with \"fpp\" and <bar>").
   479  		text("Comment in scenario").
   480  		step("<table:file.csv> and <another> with \"foo\"").
   481  		scenarioHeading("First flow").
   482  		step("another").String()
   483  
   484  	tokens, err := parser.GenerateTokens(specText)
   485  	c.Assert(err, IsNil)
   486  	c.Assert(len(tokens), Equals, 15)
   487  
   488  	c.Assert(tokens[0].Kind, Equals, gauge.SpecKind)
   489  	c.Assert(tokens[1].Kind, Equals, gauge.CommentKind)
   490  	c.Assert(tokens[2].Kind, Equals, gauge.CommentKind)
   491  
   492  	c.Assert(tokens[3].Kind, Equals, gauge.StepKind)
   493  	c.Assert(tokens[3].Value, Equals, "Context step with {static} and {special}")
   494  
   495  	c.Assert(tokens[4].Kind, Equals, gauge.TableHeader)
   496  	c.Assert(tokens[5].Kind, Equals, gauge.TableRow)
   497  	c.Assert(tokens[6].Kind, Equals, gauge.TableRow)
   498  	c.Assert(tokens[7].Kind, Equals, gauge.TagKind)
   499  	c.Assert(tokens[8].Kind, Equals, gauge.ScenarioKind)
   500  	c.Assert(tokens[9].Kind, Equals, gauge.TagKind)
   501  
   502  	c.Assert(tokens[10].Kind, Equals, gauge.StepKind)
   503  	c.Assert(tokens[10].Value, Equals, "first with {static} and {dynamic}")
   504  
   505  	c.Assert(tokens[11].Kind, Equals, gauge.CommentKind)
   506  
   507  	c.Assert(tokens[12].Kind, Equals, gauge.StepKind)
   508  	c.Assert(tokens[12].Value, Equals, "{special} and {dynamic} with {static}")
   509  
   510  	c.Assert(tokens[13].Kind, Equals, gauge.ScenarioKind)
   511  
   512  	c.Assert(tokens[14].Kind, Equals, gauge.StepKind)
   513  	c.Assert(tokens[14].Value, Equals, "another")
   514  
   515  }
   516  
   517  func (s *MySuite) TestParsingSpecWithTearDownSteps(c *C) {
   518  	parser := new(SpecParser)
   519  	specText := SpecBuilder().specHeading("A spec heading").
   520  		text("Hello, i am a comment").
   521  		scenarioHeading("First flow").
   522  		step("another").
   523  		text("_____").
   524  		step("step1").
   525  		step("step2").String()
   526  
   527  	tokens, err := parser.GenerateTokens(specText)
   528  	c.Assert(err, IsNil)
   529  	c.Assert(len(tokens), Equals, 7)
   530  
   531  	c.Assert(tokens[0].Kind, Equals, gauge.SpecKind)
   532  	c.Assert(tokens[1].Kind, Equals, gauge.CommentKind)
   533  
   534  	c.Assert(tokens[2].Kind, Equals, gauge.ScenarioKind)
   535  	c.Assert(tokens[3].Kind, Equals, gauge.StepKind)
   536  	c.Assert(tokens[3].Value, Equals, "another")
   537  	c.Assert(tokens[4].Kind, Equals, gauge.TearDownKind)
   538  
   539  	c.Assert(tokens[5].Kind, Equals, gauge.StepKind)
   540  	c.Assert(tokens[5].Value, Equals, "step1")
   541  	c.Assert(tokens[6].Kind, Equals, gauge.StepKind)
   542  	c.Assert(tokens[6].Value, Equals, "step2")
   543  
   544  }
   545  
   546  func (s *MySuite) TestParsingConceptInSpec(c *C) {
   547  	parser := new(SpecParser)
   548  	specText := SpecBuilder().specHeading("A spec heading").
   549  		scenarioHeading("First flow").
   550  		step("test concept step 1").
   551  		step("another step").String()
   552  	conceptDictionary := gauge.NewConceptDictionary()
   553  	path, _ := filepath.Abs(filepath.Join("testdata", "concept.cpt"))
   554  	AddConcepts(path, conceptDictionary)
   555  	tokens, err := parser.GenerateTokens(specText)
   556  	c.Assert(err, IsNil)
   557  	spec, parseResult := parser.CreateSpecification(tokens, conceptDictionary)
   558  
   559  	c.Assert(parseResult.Ok, Equals, true)
   560  	firstStepInSpec := spec.Scenarios[0].Steps[0]
   561  	secondStepInSpec := spec.Scenarios[0].Steps[1]
   562  	c.Assert(firstStepInSpec.ConceptSteps[0].Parent, Equals, firstStepInSpec)
   563  	c.Assert(firstStepInSpec.Parent, IsNil)
   564  	c.Assert(secondStepInSpec.Parent, IsNil)
   565  }
   566  
   567  func (s *MySuite) TestTableFromInvalidFile(c *C) {
   568  	parser := new(SpecParser)
   569  	specText := SpecBuilder().specHeading("Spec heading").text("table: inputinvalid.csv").String()
   570  
   571  	_, err := parser.GenerateTokens(specText)
   572  	c.Assert(err.Message, Equals, "Could not resolve table from table: inputinvalid.csv")
   573  }
   574  
   575  func (s *MySuite) TestTableInputFromInvalidFileAndDataTableNotInitialized(c *C) {
   576  	parser := new(SpecParser)
   577  	specText := SpecBuilder().specHeading("Spec heading").text("table: inputinvalid.csv").String()
   578  
   579  	_, parseRes := parser.Parse(specText, gauge.NewConceptDictionary())
   580  	c.Assert(parseRes.ParseError.Message, Equals, "Could not resolve table from table: inputinvalid.csv")
   581  	c.Assert(parseRes.Ok, Equals, false)
   582  }
   583  
   584  func (s *MySuite) TestTableInputFromFile(c *C) {
   585  	parser := new(SpecParser)
   586  	specText := SpecBuilder().specHeading("Spec heading").text("Table: inputinvalid.csv").String()
   587  
   588  	_, parseRes := parser.Parse(specText, gauge.NewConceptDictionary())
   589  	c.Assert(parseRes.ParseError.Message, Equals, "Could not resolve table from Table: inputinvalid.csv")
   590  	c.Assert(parseRes.Ok, Equals, false)
   591  }
   592  
   593  func (s *MySuite) TestTableInputFromFileIfPathNotSpecified(c *C) {
   594  	parser := new(SpecParser)
   595  	specText := SpecBuilder().specHeading("Spec heading").text("Table: ").String()
   596  
   597  	_, parseRes := parser.Parse(specText, gauge.NewConceptDictionary())
   598  	c.Assert(parseRes.ParseError.Message, Equals, "Table location not specified")
   599  	c.Assert(parseRes.Ok, Equals, false)
   600  }
   601  
   602  func (s *MySuite) TestToSplitTagNames(c *C) {
   603  	allTags := splitAndTrimTags("tag1 , tag2,   tag3")
   604  	c.Assert(allTags[0], Equals, "tag1")
   605  	c.Assert(allTags[1], Equals, "tag2")
   606  	c.Assert(allTags[2], Equals, "tag3")
   607  }
   608  
   609  func (s *MySuite) TestThrowsErrorForMultipleSpecHeading(c *C) {
   610  	tokens := []*Token{
   611  		&Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1},
   612  		&Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 2},
   613  		&Token{Kind: gauge.StepKind, Value: "Example step", LineNo: 3},
   614  		&Token{Kind: gauge.SpecKind, Value: "Another Heading", LineNo: 4},
   615  	}
   616  
   617  	_, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary())
   618  
   619  	c.Assert(result.Ok, Equals, false)
   620  
   621  	c.Assert(result.ParseError.Message, Equals, "Parse error: Multiple spec headings found in same file")
   622  	c.Assert(result.ParseError.LineNo, Equals, 4)
   623  }
   624  
   625  func (s *MySuite) TestThrowsErrorForScenarioWithoutSpecHeading(c *C) {
   626  	tokens := []*Token{
   627  		&Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 1},
   628  		&Token{Kind: gauge.StepKind, Value: "Example step", LineNo: 2},
   629  	}
   630  
   631  	_, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary())
   632  
   633  	c.Assert(result.Ok, Equals, false)
   634  
   635  	c.Assert(result.ParseError.Message, Equals, "Parse error: Scenario should be defined after the spec heading")
   636  	c.Assert(result.ParseError.LineNo, Equals, 1)
   637  }
   638  
   639  func (s *MySuite) TestThrowsErrorForDuplicateScenariosWithinTheSameSpec(c *C) {
   640  	tokens := []*Token{
   641  		&Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1},
   642  		&Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 2},
   643  		&Token{Kind: gauge.StepKind, Value: "Example step", LineNo: 3},
   644  		&Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 4},
   645  	}
   646  
   647  	_, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary())
   648  
   649  	c.Assert(result.Ok, Equals, false)
   650  
   651  	c.Assert(result.ParseError.Message, Equals, "Parse error: Duplicate scenario definition 'Scenario Heading' found in the same specification")
   652  	c.Assert(result.ParseError.LineNo, Equals, 4)
   653  }
   654  
   655  func (s *MySuite) TestSpecWithHeadingAndSimpleSteps(c *C) {
   656  	tokens := []*Token{
   657  		&Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1},
   658  		&Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 2},
   659  		&Token{Kind: gauge.StepKind, Value: "Example step", LineNo: 3},
   660  	}
   661  
   662  	spec, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary())
   663  
   664  	c.Assert(len(spec.Items), Equals, 1)
   665  	c.Assert(spec.Items[0], Equals, spec.Scenarios[0])
   666  	scenarioItems := (spec.Items[0]).(*gauge.Scenario).Items
   667  	c.Assert(scenarioItems[0], Equals, spec.Scenarios[0].Steps[0])
   668  
   669  	c.Assert(result.Ok, Equals, true)
   670  	c.Assert(spec.Heading.LineNo, Equals, 1)
   671  	c.Assert(spec.Heading.Value, Equals, "Spec Heading")
   672  
   673  	c.Assert(len(spec.Scenarios), Equals, 1)
   674  	c.Assert(spec.Scenarios[0].Heading.LineNo, Equals, 2)
   675  	c.Assert(spec.Scenarios[0].Heading.Value, Equals, "Scenario Heading")
   676  	c.Assert(len(spec.Scenarios[0].Steps), Equals, 1)
   677  	c.Assert(spec.Scenarios[0].Steps[0].Value, Equals, "Example step")
   678  }
   679  
   680  func (s *MySuite) TestStepsAndComments(c *C) {
   681  	tokens := []*Token{
   682  		&Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1},
   683  		&Token{Kind: gauge.CommentKind, Value: "A comment with some text and **bold** characters", LineNo: 2},
   684  		&Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 3},
   685  		&Token{Kind: gauge.CommentKind, Value: "Another comment", LineNo: 4},
   686  		&Token{Kind: gauge.StepKind, Value: "Example step", LineNo: 5},
   687  		&Token{Kind: gauge.CommentKind, Value: "Third comment", LineNo: 6},
   688  	}
   689  
   690  	spec, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary())
   691  	c.Assert(len(spec.Items), Equals, 2)
   692  	c.Assert(spec.Items[0], Equals, spec.Comments[0])
   693  	c.Assert(spec.Items[1], Equals, spec.Scenarios[0])
   694  
   695  	scenarioItems := (spec.Items[1]).(*gauge.Scenario).Items
   696  	c.Assert(3, Equals, len(scenarioItems))
   697  	c.Assert(scenarioItems[0], Equals, spec.Scenarios[0].Comments[0])
   698  	c.Assert(scenarioItems[1], Equals, spec.Scenarios[0].Steps[0])
   699  	c.Assert(scenarioItems[2], Equals, spec.Scenarios[0].Comments[1])
   700  
   701  	c.Assert(result.Ok, Equals, true)
   702  	c.Assert(spec.Heading.Value, Equals, "Spec Heading")
   703  
   704  	c.Assert(len(spec.Comments), Equals, 1)
   705  	c.Assert(spec.Comments[0].LineNo, Equals, 2)
   706  	c.Assert(spec.Comments[0].Value, Equals, "A comment with some text and **bold** characters")
   707  
   708  	c.Assert(len(spec.Scenarios), Equals, 1)
   709  	scenario := spec.Scenarios[0]
   710  
   711  	c.Assert(2, Equals, len(scenario.Comments))
   712  	c.Assert(scenario.Comments[0].LineNo, Equals, 4)
   713  	c.Assert(scenario.Comments[0].Value, Equals, "Another comment")
   714  
   715  	c.Assert(scenario.Comments[1].LineNo, Equals, 6)
   716  	c.Assert(scenario.Comments[1].Value, Equals, "Third comment")
   717  
   718  	c.Assert(scenario.Heading.Value, Equals, "Scenario Heading")
   719  	c.Assert(len(scenario.Steps), Equals, 1)
   720  }
   721  
   722  func (s *MySuite) TestStepsWithParam(c *C) {
   723  	tokens := []*Token{
   724  		&Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1},
   725  		&Token{Kind: gauge.TableHeader, Args: []string{"id"}, LineNo: 2},
   726  		&Token{Kind: gauge.TableRow, Args: []string{"1"}, LineNo: 3},
   727  		&Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 4},
   728  		&Token{Kind: gauge.StepKind, Value: "enter {static} with {dynamic}", LineNo: 5, Args: []string{"user \\n foo", "id"}},
   729  		&Token{Kind: gauge.StepKind, Value: "sample \\{static\\}", LineNo: 6},
   730  	}
   731  
   732  	spec, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary())
   733  	c.Assert(result.Ok, Equals, true)
   734  	step := spec.Scenarios[0].Steps[0]
   735  	c.Assert(step.Value, Equals, "enter {} with {}")
   736  	c.Assert(step.LineNo, Equals, 5)
   737  	c.Assert(len(step.Args), Equals, 2)
   738  	c.Assert(step.Args[0].Value, Equals, "user \\n foo")
   739  	c.Assert(step.Args[0].ArgType, Equals, gauge.Static)
   740  	c.Assert(step.Args[1].Value, Equals, "id")
   741  	c.Assert(step.Args[1].ArgType, Equals, gauge.Dynamic)
   742  	c.Assert(step.Args[1].Name, Equals, "id")
   743  
   744  	escapedStep := spec.Scenarios[0].Steps[1]
   745  	c.Assert(escapedStep.Value, Equals, "sample \\{static\\}")
   746  	c.Assert(len(escapedStep.Args), Equals, 0)
   747  }
   748  
   749  func (s *MySuite) TestStepsWithKeywords(c *C) {
   750  	tokens := []*Token{
   751  		&Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1},
   752  		&Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 2},
   753  		&Token{Kind: gauge.StepKind, Value: "sample {static} and {dynamic}", LineNo: 3, Args: []string{"name"}},
   754  	}
   755  
   756  	_, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary())
   757  
   758  	c.Assert(result, NotNil)
   759  	c.Assert(result.Ok, Equals, false)
   760  	c.Assert(result.ParseError.Message, Equals, "Step text should not have '{static}' or '{dynamic}' or '{special}'")
   761  	c.Assert(result.ParseError.LineNo, Equals, 3)
   762  }
   763  
   764  func (s *MySuite) TestContextWithKeywords(c *C) {
   765  	tokens := []*Token{
   766  		&Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1},
   767  		&Token{Kind: gauge.StepKind, Value: "sample {static} and {dynamic}", LineNo: 3, Args: []string{"name"}},
   768  		&Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 2},
   769  	}
   770  
   771  	_, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary())
   772  
   773  	c.Assert(result, NotNil)
   774  	c.Assert(result.Ok, Equals, false)
   775  	c.Assert(result.ParseError.Message, Equals, "Step text should not have '{static}' or '{dynamic}' or '{special}'")
   776  	c.Assert(result.ParseError.LineNo, Equals, 3)
   777  }
   778  
   779  func (s *MySuite) TestSpecWithDataTable(c *C) {
   780  	tokens := []*Token{
   781  		&Token{Kind: gauge.SpecKind, Value: "Spec Heading"},
   782  		&Token{Kind: gauge.CommentKind, Value: "Comment before data table"},
   783  		&Token{Kind: gauge.TableHeader, Args: []string{"id", "name"}},
   784  		&Token{Kind: gauge.TableRow, Args: []string{"1", "foo"}},
   785  		&Token{Kind: gauge.TableRow, Args: []string{"2", "bar"}},
   786  		&Token{Kind: gauge.CommentKind, Value: "Comment before data table"},
   787  	}
   788  
   789  	spec, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary())
   790  
   791  	c.Assert(len(spec.Items), Equals, 3)
   792  	c.Assert(spec.Items[0], Equals, spec.Comments[0])
   793  	c.Assert(spec.Items[1], DeepEquals, &spec.DataTable)
   794  	c.Assert(spec.Items[2], Equals, spec.Comments[1])
   795  
   796  	c.Assert(result.Ok, Equals, true)
   797  	c.Assert(spec.DataTable, NotNil)
   798  	c.Assert(len(spec.DataTable.Table.Get("id")), Equals, 2)
   799  	c.Assert(len(spec.DataTable.Table.Get("name")), Equals, 2)
   800  	c.Assert(spec.DataTable.Table.Get("id")[0].Value, Equals, "1")
   801  	c.Assert(spec.DataTable.Table.Get("id")[0].CellType, Equals, gauge.Static)
   802  	c.Assert(spec.DataTable.Table.Get("id")[1].Value, Equals, "2")
   803  	c.Assert(spec.DataTable.Table.Get("id")[1].CellType, Equals, gauge.Static)
   804  	c.Assert(spec.DataTable.Table.Get("name")[0].Value, Equals, "foo")
   805  	c.Assert(spec.DataTable.Table.Get("name")[0].CellType, Equals, gauge.Static)
   806  	c.Assert(spec.DataTable.Table.Get("name")[1].Value, Equals, "bar")
   807  	c.Assert(spec.DataTable.Table.Get("name")[1].CellType, Equals, gauge.Static)
   808  }
   809  
   810  func (s *MySuite) TestStepWithInlineTable(c *C) {
   811  	tokens := []*Token{
   812  		&Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1},
   813  		&Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 2},
   814  		&Token{Kind: gauge.StepKind, Value: "Step with inline table", LineNo: 3},
   815  		&Token{Kind: gauge.TableHeader, Args: []string{"id", "name"}},
   816  		&Token{Kind: gauge.TableRow, Args: []string{"1", "foo"}},
   817  		&Token{Kind: gauge.TableRow, Args: []string{"2", "bar"}},
   818  	}
   819  
   820  	spec, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary())
   821  
   822  	c.Assert(result.Ok, Equals, true)
   823  	step := spec.Scenarios[0].Steps[0]
   824  
   825  	c.Assert(step.Args[0].ArgType, Equals, gauge.TableArg)
   826  	inlineTable := step.Args[0].Table
   827  	c.Assert(inlineTable, NotNil)
   828  
   829  	c.Assert(step.Value, Equals, "Step with inline table {}")
   830  	c.Assert(step.HasInlineTable, Equals, true)
   831  	c.Assert(len(inlineTable.Get("id")), Equals, 2)
   832  	c.Assert(len(inlineTable.Get("name")), Equals, 2)
   833  	c.Assert(inlineTable.Get("id")[0].Value, Equals, "1")
   834  	c.Assert(inlineTable.Get("id")[0].CellType, Equals, gauge.Static)
   835  	c.Assert(inlineTable.Get("id")[1].Value, Equals, "2")
   836  	c.Assert(inlineTable.Get("id")[1].CellType, Equals, gauge.Static)
   837  	c.Assert(inlineTable.Get("name")[0].Value, Equals, "foo")
   838  	c.Assert(inlineTable.Get("name")[0].CellType, Equals, gauge.Static)
   839  	c.Assert(inlineTable.Get("name")[1].Value, Equals, "bar")
   840  	c.Assert(inlineTable.Get("name")[1].CellType, Equals, gauge.Static)
   841  }
   842  
   843  func (s *MySuite) TestStepWithInlineTableWithDynamicParam(c *C) {
   844  	tokens := []*Token{
   845  		&Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1},
   846  		&Token{Kind: gauge.TableHeader, Args: []string{"type1", "type2"}},
   847  		&Token{Kind: gauge.TableRow, Args: []string{"1", "2"}},
   848  		&Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 2},
   849  		&Token{Kind: gauge.StepKind, Value: "Step with inline table", LineNo: 3},
   850  		&Token{Kind: gauge.TableHeader, Args: []string{"id", "name"}},
   851  		&Token{Kind: gauge.TableRow, Args: []string{"1", "<type1>"}},
   852  		&Token{Kind: gauge.TableRow, Args: []string{"2", "<type2>"}},
   853  		&Token{Kind: gauge.TableRow, Args: []string{"<2>", "<type3>"}},
   854  	}
   855  
   856  	spec, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary())
   857  
   858  	c.Assert(result.Ok, Equals, true)
   859  	step := spec.Scenarios[0].Steps[0]
   860  
   861  	c.Assert(step.Args[0].ArgType, Equals, gauge.TableArg)
   862  	inlineTable := step.Args[0].Table
   863  	c.Assert(inlineTable, NotNil)
   864  
   865  	c.Assert(step.Value, Equals, "Step with inline table {}")
   866  	c.Assert(len(inlineTable.Get("id")), Equals, 3)
   867  	c.Assert(len(inlineTable.Get("name")), Equals, 3)
   868  	c.Assert(inlineTable.Get("id")[0].Value, Equals, "1")
   869  	c.Assert(inlineTable.Get("id")[0].CellType, Equals, gauge.Static)
   870  	c.Assert(inlineTable.Get("id")[1].Value, Equals, "2")
   871  	c.Assert(inlineTable.Get("id")[1].CellType, Equals, gauge.Static)
   872  	c.Assert(inlineTable.Get("id")[2].Value, Equals, "<2>")
   873  	c.Assert(inlineTable.Get("id")[2].CellType, Equals, gauge.Static)
   874  
   875  	c.Assert(inlineTable.Get("name")[0].Value, Equals, "type1")
   876  	c.Assert(inlineTable.Get("name")[0].CellType, Equals, gauge.Dynamic)
   877  	c.Assert(inlineTable.Get("name")[1].Value, Equals, "type2")
   878  	c.Assert(inlineTable.Get("name")[1].CellType, Equals, gauge.Dynamic)
   879  	c.Assert(inlineTable.Get("name")[2].Value, Equals, "<type3>")
   880  	c.Assert(inlineTable.Get("name")[2].CellType, Equals, gauge.Static)
   881  }
   882  
   883  func (s *MySuite) TestStepWithInlineTableWithUnResolvableDynamicParam(c *C) {
   884  	tokens := []*Token{
   885  		&Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1},
   886  		&Token{Kind: gauge.TableHeader, Args: []string{"type1", "type2"}},
   887  		&Token{Kind: gauge.TableRow, Args: []string{"1", "2"}},
   888  		&Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 2},
   889  		&Token{Kind: gauge.StepKind, Value: "Step with inline table", LineNo: 3},
   890  		&Token{Kind: gauge.TableHeader, Args: []string{"id", "name"}},
   891  		&Token{Kind: gauge.TableRow, Args: []string{"1", "<invalid>"}},
   892  		&Token{Kind: gauge.TableRow, Args: []string{"2", "<type2>"}},
   893  	}
   894  
   895  	spec, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary())
   896  	c.Assert(result.Ok, Equals, true)
   897  	c.Assert(spec.Scenarios[0].Steps[0].Args[0].Table.Get("id")[0].Value, Equals, "1")
   898  	c.Assert(spec.Scenarios[0].Steps[0].Args[0].Table.Get("name")[0].Value, Equals, "<invalid>")
   899  	c.Assert(result.Warnings[0].Message, Equals, "Dynamic param <invalid> could not be resolved, Treating it as static param")
   900  }
   901  
   902  func (s *MySuite) TestContextWithInlineTable(c *C) {
   903  	tokens := []*Token{
   904  		&Token{Kind: gauge.SpecKind, Value: "Spec Heading"},
   905  		&Token{Kind: gauge.StepKind, Value: "Context with inline table"},
   906  		&Token{Kind: gauge.TableHeader, Args: []string{"id", "name"}},
   907  		&Token{Kind: gauge.TableRow, Args: []string{"1", "foo"}},
   908  		&Token{Kind: gauge.TableRow, Args: []string{"2", "bar"}},
   909  		&Token{Kind: gauge.TableRow, Args: []string{"3", "not a <dynamic>"}},
   910  		&Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading"},
   911  	}
   912  
   913  	spec, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary())
   914  	c.Assert(len(spec.Items), Equals, 2)
   915  	c.Assert(spec.Items[0], DeepEquals, spec.Contexts[0])
   916  	c.Assert(spec.Items[1], Equals, spec.Scenarios[0])
   917  
   918  	c.Assert(result.Ok, Equals, true)
   919  	context := spec.Contexts[0]
   920  
   921  	c.Assert(context.Args[0].ArgType, Equals, gauge.TableArg)
   922  	inlineTable := context.Args[0].Table
   923  
   924  	c.Assert(inlineTable, NotNil)
   925  	c.Assert(context.Value, Equals, "Context with inline table {}")
   926  	c.Assert(len(inlineTable.Get("id")), Equals, 3)
   927  	c.Assert(len(inlineTable.Get("name")), Equals, 3)
   928  	c.Assert(inlineTable.Get("id")[0].Value, Equals, "1")
   929  	c.Assert(inlineTable.Get("id")[0].CellType, Equals, gauge.Static)
   930  	c.Assert(inlineTable.Get("id")[1].Value, Equals, "2")
   931  	c.Assert(inlineTable.Get("id")[1].CellType, Equals, gauge.Static)
   932  	c.Assert(inlineTable.Get("id")[2].Value, Equals, "3")
   933  	c.Assert(inlineTable.Get("id")[2].CellType, Equals, gauge.Static)
   934  	c.Assert(inlineTable.Get("name")[0].Value, Equals, "foo")
   935  	c.Assert(inlineTable.Get("name")[0].CellType, Equals, gauge.Static)
   936  	c.Assert(inlineTable.Get("name")[1].Value, Equals, "bar")
   937  	c.Assert(inlineTable.Get("name")[1].CellType, Equals, gauge.Static)
   938  	c.Assert(inlineTable.Get("name")[2].Value, Equals, "not a <dynamic>")
   939  	c.Assert(inlineTable.Get("name")[2].CellType, Equals, gauge.Static)
   940  }
   941  
   942  func (s *MySuite) TestErrorWhenDataTableHasOnlyHeader(c *C) {
   943  	tokens := []*Token{
   944  		&Token{Kind: gauge.SpecKind, Value: "Spec Heading"},
   945  		&Token{Kind: gauge.TableHeader, Args: []string{"id", "name"}, LineNo: 3},
   946  		&Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading"},
   947  	}
   948  
   949  	_, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary())
   950  
   951  	c.Assert(result.Ok, Equals, false)
   952  	c.Assert(result.ParseError.Message, Equals, "Data table should have at least 1 data row")
   953  	c.Assert(result.ParseError.LineNo, Equals, 3)
   954  }
   955  
   956  func (s *MySuite) TestWarningWhenParsingMultipleDataTable(c *C) {
   957  	tokens := []*Token{
   958  		&Token{Kind: gauge.SpecKind, Value: "Spec Heading"},
   959  		&Token{Kind: gauge.CommentKind, Value: "Comment before data table"},
   960  		&Token{Kind: gauge.TableHeader, Args: []string{"id", "name"}},
   961  		&Token{Kind: gauge.TableRow, Args: []string{"1", "foo"}},
   962  		&Token{Kind: gauge.TableRow, Args: []string{"2", "bar"}},
   963  		&Token{Kind: gauge.CommentKind, Value: "Comment before data table"},
   964  		&Token{Kind: gauge.TableHeader, Args: []string{"phone"}, LineNo: 7},
   965  		&Token{Kind: gauge.TableRow, Args: []string{"1"}},
   966  		&Token{Kind: gauge.TableRow, Args: []string{"2"}},
   967  	}
   968  
   969  	_, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary())
   970  
   971  	c.Assert(result.Ok, Equals, true)
   972  	c.Assert(len(result.Warnings), Equals, 1)
   973  	c.Assert(result.Warnings[0].String(), Equals, "line no: 7, Multiple data table present, ignoring table")
   974  
   975  }
   976  
   977  func (s *MySuite) TestWarningWhenParsingTableOccursWithoutStep(c *C) {
   978  	tokens := []*Token{
   979  		&Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1},
   980  		&Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 2},
   981  		&Token{Kind: gauge.TableHeader, Args: []string{"id", "name"}, LineNo: 3},
   982  		&Token{Kind: gauge.TableRow, Args: []string{"1", "foo"}, LineNo: 4},
   983  		&Token{Kind: gauge.TableRow, Args: []string{"2", "bar"}, LineNo: 5},
   984  		&Token{Kind: gauge.StepKind, Value: "Step", LineNo: 6},
   985  		&Token{Kind: gauge.CommentKind, Value: "comment in between", LineNo: 7},
   986  		&Token{Kind: gauge.TableHeader, Args: []string{"phone"}, LineNo: 8},
   987  		&Token{Kind: gauge.TableRow, Args: []string{"1"}},
   988  		&Token{Kind: gauge.TableRow, Args: []string{"2"}},
   989  	}
   990  
   991  	_, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary())
   992  	c.Assert(result.Ok, Equals, true)
   993  	c.Assert(len(result.Warnings), Equals, 2)
   994  	c.Assert(result.Warnings[0].String(), Equals, "line no: 3, Table not associated with a step, ignoring table")
   995  	c.Assert(result.Warnings[1].String(), Equals, "line no: 8, Table not associated with a step, ignoring table")
   996  
   997  }
   998  
   999  func (s *MySuite) TestAddSpecTags(c *C) {
  1000  	tokens := []*Token{
  1001  		&Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1},
  1002  		&Token{Kind: gauge.TagKind, Args: []string{"tag1", "tag2"}, LineNo: 2},
  1003  		&Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 3},
  1004  	}
  1005  
  1006  	spec, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary())
  1007  
  1008  	c.Assert(result.Ok, Equals, true)
  1009  
  1010  	c.Assert(len(spec.Tags.Values), Equals, 2)
  1011  	c.Assert(spec.Tags.Values[0], Equals, "tag1")
  1012  	c.Assert(spec.Tags.Values[1], Equals, "tag2")
  1013  }
  1014  
  1015  func (s *MySuite) TestAddSpecTagsAndScenarioTags(c *C) {
  1016  	tokens := []*Token{
  1017  		&Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1},
  1018  		&Token{Kind: gauge.TagKind, Args: []string{"tag1", "tag2"}, LineNo: 2},
  1019  		&Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 3},
  1020  		&Token{Kind: gauge.TagKind, Args: []string{"tag3", "tag4"}, LineNo: 2},
  1021  	}
  1022  
  1023  	spec, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary())
  1024  
  1025  	c.Assert(result.Ok, Equals, true)
  1026  
  1027  	c.Assert(len(spec.Tags.Values), Equals, 2)
  1028  	c.Assert(spec.Tags.Values[0], Equals, "tag1")
  1029  	c.Assert(spec.Tags.Values[1], Equals, "tag2")
  1030  
  1031  	tags := spec.Scenarios[0].Tags
  1032  	c.Assert(len(tags.Values), Equals, 2)
  1033  	c.Assert(tags.Values[0], Equals, "tag3")
  1034  	c.Assert(tags.Values[1], Equals, "tag4")
  1035  }
  1036  
  1037  func (s *MySuite) TestErrorOnAddingDynamicParamterWithoutADataTable(c *C) {
  1038  	tokens := []*Token{
  1039  		&Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1},
  1040  		&Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 2},
  1041  		&Token{Kind: gauge.StepKind, Value: "Step with a {dynamic}", Args: []string{"foo"}, LineNo: 3, LineText: "*Step with a <foo>"},
  1042  	}
  1043  
  1044  	_, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary())
  1045  
  1046  	c.Assert(result.Ok, Equals, false)
  1047  	c.Assert(result.ParseError.Message, Equals, "Dynamic parameter <foo> could not be resolved")
  1048  	c.Assert(result.ParseError.LineNo, Equals, 3)
  1049  
  1050  }
  1051  
  1052  func (s *MySuite) TestErrorOnAddingDynamicParamterWithoutDataTableHeaderValue(c *C) {
  1053  	tokens := []*Token{
  1054  		&Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1},
  1055  		&Token{Kind: gauge.TableHeader, Args: []string{"id, name"}, LineNo: 2},
  1056  		&Token{Kind: gauge.TableRow, Args: []string{"123, hello"}, LineNo: 3},
  1057  		&Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 4},
  1058  		&Token{Kind: gauge.StepKind, Value: "Step with a {dynamic}", Args: []string{"foo"}, LineNo: 5, LineText: "*Step with a <foo>"},
  1059  	}
  1060  
  1061  	_, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary())
  1062  
  1063  	c.Assert(result.Ok, Equals, false)
  1064  	c.Assert(result.ParseError.Message, Equals, "Dynamic parameter <foo> could not be resolved")
  1065  	c.Assert(result.ParseError.LineNo, Equals, 5)
  1066  
  1067  }
  1068  
  1069  func (s *MySuite) TestCreateStepFromSimpleConcept(c *C) {
  1070  	tokens := []*Token{
  1071  		&Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1},
  1072  		&Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 2},
  1073  		&Token{Kind: gauge.StepKind, Value: "test concept step 1", LineNo: 3},
  1074  	}
  1075  
  1076  	conceptDictionary := gauge.NewConceptDictionary()
  1077  	path, _ := filepath.Abs(filepath.Join("testdata", "concept.cpt"))
  1078  	AddConcepts(path, conceptDictionary)
  1079  	spec, result := new(SpecParser).CreateSpecification(tokens, conceptDictionary)
  1080  	c.Assert(result.Ok, Equals, true)
  1081  
  1082  	c.Assert(len(spec.Scenarios[0].Steps), Equals, 1)
  1083  	specConceptStep := spec.Scenarios[0].Steps[0]
  1084  	c.Assert(specConceptStep.IsConcept, Equals, true)
  1085  	assertStepEqual(c, &gauge.Step{LineNo: 2, Value: "step 1", LineText: "step 1"}, specConceptStep.ConceptSteps[0])
  1086  }
  1087  
  1088  func (s *MySuite) TestCreateStepFromConceptWithParameters(c *C) {
  1089  	tokens := []*Token{
  1090  		&Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1},
  1091  		&Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 2},
  1092  		&Token{Kind: gauge.StepKind, Value: "assign id {static} and name {static}", Args: []string{"foo", "foo1"}, LineNo: 3},
  1093  		&Token{Kind: gauge.StepKind, Value: "assign id {static} and name {static}", Args: []string{"bar", "bar1"}, LineNo: 4},
  1094  	}
  1095  
  1096  	conceptDictionary := gauge.NewConceptDictionary()
  1097  	path, _ := filepath.Abs(filepath.Join("testdata", "dynamic_param_concept.cpt"))
  1098  	AddConcepts(path, conceptDictionary)
  1099  
  1100  	spec, result := new(SpecParser).CreateSpecification(tokens, conceptDictionary)
  1101  	c.Assert(result.Ok, Equals, true)
  1102  
  1103  	c.Assert(len(spec.Scenarios[0].Steps), Equals, 2)
  1104  
  1105  	firstConceptStep := spec.Scenarios[0].Steps[0]
  1106  	c.Assert(firstConceptStep.IsConcept, Equals, true)
  1107  	c.Assert(firstConceptStep.ConceptSteps[0].Value, Equals, "add id {}")
  1108  	c.Assert(firstConceptStep.ConceptSteps[0].Args[0].Value, Equals, "userid")
  1109  	c.Assert(firstConceptStep.ConceptSteps[1].Value, Equals, "add name {}")
  1110  	c.Assert(firstConceptStep.ConceptSteps[1].Args[0].Value, Equals, "username")
  1111  	c.Assert(firstConceptStep.GetArg("username").Value, Equals, "foo1")
  1112  	c.Assert(firstConceptStep.GetArg("userid").Value, Equals, "foo")
  1113  
  1114  	secondConceptStep := spec.Scenarios[0].Steps[1]
  1115  	c.Assert(secondConceptStep.IsConcept, Equals, true)
  1116  	c.Assert(secondConceptStep.ConceptSteps[0].Value, Equals, "add id {}")
  1117  	c.Assert(secondConceptStep.ConceptSteps[0].Args[0].Value, Equals, "userid")
  1118  	c.Assert(secondConceptStep.ConceptSteps[1].Value, Equals, "add name {}")
  1119  	c.Assert(secondConceptStep.ConceptSteps[1].Args[0].Value, Equals, "username")
  1120  	c.Assert(secondConceptStep.GetArg("username").Value, Equals, "bar1")
  1121  	c.Assert(secondConceptStep.GetArg("userid").Value, Equals, "bar")
  1122  
  1123  }
  1124  
  1125  func (s *MySuite) TestCreateStepFromConceptWithDynamicParameters(c *C) {
  1126  	tokens := []*Token{
  1127  		&Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1},
  1128  		&Token{Kind: gauge.TableHeader, Args: []string{"id", "description"}, LineNo: 2},
  1129  		&Token{Kind: gauge.TableRow, Args: []string{"123", "Admin fellow"}, LineNo: 3},
  1130  		&Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 4},
  1131  		&Token{Kind: gauge.StepKind, Value: "assign id {dynamic} and name {dynamic}", Args: []string{"id", "description"}, LineNo: 5},
  1132  	}
  1133  
  1134  	conceptDictionary := gauge.NewConceptDictionary()
  1135  	path, _ := filepath.Abs(filepath.Join("testdata", "dynamic_param_concept.cpt"))
  1136  	AddConcepts(path, conceptDictionary)
  1137  	spec, result := new(SpecParser).CreateSpecification(tokens, conceptDictionary)
  1138  	c.Assert(result.Ok, Equals, true)
  1139  
  1140  	c.Assert(len(spec.Items), Equals, 2)
  1141  	c.Assert(spec.Items[0], DeepEquals, &spec.DataTable)
  1142  	c.Assert(spec.Items[1], Equals, spec.Scenarios[0])
  1143  
  1144  	scenarioItems := (spec.Items[1]).(*gauge.Scenario).Items
  1145  	c.Assert(scenarioItems[0], Equals, spec.Scenarios[0].Steps[0])
  1146  
  1147  	c.Assert(len(spec.Scenarios[0].Steps), Equals, 1)
  1148  
  1149  	firstConcept := spec.Scenarios[0].Steps[0]
  1150  	c.Assert(firstConcept.IsConcept, Equals, true)
  1151  	c.Assert(firstConcept.ConceptSteps[0].Value, Equals, "add id {}")
  1152  	c.Assert(firstConcept.ConceptSteps[0].Args[0].ArgType, Equals, gauge.Dynamic)
  1153  	c.Assert(firstConcept.ConceptSteps[0].Args[0].Value, Equals, "userid")
  1154  	c.Assert(firstConcept.ConceptSteps[1].Value, Equals, "add name {}")
  1155  	c.Assert(firstConcept.ConceptSteps[1].Args[0].Value, Equals, "username")
  1156  	c.Assert(firstConcept.ConceptSteps[1].Args[0].ArgType, Equals, gauge.Dynamic)
  1157  
  1158  	arg1 := firstConcept.Lookup.GetArg("userid")
  1159  	c.Assert(arg1.Value, Equals, "id")
  1160  	c.Assert(arg1.ArgType, Equals, gauge.Dynamic)
  1161  
  1162  	arg2 := firstConcept.Lookup.GetArg("username")
  1163  	c.Assert(arg2.Value, Equals, "description")
  1164  	c.Assert(arg2.ArgType, Equals, gauge.Dynamic)
  1165  }
  1166  
  1167  func (s *MySuite) TestCreateStepFromConceptWithInlineTable(c *C) {
  1168  	tokens := []*Token{
  1169  		&Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1},
  1170  		&Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 4},
  1171  		&Token{Kind: gauge.StepKind, Value: "assign id {static} and name", Args: []string{"sdf"}, LineNo: 3},
  1172  		&Token{Kind: gauge.TableHeader, Args: []string{"id", "description"}, LineNo: 4},
  1173  		&Token{Kind: gauge.TableRow, Args: []string{"123", "Admin"}, LineNo: 5},
  1174  		&Token{Kind: gauge.TableRow, Args: []string{"456", "normal fellow"}, LineNo: 6},
  1175  	}
  1176  
  1177  	conceptDictionary := gauge.NewConceptDictionary()
  1178  	path, _ := filepath.Abs(filepath.Join("testdata", "dynamic_param_concept.cpt"))
  1179  	AddConcepts(path, conceptDictionary)
  1180  	spec, result := new(SpecParser).CreateSpecification(tokens, conceptDictionary)
  1181  	c.Assert(result.Ok, Equals, true)
  1182  
  1183  	steps := spec.Scenarios[0].Steps
  1184  	c.Assert(len(steps), Equals, 1)
  1185  	c.Assert(steps[0].IsConcept, Equals, true)
  1186  	c.Assert(steps[0].Value, Equals, "assign id {} and name {}")
  1187  	c.Assert(len(steps[0].Args), Equals, 2)
  1188  	c.Assert(steps[0].Args[1].ArgType, Equals, gauge.TableArg)
  1189  	c.Assert(len(steps[0].ConceptSteps), Equals, 2)
  1190  }
  1191  
  1192  func (s *MySuite) TestCreateStepFromConceptWithInlineTableHavingDynamicParam(c *C) {
  1193  	tokens := []*Token{
  1194  		&Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1},
  1195  		&Token{Kind: gauge.TableHeader, Args: []string{"id", "description"}, LineNo: 2},
  1196  		&Token{Kind: gauge.TableRow, Args: []string{"123", "Admin"}, LineNo: 3},
  1197  		&Token{Kind: gauge.TableRow, Args: []string{"456", "normal fellow"}, LineNo: 4},
  1198  		&Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 5},
  1199  		&Token{Kind: gauge.StepKind, Value: "assign id {static} and name", Args: []string{"sdf"}, LineNo: 6},
  1200  		&Token{Kind: gauge.TableHeader, Args: []string{"user-id", "description", "name"}, LineNo: 7},
  1201  		&Token{Kind: gauge.TableRow, Args: []string{"<id>", "<description>", "root"}, LineNo: 8},
  1202  	}
  1203  
  1204  	conceptDictionary := gauge.NewConceptDictionary()
  1205  	path, _ := filepath.Abs(filepath.Join("testdata", "dynamic_param_concept.cpt"))
  1206  	AddConcepts(path, conceptDictionary)
  1207  	spec, result := new(SpecParser).CreateSpecification(tokens, conceptDictionary)
  1208  	c.Assert(result.Ok, Equals, true)
  1209  
  1210  	steps := spec.Scenarios[0].Steps
  1211  	c.Assert(len(steps), Equals, 1)
  1212  	c.Assert(steps[0].IsConcept, Equals, true)
  1213  	c.Assert(steps[0].Value, Equals, "assign id {} and name {}")
  1214  	c.Assert(len(steps[0].Args), Equals, 2)
  1215  	c.Assert(steps[0].Args[1].ArgType, Equals, gauge.TableArg)
  1216  	table := steps[0].Args[1].Table
  1217  	c.Assert(table.Get("user-id")[0].Value, Equals, "id")
  1218  	c.Assert(table.Get("user-id")[0].CellType, Equals, gauge.Dynamic)
  1219  	c.Assert(table.Get("description")[0].Value, Equals, "description")
  1220  	c.Assert(table.Get("description")[0].CellType, Equals, gauge.Dynamic)
  1221  	c.Assert(table.Get("name")[0].Value, Equals, "root")
  1222  	c.Assert(table.Get("name")[0].CellType, Equals, gauge.Static)
  1223  	c.Assert(len(steps[0].ConceptSteps), Equals, 2)
  1224  }
  1225  
  1226  func (s *MySuite) TestCreateConceptStep(c *C) {
  1227  	dictionary := gauge.NewConceptDictionary()
  1228  	path, _ := filepath.Abs(filepath.Join("testdata", "param_nested_concept.cpt"))
  1229  	AddConcepts(path, dictionary)
  1230  
  1231  	argsInStep := []*gauge.StepArg{&gauge.StepArg{Name: "bar", Value: "first name", ArgType: gauge.Static}, &gauge.StepArg{Name: "far", Value: "last name", ArgType: gauge.Static}}
  1232  	originalStep := &gauge.Step{
  1233  		LineNo:         12,
  1234  		Value:          "create user {} {}",
  1235  		LineText:       "create user \"first name\" \"last name\"",
  1236  		Args:           argsInStep,
  1237  		IsConcept:      false,
  1238  		HasInlineTable: false}
  1239  
  1240  	createConceptStep(new(gauge.Specification), dictionary.Search("create user {} {}").ConceptStep, originalStep)
  1241  
  1242  	c.Assert(originalStep.IsConcept, Equals, true)
  1243  	c.Assert(len(originalStep.ConceptSteps), Equals, 1)
  1244  	c.Assert(originalStep.Args[0].Value, Equals, "first name")
  1245  	c.Assert(originalStep.Lookup.GetArg("bar").Value, Equals, "first name")
  1246  	c.Assert(originalStep.Args[1].Value, Equals, "last name")
  1247  	c.Assert(originalStep.Lookup.GetArg("far").Value, Equals, "last name")
  1248  
  1249  	nestedConcept := originalStep.ConceptSteps[0]
  1250  	c.Assert(nestedConcept.IsConcept, Equals, true)
  1251  	c.Assert(len(nestedConcept.ConceptSteps), Equals, 1)
  1252  
  1253  	c.Assert(nestedConcept.Args[0].ArgType, Equals, gauge.Dynamic)
  1254  	c.Assert(nestedConcept.Args[0].Name, Equals, "bar")
  1255  
  1256  	c.Assert(nestedConcept.Args[1].ArgType, Equals, gauge.Dynamic)
  1257  	c.Assert(nestedConcept.Args[1].Name, Equals, "far")
  1258  
  1259  	c.Assert(nestedConcept.ConceptSteps[0].Args[0].ArgType, Equals, gauge.Dynamic)
  1260  	c.Assert(nestedConcept.ConceptSteps[0].Args[0].Name, Equals, "baz")
  1261  
  1262  	c.Assert(nestedConcept.Lookup.GetArg("baz").ArgType, Equals, gauge.Dynamic)
  1263  	c.Assert(nestedConcept.Lookup.GetArg("baz").Value, Equals, "bar")
  1264  }
  1265  
  1266  func (s *MySuite) TestCreateInValidSpecialArgInStep(c *C) {
  1267  	tokens := []*Token{
  1268  		&Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1},
  1269  		&Token{Kind: gauge.TableHeader, Args: []string{"unknown:foo", "description"}, LineNo: 2},
  1270  		&Token{Kind: gauge.TableRow, Args: []string{"123", "Admin"}, LineNo: 3},
  1271  		&Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 2},
  1272  		&Token{Kind: gauge.StepKind, Value: "Example {special} step", LineNo: 3, Args: []string{"unknown:foo"}},
  1273  	}
  1274  	spec, parseResults := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary())
  1275  	c.Assert(spec.Scenarios[0].Steps[0].Args[0].ArgType, Equals, gauge.Dynamic)
  1276  	c.Assert(len(parseResults.Warnings), Equals, 1)
  1277  	c.Assert(parseResults.Warnings[0].Message, Equals, "Could not resolve special param type <unknown:foo>. Treating it as dynamic param.")
  1278  }
  1279  
  1280  func (s *MySuite) TestTearDownSteps(c *C) {
  1281  	tokens := []*Token{
  1282  		&Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1},
  1283  		&Token{Kind: gauge.CommentKind, Value: "A comment with some text and **bold** characters", LineNo: 2},
  1284  		&Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 3},
  1285  		&Token{Kind: gauge.CommentKind, Value: "Another comment", LineNo: 4},
  1286  		&Token{Kind: gauge.StepKind, Value: "Example step", LineNo: 5},
  1287  		&Token{Kind: gauge.CommentKind, Value: "Third comment", LineNo: 6},
  1288  		&Token{Kind: gauge.TearDownKind, Value: "____", LineNo: 7},
  1289  		&Token{Kind: gauge.StepKind, Value: "Example step1", LineNo: 8},
  1290  		&Token{Kind: gauge.CommentKind, Value: "Fourth comment", LineNo: 9},
  1291  		&Token{Kind: gauge.StepKind, Value: "Example step2", LineNo: 10},
  1292  	}
  1293  
  1294  	spec, _ := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary())
  1295  	c.Assert(len(spec.TearDownSteps), Equals, 2)
  1296  	c.Assert(spec.TearDownSteps[0].Value, Equals, "Example step1")
  1297  	c.Assert(spec.TearDownSteps[0].LineNo, Equals, 8)
  1298  	c.Assert(spec.TearDownSteps[1].Value, Equals, "Example step2")
  1299  	c.Assert(spec.TearDownSteps[1].LineNo, Equals, 10)
  1300  }
  1301  
  1302  func (s *MySuite) TestParsingOfTableWithHyphens(c *C) {
  1303  	p := new(SpecParser)
  1304  
  1305  	text := SpecBuilder().specHeading("My Spec Heading").text("|id|").text("|--|").text("|1 |").text("|- |").String()
  1306  	tokens, _ := p.GenerateTokens(text)
  1307  
  1308  	spec, _ := p.CreateSpecification(tokens, gauge.NewConceptDictionary())
  1309  	c.Assert((len(spec.DataTable.Table.Get("id"))), Equals, 2)
  1310  	c.Assert(spec.DataTable.Table.Get("id")[0].Value, Equals, "1")
  1311  	c.Assert(spec.DataTable.Table.Get("id")[1].Value, Equals, "-")
  1312  }