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 }