github.com/ezbuy/gauge@v0.9.4-0.20171013092048-7ac5bd3931cd/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("").text("dsfdsf").String() 74 75 _, res := parser.Parse(specText, gauge.NewConceptDictionary(), "foo.spec") 76 77 c.Assert(len(res.ParseErrors) > 0, Equals, true) 78 c.Assert(res.ParseErrors[0].Error(), Equals, "foo.spec: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 _, errs := parser.GenerateTokens(specText, "foo.spec") 98 99 c.Assert(len(errs) > 0, Equals, true) 100 c.Assert(errs[0].Error(), Equals, "foo.spec: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) TestParseScenarioWithTagsInMultipleLines(c *C) { 299 parser := new(SpecParser) 300 specText := SpecBuilder().specHeading("Spec heading with hash ").scenarioHeading("Scenario Heading").tags("tag1", "\ntag2").String() 301 302 tokens, err := parser.GenerateTokens(specText, "") 303 304 c.Assert(err, IsNil) 305 c.Assert(len(tokens), Equals, 4) 306 307 c.Assert(tokens[2].Kind, Equals, gauge.TagKind) 308 c.Assert(len(tokens[2].Args), Equals, 1) 309 c.Assert(tokens[2].Args[0], Equals, "tag1") 310 c.Assert(tokens[2].LineText, Equals, "tags: tag1,") 311 c.Assert(tokens[2].Value, Equals, "tag1,") 312 c.Assert(tokens[3].Args[0], Equals, "tag2") 313 c.Assert(tokens[3].LineText, Equals, "tag2") 314 c.Assert(tokens[3].Value, Equals, "tag2") 315 } 316 317 func (s *MySuite) TestParseSpecTagsBeforeSpecHeading(c *C) { 318 parser := new(SpecParser) 319 specText := SpecBuilder().tags("tag1 ").specHeading("Spec heading with hash ").String() 320 321 tokens, err := parser.GenerateTokens(specText, "") 322 323 c.Assert(err, IsNil) 324 c.Assert(len(tokens), Equals, 2) 325 326 c.Assert(tokens[0].Kind, Equals, gauge.TagKind) 327 c.Assert(len(tokens[0].Args), Equals, 1) 328 c.Assert(tokens[0].Args[0], Equals, "tag1") 329 c.Assert(tokens[0].LineText, Equals, "tags: tag1 ") 330 c.Assert(tokens[0].Value, Equals, "tag1") 331 } 332 333 func (s *MySuite) TestParsingSimpleDataTable(c *C) { 334 parser := new(SpecParser) 335 specText := SpecBuilder().specHeading("Spec heading").text("|name|id|").text("|---|---|").text("|john|123|").text("|james|007|").String() 336 337 tokens, err := parser.GenerateTokens(specText, "") 338 c.Assert(err, IsNil) 339 c.Assert(len(tokens), Equals, 5) 340 341 c.Assert(tokens[1].Kind, Equals, gauge.TableHeader) 342 c.Assert(len(tokens[1].Args), Equals, 2) 343 c.Assert(tokens[1].Args[0], Equals, "name") 344 c.Assert(tokens[1].Args[1], Equals, "id") 345 346 c.Assert(tokens[2].Kind, Equals, gauge.TableRow) 347 c.Assert(len(tokens[2].Args), Equals, 2) 348 c.Assert(tokens[2].Args[0], Equals, "---") 349 c.Assert(tokens[2].Args[1], Equals, "---") 350 351 c.Assert(tokens[3].Kind, Equals, gauge.TableRow) 352 c.Assert(len(tokens[3].Args), Equals, 2) 353 c.Assert(tokens[3].Args[0], Equals, "john") 354 c.Assert(tokens[3].Args[1], Equals, "123") 355 356 c.Assert(tokens[4].Kind, Equals, gauge.TableRow) 357 c.Assert(len(tokens[4].Args), Equals, 2) 358 c.Assert(tokens[4].Args[0], Equals, "james") 359 c.Assert(tokens[4].Args[1], Equals, "007") 360 361 } 362 363 func (s *MySuite) TestParsingMultipleDataTable(c *C) { 364 parser := new(SpecParser) 365 specText := SpecBuilder().specHeading("Spec heading").text("|name|id|").text("|john|123|").text("|james|007|").step("Example step").text("|user|role|").text("|root | admin|").String() 366 367 tokens, err := parser.GenerateTokens(specText, "") 368 c.Assert(err, IsNil) 369 c.Assert(len(tokens), Equals, 7) 370 371 c.Assert(tokens[1].Kind, Equals, gauge.TableHeader) 372 c.Assert(len(tokens[1].Args), Equals, 2) 373 c.Assert(tokens[1].Args[0], Equals, "name") 374 c.Assert(tokens[1].Args[1], Equals, "id") 375 376 c.Assert(tokens[2].Kind, Equals, gauge.TableRow) 377 c.Assert(len(tokens[2].Args), Equals, 2) 378 c.Assert(tokens[2].Args[0], Equals, "john") 379 c.Assert(tokens[2].Args[1], Equals, "123") 380 381 c.Assert(tokens[3].Kind, Equals, gauge.TableRow) 382 c.Assert(len(tokens[3].Args), Equals, 2) 383 c.Assert(tokens[3].Args[0], Equals, "james") 384 c.Assert(tokens[3].Args[1], Equals, "007") 385 386 c.Assert(tokens[5].Kind, Equals, gauge.TableHeader) 387 c.Assert(len(tokens[5].Args), Equals, 2) 388 c.Assert(tokens[5].Args[0], Equals, "user") 389 c.Assert(tokens[5].Args[1], Equals, "role") 390 391 c.Assert(tokens[6].Kind, Equals, gauge.TableRow) 392 c.Assert(len(tokens[6].Args), Equals, 2) 393 c.Assert(tokens[6].Args[0], Equals, "root") 394 c.Assert(tokens[6].Args[1], Equals, "admin") 395 } 396 397 func (s *MySuite) TestParsingDataTableWithEmptyHeaderSeparatorRow(c *C) { 398 parser := new(SpecParser) 399 specText := SpecBuilder().specHeading("Spec heading").text("|name|id|").text("|||").text("|john|123|").String() 400 401 tokens, err := parser.GenerateTokens(specText, "") 402 c.Assert(err, IsNil) 403 c.Assert(len(tokens), Equals, 4) 404 405 c.Assert(tokens[1].Kind, Equals, gauge.TableHeader) 406 c.Assert(len(tokens[1].Args), Equals, 2) 407 c.Assert(tokens[1].Args[0], Equals, "name") 408 c.Assert(tokens[1].Args[1], Equals, "id") 409 410 c.Assert(tokens[2].Kind, Equals, gauge.TableRow) 411 c.Assert(len(tokens[2].Args), Equals, 2) 412 c.Assert(tokens[2].Args[0], Equals, "") 413 c.Assert(tokens[2].Args[1], Equals, "") 414 415 c.Assert(tokens[3].Kind, Equals, gauge.TableRow) 416 c.Assert(len(tokens[3].Args), Equals, 2) 417 c.Assert(tokens[3].Args[0], Equals, "john") 418 c.Assert(tokens[3].Args[1], Equals, "123") 419 420 } 421 422 func (s *MySuite) TestParsingDataTableRowEscapingPipe(c *C) { 423 parser := new(SpecParser) 424 specText := SpecBuilder().specHeading("Spec heading").text("| name|id | address| phone|").text("| escape \\| pipe |second|third|").String() 425 426 tokens, err := parser.GenerateTokens(specText, "") 427 c.Assert(err, IsNil) 428 c.Assert(len(tokens), Equals, 3) 429 430 c.Assert(tokens[1].Kind, Equals, gauge.TableHeader) 431 c.Assert(len(tokens[1].Args), Equals, 4) 432 c.Assert(tokens[1].Args[0], Equals, "name") 433 c.Assert(tokens[1].Args[1], Equals, "id") 434 c.Assert(tokens[1].Args[2], Equals, "address") 435 c.Assert(tokens[1].Args[3], Equals, "phone") 436 437 c.Assert(tokens[2].Kind, Equals, gauge.TableRow) 438 c.Assert(len(tokens[2].Args), Equals, 3) 439 c.Assert(tokens[2].Args[0], Equals, "escape | pipe") 440 c.Assert(tokens[2].Args[1], Equals, "second") 441 c.Assert(tokens[2].Args[2], Equals, "third") 442 443 } 444 445 func (s *MySuite) TestParsingDataTableThrowsErrorWithEmptyHeader(c *C) { 446 parser := new(SpecParser) 447 specText := SpecBuilder().specHeading("Spec heading").text("| name|id |||").text("| escape \\| pipe |second|third|second|").String() 448 449 _, errs := parser.GenerateTokens(specText, "foo.spec") 450 c.Assert(len(errs) > 0, Equals, true) 451 c.Assert(errs[0].Error(), Equals, "foo.spec:2 Table header should not be blank => '| name|id |||'") 452 } 453 454 func (s *MySuite) TestParsingDataTableThrowsErrorWithSameColumnHeader(c *C) { 455 parser := new(SpecParser) 456 specText := SpecBuilder().specHeading("Spec heading").text("| name|id|name|").text("|1|2|3|").String() 457 458 _, errs := parser.GenerateTokens(specText, "foo.spec") 459 c.Assert(len(errs) > 0, Equals, true) 460 c.Assert(errs[0].Error(), Equals, "foo.spec:2 Table header cannot have repeated column values => '| name|id|name|'") 461 } 462 463 func (s *MySuite) TestParsingDataTableWithSeparatorAsHeader(c *C) { 464 parser := new(SpecParser) 465 specText := SpecBuilder().specHeading("Spec heading").text("|---|--|-|").text("|---|--|-|").text("|---|--|-|").text("| escape \\| pipe |second|third|").String() 466 467 tokens, err := parser.GenerateTokens(specText, "") 468 c.Assert(err, IsNil) 469 c.Assert(len(tokens), Equals, 5) 470 471 c.Assert(tokens[1].Kind, Equals, gauge.TableHeader) 472 c.Assert(len(tokens[1].Args), Equals, 3) 473 c.Assert(tokens[1].Args[0], Equals, "---") 474 c.Assert(tokens[1].Args[1], Equals, "--") 475 c.Assert(tokens[1].Args[2], Equals, "-") 476 477 c.Assert(tokens[2].Kind, Equals, gauge.TableRow) 478 c.Assert(len(tokens[2].Args), Equals, 3) 479 c.Assert(tokens[2].Args[0], Equals, "---") 480 c.Assert(tokens[2].Args[1], Equals, "--") 481 c.Assert(tokens[2].Args[2], Equals, "-") 482 483 } 484 485 func (s *MySuite) TestParsingSpecWithMultipleLines(c *C) { 486 parser := new(SpecParser) 487 specText := SpecBuilder().specHeading("A spec heading"). 488 text("Hello, i am a comment"). 489 text(" "). 490 step("Context step with \"param\" and <file:foo>"). 491 text("|a|b|c|"). 492 text("|--||"). 493 text("|a1|a2|a3|"). 494 tags("one", "two"). 495 scenarioHeading("First flow"). 496 tags("tag1", "tag2"). 497 step("first with \"fpp\" and <bar>"). 498 text("Comment in scenario"). 499 step("<table:file.csv> and <another> with \"foo\""). 500 scenarioHeading("First flow"). 501 step("another").String() 502 503 tokens, err := parser.GenerateTokens(specText, "") 504 c.Assert(err, IsNil) 505 c.Assert(len(tokens), Equals, 15) 506 507 c.Assert(tokens[0].Kind, Equals, gauge.SpecKind) 508 c.Assert(tokens[1].Kind, Equals, gauge.CommentKind) 509 c.Assert(tokens[2].Kind, Equals, gauge.CommentKind) 510 511 c.Assert(tokens[3].Kind, Equals, gauge.StepKind) 512 c.Assert(tokens[3].Value, Equals, "Context step with {static} and {special}") 513 514 c.Assert(tokens[4].Kind, Equals, gauge.TableHeader) 515 c.Assert(tokens[5].Kind, Equals, gauge.TableRow) 516 c.Assert(tokens[6].Kind, Equals, gauge.TableRow) 517 c.Assert(tokens[7].Kind, Equals, gauge.TagKind) 518 c.Assert(tokens[8].Kind, Equals, gauge.ScenarioKind) 519 c.Assert(tokens[9].Kind, Equals, gauge.TagKind) 520 521 c.Assert(tokens[10].Kind, Equals, gauge.StepKind) 522 c.Assert(tokens[10].Value, Equals, "first with {static} and {dynamic}") 523 524 c.Assert(tokens[11].Kind, Equals, gauge.CommentKind) 525 526 c.Assert(tokens[12].Kind, Equals, gauge.StepKind) 527 c.Assert(tokens[12].Value, Equals, "{special} and {dynamic} with {static}") 528 529 c.Assert(tokens[13].Kind, Equals, gauge.ScenarioKind) 530 531 c.Assert(tokens[14].Kind, Equals, gauge.StepKind) 532 c.Assert(tokens[14].Value, Equals, "another") 533 534 } 535 536 func (s *MySuite) TestParsingMultilineStep(c *C) { 537 parser := new(SpecParser) 538 specText := SpecBuilder(). 539 step("step1"). 540 text(""). 541 tableHeader("foo|bar"). 542 tableRow("somerow|another").String() 543 544 tokens, err := parser.GenerateTokens(specText, "") 545 c.Assert(err, IsNil) 546 c.Assert(len(tokens), Equals, 3) 547 548 c.Assert(tokens[0].Kind, Equals, gauge.StepKind) 549 550 c.Assert(tokens[1].Kind, Equals, gauge.TableHeader) 551 c.Assert(tokens[2].Kind, Equals, gauge.TableRow) 552 } 553 554 func (s *MySuite) TestParsingSpecWithTearDownSteps(c *C) { 555 parser := new(SpecParser) 556 specText := SpecBuilder().specHeading("A spec heading"). 557 text("Hello, i am a comment"). 558 scenarioHeading("First flow"). 559 step("another"). 560 text("_____"). 561 step("step1"). 562 step("step2").String() 563 564 tokens, err := parser.GenerateTokens(specText, "") 565 c.Assert(err, IsNil) 566 c.Assert(len(tokens), Equals, 7) 567 568 c.Assert(tokens[0].Kind, Equals, gauge.SpecKind) 569 c.Assert(tokens[1].Kind, Equals, gauge.CommentKind) 570 571 c.Assert(tokens[2].Kind, Equals, gauge.ScenarioKind) 572 c.Assert(tokens[3].Kind, Equals, gauge.StepKind) 573 c.Assert(tokens[3].Value, Equals, "another") 574 c.Assert(tokens[4].Kind, Equals, gauge.TearDownKind) 575 576 c.Assert(tokens[5].Kind, Equals, gauge.StepKind) 577 c.Assert(tokens[5].Value, Equals, "step1") 578 c.Assert(tokens[6].Kind, Equals, gauge.StepKind) 579 c.Assert(tokens[6].Value, Equals, "step2") 580 581 } 582 583 func (s *MySuite) TestToCheckTagsInSpecLevel(c *C) { 584 tokens := []*Token{ 585 {Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1}, 586 {Kind: gauge.TagKind, Args: []string{"tag1", "tag2"}, LineNo: 2}, 587 {Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 3}, 588 {Kind: gauge.StepKind, Value: "my step"}, 589 } 590 591 spec, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary(), "") 592 593 c.Assert(result.Ok, Equals, true) 594 595 c.Assert(len(spec.Tags.Values()), Equals, 2) 596 c.Assert(spec.Tags.Values()[0], Equals, "tag1") 597 c.Assert(spec.Tags.Values()[1], Equals, "tag2") 598 } 599 600 func (s *MySuite) TestToCheckTagsInScenarioLevel(c *C) { 601 tokens := []*Token{ 602 {Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1}, 603 {Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 2}, 604 {Kind: gauge.TagKind, Args: []string{"tag1", "tag2"}, LineNo: 3}, 605 {Kind: gauge.StepKind, Value: "my step"}, 606 } 607 608 spec, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary(), "") 609 610 c.Assert(result.Ok, Equals, true) 611 612 c.Assert(len(spec.Scenarios[0].Tags.Values()), Equals, 2) 613 c.Assert(spec.Scenarios[0].Tags.Values()[0], Equals, "tag1") 614 c.Assert(spec.Scenarios[0].Tags.Values()[1], Equals, "tag2") 615 } 616 617 func (s *MySuite) TestParsingConceptInSpec(c *C) { 618 parser := new(SpecParser) 619 specText := SpecBuilder().specHeading("A spec heading"). 620 scenarioHeading("First flow"). 621 step("test concept step 1"). 622 step("another step").String() 623 conceptDictionary := gauge.NewConceptDictionary() 624 path, _ := filepath.Abs(filepath.Join("testdata", "concept.cpt")) 625 AddConcepts([]string{path}, conceptDictionary) 626 tokens, err := parser.GenerateTokens(specText, "") 627 c.Assert(err, IsNil) 628 spec, parseResult := parser.CreateSpecification(tokens, conceptDictionary, "") 629 630 c.Assert(parseResult.Ok, Equals, true) 631 firstStepInSpec := spec.Scenarios[0].Steps[0] 632 secondStepInSpec := spec.Scenarios[0].Steps[1] 633 c.Assert(firstStepInSpec.ConceptSteps[0].Parent, Equals, firstStepInSpec) 634 c.Assert(firstStepInSpec.Parent, IsNil) 635 c.Assert(secondStepInSpec.Parent, IsNil) 636 } 637 638 func (s *MySuite) TestTableInputFromInvalidFileAndDataTableNotInitialized(c *C) { 639 parser := new(SpecParser) 640 specText := SpecBuilder().specHeading("Spec heading").text("table: inputinvalid.csv").text("comment").scenarioHeading("Sce heading").step("my step").String() 641 642 _, parseRes := parser.Parse(specText, gauge.NewConceptDictionary(), "") 643 c.Assert(parseRes.ParseErrors[0].Message, Equals, "Could not resolve table from table: inputinvalid.csv") 644 c.Assert(parseRes.Ok, Equals, false) 645 } 646 647 func (s *MySuite) TestTableInputFromFile(c *C) { 648 parser := new(SpecParser) 649 specText := SpecBuilder().specHeading("Spec heading").text("Table: inputinvalid.csv").text("comment").scenarioHeading("Sce heading").step("my step").String() 650 651 _, parseRes := parser.Parse(specText, gauge.NewConceptDictionary(), "") 652 c.Assert(parseRes.ParseErrors[0].Message, Equals, "Could not resolve table from Table: inputinvalid.csv") 653 c.Assert(parseRes.Ok, Equals, false) 654 } 655 656 func (s *MySuite) TestTableInputFromFileIfPathNotSpecified(c *C) { 657 parser := new(SpecParser) 658 specText := SpecBuilder().specHeading("Spec heading").text("Table: ").scenarioHeading("Sce heading").step("my step").String() 659 660 _, parseRes := parser.Parse(specText, gauge.NewConceptDictionary(), "") 661 c.Assert(parseRes.ParseErrors[0].Message, Equals, "Table location not specified") 662 c.Assert(parseRes.Ok, Equals, false) 663 } 664 665 func (s *MySuite) TestToSplitTagNames(c *C) { 666 allTags := splitAndTrimTags("tag1 , tag2, tag3") 667 c.Assert(allTags[0], Equals, "tag1") 668 c.Assert(allTags[1], Equals, "tag2") 669 c.Assert(allTags[2], Equals, "tag3") 670 } 671 672 func (s *MySuite) TestThrowsErrorForMultipleSpecHeading(c *C) { 673 tokens := []*Token{ 674 &Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1}, 675 &Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 2}, 676 &Token{Kind: gauge.StepKind, Value: "Example step", LineNo: 3}, 677 &Token{Kind: gauge.SpecKind, Value: "Another Heading", LineNo: 4}, 678 } 679 680 _, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary(), "") 681 682 c.Assert(result.Ok, Equals, false) 683 684 c.Assert(result.ParseErrors[0].Message, Equals, "Multiple spec headings found in same file") 685 c.Assert(result.ParseErrors[0].LineNo, Equals, 4) 686 } 687 688 func (s *MySuite) TestThrowsErrorForScenarioWithoutSpecHeading(c *C) { 689 tokens := []*Token{ 690 &Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 1}, 691 &Token{Kind: gauge.StepKind, Value: "Example step", LineNo: 2}, 692 &Token{Kind: gauge.CommentKind, Value: "Comment", LineNo: 3}, 693 } 694 695 _, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary(), "") 696 697 c.Assert(result.Ok, Equals, false) 698 c.Assert(len(result.ParseErrors), Equals, 2) 699 700 c.Assert(result.ParseErrors[0].Message, Equals, "Spec heading not found") 701 c.Assert(result.ParseErrors[0].LineNo, Equals, 1) 702 c.Assert(result.ParseErrors[1].Message, Equals, "Scenario should be defined after the spec heading") 703 c.Assert(result.ParseErrors[1].LineNo, Equals, 1) 704 705 } 706 707 func (s *MySuite) TestThrowsErrorForDuplicateScenariosWithinTheSameSpec(c *C) { 708 tokens := []*Token{ 709 &Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1}, 710 &Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 2}, 711 &Token{Kind: gauge.StepKind, Value: "Example step", LineNo: 3}, 712 &Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 4}, 713 } 714 715 _, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary(), "") 716 717 c.Assert(result.Ok, Equals, false) 718 719 c.Assert(result.ParseErrors[0].Message, Equals, "Duplicate scenario definition 'Scenario Heading' found in the same specification") 720 c.Assert(result.ParseErrors[0].LineNo, Equals, 4) 721 } 722 723 func (s *MySuite) TestSpecWithHeadingAndSimpleSteps(c *C) { 724 tokens := []*Token{ 725 &Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1}, 726 &Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 2}, 727 &Token{Kind: gauge.StepKind, Value: "Example step", LineNo: 3}, 728 } 729 730 spec, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary(), "") 731 732 c.Assert(len(spec.Items), Equals, 1) 733 c.Assert(spec.Items[0], Equals, spec.Scenarios[0]) 734 scenarioItems := (spec.Items[0]).(*gauge.Scenario).Items 735 c.Assert(scenarioItems[0], Equals, spec.Scenarios[0].Steps[0]) 736 737 c.Assert(result.Ok, Equals, true) 738 c.Assert(spec.Heading.LineNo, Equals, 1) 739 c.Assert(spec.Heading.Value, Equals, "Spec Heading") 740 741 c.Assert(len(spec.Scenarios), Equals, 1) 742 c.Assert(spec.Scenarios[0].Heading.LineNo, Equals, 2) 743 c.Assert(spec.Scenarios[0].Heading.Value, Equals, "Scenario Heading") 744 c.Assert(len(spec.Scenarios[0].Steps), Equals, 1) 745 c.Assert(spec.Scenarios[0].Steps[0].Value, Equals, "Example step") 746 } 747 748 func (s *MySuite) TestStepsAndComments(c *C) { 749 tokens := []*Token{ 750 &Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1}, 751 &Token{Kind: gauge.CommentKind, Value: "A comment with some text and **bold** characters", LineNo: 2}, 752 &Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 3}, 753 &Token{Kind: gauge.CommentKind, Value: "Another comment", LineNo: 4}, 754 &Token{Kind: gauge.StepKind, Value: "Example step", LineNo: 5}, 755 &Token{Kind: gauge.CommentKind, Value: "Third comment", LineNo: 6}, 756 } 757 758 spec, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary(), "") 759 c.Assert(len(spec.Items), Equals, 2) 760 c.Assert(spec.Items[0], Equals, spec.Comments[0]) 761 c.Assert(spec.Items[1], Equals, spec.Scenarios[0]) 762 763 scenarioItems := (spec.Items[1]).(*gauge.Scenario).Items 764 c.Assert(3, Equals, len(scenarioItems)) 765 c.Assert(scenarioItems[0], Equals, spec.Scenarios[0].Comments[0]) 766 c.Assert(scenarioItems[1], Equals, spec.Scenarios[0].Steps[0]) 767 c.Assert(scenarioItems[2], Equals, spec.Scenarios[0].Comments[1]) 768 769 c.Assert(result.Ok, Equals, true) 770 c.Assert(spec.Heading.Value, Equals, "Spec Heading") 771 772 c.Assert(len(spec.Comments), Equals, 1) 773 c.Assert(spec.Comments[0].LineNo, Equals, 2) 774 c.Assert(spec.Comments[0].Value, Equals, "A comment with some text and **bold** characters") 775 776 c.Assert(len(spec.Scenarios), Equals, 1) 777 scenario := spec.Scenarios[0] 778 779 c.Assert(2, Equals, len(scenario.Comments)) 780 c.Assert(scenario.Comments[0].LineNo, Equals, 4) 781 c.Assert(scenario.Comments[0].Value, Equals, "Another comment") 782 783 c.Assert(scenario.Comments[1].LineNo, Equals, 6) 784 c.Assert(scenario.Comments[1].Value, Equals, "Third comment") 785 786 c.Assert(scenario.Heading.Value, Equals, "Scenario Heading") 787 c.Assert(len(scenario.Steps), Equals, 1) 788 } 789 790 func (s *MySuite) TestTableFromInvalidFile(c *C) { 791 parser := new(SpecParser) 792 specText := SpecBuilder().specHeading("Spec heading").text("table: inputinvalid.csv").text("comment").scenarioHeading("Sce heading").step("my step").String() 793 794 tokens, _ := parser.GenerateTokens(specText, "") 795 _, res := parser.CreateSpecification(tokens, gauge.NewConceptDictionary(), "") 796 797 c.Assert(len(res.ParseErrors) > 0, Equals, true) 798 c.Assert(res.ParseErrors[0].Message, Equals, "Could not resolve table from table: inputinvalid.csv") 799 } 800 801 func (s *MySuite) TestStepsWithParam(c *C) { 802 tokens := []*Token{ 803 &Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1}, 804 &Token{Kind: gauge.TableHeader, Args: []string{"id"}, LineNo: 2}, 805 &Token{Kind: gauge.TableRow, Args: []string{"1"}, LineNo: 3}, 806 &Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 4}, 807 &Token{Kind: gauge.StepKind, Value: "enter {static} with {dynamic}", LineNo: 5, Args: []string{"user \\n foo", "id"}}, 808 &Token{Kind: gauge.StepKind, Value: "sample \\{static\\}", LineNo: 6}, 809 } 810 811 spec, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary(), "") 812 c.Assert(result.Ok, Equals, true) 813 step := spec.Scenarios[0].Steps[0] 814 c.Assert(step.Value, Equals, "enter {} with {}") 815 c.Assert(step.LineNo, Equals, 5) 816 c.Assert(len(step.Args), Equals, 2) 817 c.Assert(step.Args[0].Value, Equals, "user \\n foo") 818 c.Assert(step.Args[0].ArgType, Equals, gauge.Static) 819 c.Assert(step.Args[1].Value, Equals, "id") 820 c.Assert(step.Args[1].ArgType, Equals, gauge.Dynamic) 821 c.Assert(step.Args[1].Name, Equals, "id") 822 823 escapedStep := spec.Scenarios[0].Steps[1] 824 c.Assert(escapedStep.Value, Equals, "sample \\{static\\}") 825 c.Assert(len(escapedStep.Args), Equals, 0) 826 } 827 828 func (s *MySuite) TestStepsWithKeywords(c *C) { 829 tokens := []*Token{ 830 &Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1}, 831 &Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 2}, 832 &Token{Kind: gauge.StepKind, Value: "sample {static} and {dynamic}", LineNo: 3, Args: []string{"name"}}, 833 } 834 835 _, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary(), "") 836 837 c.Assert(result, NotNil) 838 c.Assert(result.Ok, Equals, false) 839 c.Assert(result.ParseErrors[0].Message, Equals, "Scenario should have atleast one step") 840 c.Assert(result.ParseErrors[0].LineNo, Equals, 2) 841 c.Assert(result.ParseErrors[1].Message, Equals, "Step text should not have '{static}' or '{dynamic}' or '{special}'") 842 c.Assert(result.ParseErrors[1].LineNo, Equals, 3) 843 } 844 845 func (s *MySuite) TestContextWithKeywords(c *C) { 846 tokens := []*Token{ 847 &Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1}, 848 &Token{Kind: gauge.StepKind, Value: "sample {static} and {dynamic}", LineNo: 3, Args: []string{"name"}}, 849 &Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 2}, 850 &Token{Kind: gauge.StepKind, Value: "Step"}, 851 } 852 853 _, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary(), "") 854 855 c.Assert(result, NotNil) 856 c.Assert(result.Ok, Equals, false) 857 c.Assert(result.ParseErrors[0].Message, Equals, "Step text should not have '{static}' or '{dynamic}' or '{special}'") 858 c.Assert(result.ParseErrors[0].LineNo, Equals, 3) 859 } 860 861 func (s *MySuite) TestSpecWithDataTable(c *C) { 862 tokens := []*Token{ 863 &Token{Kind: gauge.SpecKind, Value: "Spec Heading"}, 864 &Token{Kind: gauge.CommentKind, Value: "Comment before data table"}, 865 &Token{Kind: gauge.TableHeader, Args: []string{"id", "name"}}, 866 &Token{Kind: gauge.TableRow, Args: []string{"1", "foo"}}, 867 &Token{Kind: gauge.TableRow, Args: []string{"2", "bar"}}, 868 &Token{Kind: gauge.CommentKind, Value: "Comment before data table"}, 869 &Token{Kind: gauge.ScenarioKind, Value: "Scenario heading"}, 870 &Token{Kind: gauge.StepKind, Value: "my step"}, 871 } 872 873 spec, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary(), "") 874 875 c.Assert(len(spec.Items), Equals, 4) 876 c.Assert(spec.Items[0], Equals, spec.Comments[0]) 877 c.Assert(spec.Items[1], DeepEquals, &spec.DataTable) 878 c.Assert(spec.Items[2], Equals, spec.Comments[1]) 879 880 c.Assert(result.Ok, Equals, true) 881 c.Assert(spec.DataTable, NotNil) 882 c.Assert(len(spec.DataTable.Table.Get("id")), Equals, 2) 883 c.Assert(len(spec.DataTable.Table.Get("name")), Equals, 2) 884 c.Assert(spec.DataTable.Table.Get("id")[0].Value, Equals, "1") 885 c.Assert(spec.DataTable.Table.Get("id")[0].CellType, Equals, gauge.Static) 886 c.Assert(spec.DataTable.Table.Get("id")[1].Value, Equals, "2") 887 c.Assert(spec.DataTable.Table.Get("id")[1].CellType, Equals, gauge.Static) 888 c.Assert(spec.DataTable.Table.Get("name")[0].Value, Equals, "foo") 889 c.Assert(spec.DataTable.Table.Get("name")[0].CellType, Equals, gauge.Static) 890 c.Assert(spec.DataTable.Table.Get("name")[1].Value, Equals, "bar") 891 c.Assert(spec.DataTable.Table.Get("name")[1].CellType, Equals, gauge.Static) 892 } 893 894 func (s *MySuite) TestSpecWithDataTableHavingEmptyRowAndNoSeparator(c *C) { 895 tokens := []*Token{ 896 &Token{Kind: gauge.SpecKind, Value: "Spec Heading"}, 897 &Token{Kind: gauge.CommentKind, Value: "Comment before data table"}, 898 &Token{Kind: gauge.TableHeader, Args: []string{"id", "name"}}, 899 &Token{Kind: gauge.TableRow, Args: []string{"1", "foo"}}, 900 &Token{Kind: gauge.TableRow, Args: []string{"", ""}}, 901 &Token{Kind: gauge.TableRow, Args: []string{"2", "bar"}}, 902 &Token{Kind: gauge.CommentKind, Value: "Comment before data table"}, 903 &Token{Kind: gauge.ScenarioKind, Value: "Scenario heading"}, 904 &Token{Kind: gauge.StepKind, Value: "my step"}, 905 } 906 907 spec, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary(), "") 908 909 c.Assert(len(spec.Items), Equals, 4) 910 c.Assert(spec.Items[0], Equals, spec.Comments[0]) 911 c.Assert(spec.Items[1], DeepEquals, &spec.DataTable) 912 c.Assert(spec.Items[2], Equals, spec.Comments[1]) 913 914 c.Assert(result.Ok, Equals, true) 915 c.Assert(spec.DataTable, NotNil) 916 c.Assert(spec.DataTable.Table.GetRowCount(), Equals, 3) 917 c.Assert(len(spec.DataTable.Table.Get("id")), Equals, 3) 918 c.Assert(len(spec.DataTable.Table.Get("name")), Equals, 3) 919 c.Assert(spec.DataTable.Table.Get("id")[0].Value, Equals, "1") 920 c.Assert(spec.DataTable.Table.Get("id")[0].CellType, Equals, gauge.Static) 921 c.Assert(spec.DataTable.Table.Get("id")[1].Value, Equals, "") 922 c.Assert(spec.DataTable.Table.Get("id")[1].CellType, Equals, gauge.Static) 923 c.Assert(spec.DataTable.Table.Get("id")[2].Value, Equals, "2") 924 c.Assert(spec.DataTable.Table.Get("id")[2].CellType, Equals, gauge.Static) 925 c.Assert(spec.DataTable.Table.Get("name")[0].Value, Equals, "foo") 926 c.Assert(spec.DataTable.Table.Get("name")[0].CellType, Equals, gauge.Static) 927 c.Assert(spec.DataTable.Table.Get("name")[1].Value, Equals, "") 928 c.Assert(spec.DataTable.Table.Get("name")[1].CellType, Equals, gauge.Static) 929 c.Assert(spec.DataTable.Table.Get("name")[2].Value, Equals, "bar") 930 c.Assert(spec.DataTable.Table.Get("name")[2].CellType, Equals, gauge.Static) 931 } 932 933 func (s *MySuite) TestStepWithInlineTable(c *C) { 934 tokens := []*Token{ 935 &Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1}, 936 &Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 2}, 937 &Token{Kind: gauge.StepKind, Value: "Step with inline table", LineNo: 3}, 938 &Token{Kind: gauge.TableHeader, Args: []string{"id", "name"}}, 939 &Token{Kind: gauge.TableRow, Args: []string{"1", "foo"}}, 940 &Token{Kind: gauge.TableRow, Args: []string{"2", "bar"}}, 941 } 942 943 spec, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary(), "") 944 945 c.Assert(result.Ok, Equals, true) 946 step := spec.Scenarios[0].Steps[0] 947 948 c.Assert(step.Args[0].ArgType, Equals, gauge.TableArg) 949 inlineTable := step.Args[0].Table 950 c.Assert(inlineTable, NotNil) 951 952 c.Assert(step.Value, Equals, "Step with inline table {}") 953 c.Assert(step.HasInlineTable, Equals, true) 954 c.Assert(len(inlineTable.Get("id")), Equals, 2) 955 c.Assert(len(inlineTable.Get("name")), Equals, 2) 956 c.Assert(inlineTable.Get("id")[0].Value, Equals, "1") 957 c.Assert(inlineTable.Get("id")[0].CellType, Equals, gauge.Static) 958 c.Assert(inlineTable.Get("id")[1].Value, Equals, "2") 959 c.Assert(inlineTable.Get("id")[1].CellType, Equals, gauge.Static) 960 c.Assert(inlineTable.Get("name")[0].Value, Equals, "foo") 961 c.Assert(inlineTable.Get("name")[0].CellType, Equals, gauge.Static) 962 c.Assert(inlineTable.Get("name")[1].Value, Equals, "bar") 963 c.Assert(inlineTable.Get("name")[1].CellType, Equals, gauge.Static) 964 } 965 966 func (s *MySuite) TestStepWithInlineTableWithDynamicParam(c *C) { 967 tokens := []*Token{ 968 &Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1}, 969 &Token{Kind: gauge.TableHeader, Args: []string{"type1", "type2"}}, 970 &Token{Kind: gauge.TableRow, Args: []string{"1", "2"}}, 971 &Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 2}, 972 &Token{Kind: gauge.StepKind, Value: "Step with inline table", LineNo: 3}, 973 &Token{Kind: gauge.TableHeader, Args: []string{"id", "name"}}, 974 &Token{Kind: gauge.TableRow, Args: []string{"1", "<type1>"}}, 975 &Token{Kind: gauge.TableRow, Args: []string{"2", "<type2>"}}, 976 &Token{Kind: gauge.TableRow, Args: []string{"<2>", "<type3>"}}, 977 } 978 979 spec, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary(), "") 980 981 c.Assert(result.Ok, Equals, true) 982 step := spec.Scenarios[0].Steps[0] 983 984 c.Assert(step.Args[0].ArgType, Equals, gauge.TableArg) 985 inlineTable := step.Args[0].Table 986 c.Assert(inlineTable, NotNil) 987 988 c.Assert(step.Value, Equals, "Step with inline table {}") 989 c.Assert(len(inlineTable.Get("id")), Equals, 3) 990 c.Assert(len(inlineTable.Get("name")), Equals, 3) 991 c.Assert(inlineTable.Get("id")[0].Value, Equals, "1") 992 c.Assert(inlineTable.Get("id")[0].CellType, Equals, gauge.Static) 993 c.Assert(inlineTable.Get("id")[1].Value, Equals, "2") 994 c.Assert(inlineTable.Get("id")[1].CellType, Equals, gauge.Static) 995 c.Assert(inlineTable.Get("id")[2].Value, Equals, "<2>") 996 c.Assert(inlineTable.Get("id")[2].CellType, Equals, gauge.Static) 997 998 c.Assert(inlineTable.Get("name")[0].Value, Equals, "type1") 999 c.Assert(inlineTable.Get("name")[0].CellType, Equals, gauge.Dynamic) 1000 c.Assert(inlineTable.Get("name")[1].Value, Equals, "type2") 1001 c.Assert(inlineTable.Get("name")[1].CellType, Equals, gauge.Dynamic) 1002 c.Assert(inlineTable.Get("name")[2].Value, Equals, "<type3>") 1003 c.Assert(inlineTable.Get("name")[2].CellType, Equals, gauge.Static) 1004 } 1005 1006 func (s *MySuite) TestStepWithInlineTableWithUnResolvableDynamicParam(c *C) { 1007 tokens := []*Token{ 1008 &Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1}, 1009 &Token{Kind: gauge.TableHeader, Args: []string{"type1", "type2"}}, 1010 &Token{Kind: gauge.TableRow, Args: []string{"1", "2"}}, 1011 &Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 2}, 1012 &Token{Kind: gauge.StepKind, Value: "Step with inline table", LineNo: 3}, 1013 &Token{Kind: gauge.TableHeader, Args: []string{"id", "name"}}, 1014 &Token{Kind: gauge.TableRow, Args: []string{"1", "<invalid>"}}, 1015 &Token{Kind: gauge.TableRow, Args: []string{"2", "<type2>"}}, 1016 } 1017 1018 spec, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary(), "") 1019 c.Assert(result.Ok, Equals, true) 1020 c.Assert(spec.Scenarios[0].Steps[0].Args[0].Table.Get("id")[0].Value, Equals, "1") 1021 c.Assert(spec.Scenarios[0].Steps[0].Args[0].Table.Get("name")[0].Value, Equals, "<invalid>") 1022 c.Assert(result.Warnings[0].Message, Equals, "Dynamic param <invalid> could not be resolved, Treating it as static param") 1023 } 1024 1025 func (s *MySuite) TestContextWithInlineTable(c *C) { 1026 tokens := []*Token{ 1027 &Token{Kind: gauge.SpecKind, Value: "Spec Heading"}, 1028 &Token{Kind: gauge.StepKind, Value: "Context with inline table"}, 1029 &Token{Kind: gauge.TableHeader, Args: []string{"id", "name"}}, 1030 &Token{Kind: gauge.TableRow, Args: []string{"1", "foo"}}, 1031 &Token{Kind: gauge.TableRow, Args: []string{"2", "bar"}}, 1032 &Token{Kind: gauge.TableRow, Args: []string{"3", "not a <dynamic>"}}, 1033 &Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading"}, 1034 &Token{Kind: gauge.StepKind, Value: "Step"}, 1035 } 1036 1037 spec, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary(), "") 1038 c.Assert(len(spec.Items), Equals, 2) 1039 c.Assert(spec.Items[0], DeepEquals, spec.Contexts[0]) 1040 c.Assert(spec.Items[1], Equals, spec.Scenarios[0]) 1041 1042 c.Assert(result.Ok, Equals, true) 1043 context := spec.Contexts[0] 1044 1045 c.Assert(context.Args[0].ArgType, Equals, gauge.TableArg) 1046 inlineTable := context.Args[0].Table 1047 1048 c.Assert(inlineTable, NotNil) 1049 c.Assert(context.Value, Equals, "Context with inline table {}") 1050 c.Assert(len(inlineTable.Get("id")), Equals, 3) 1051 c.Assert(len(inlineTable.Get("name")), Equals, 3) 1052 c.Assert(inlineTable.Get("id")[0].Value, Equals, "1") 1053 c.Assert(inlineTable.Get("id")[0].CellType, Equals, gauge.Static) 1054 c.Assert(inlineTable.Get("id")[1].Value, Equals, "2") 1055 c.Assert(inlineTable.Get("id")[1].CellType, Equals, gauge.Static) 1056 c.Assert(inlineTable.Get("id")[2].Value, Equals, "3") 1057 c.Assert(inlineTable.Get("id")[2].CellType, Equals, gauge.Static) 1058 c.Assert(inlineTable.Get("name")[0].Value, Equals, "foo") 1059 c.Assert(inlineTable.Get("name")[0].CellType, Equals, gauge.Static) 1060 c.Assert(inlineTable.Get("name")[1].Value, Equals, "bar") 1061 c.Assert(inlineTable.Get("name")[1].CellType, Equals, gauge.Static) 1062 c.Assert(inlineTable.Get("name")[2].Value, Equals, "not a <dynamic>") 1063 c.Assert(inlineTable.Get("name")[2].CellType, Equals, gauge.Static) 1064 } 1065 1066 func (s *MySuite) TestErrorWhenDataTableHasOnlyHeader(c *C) { 1067 tokens := []*Token{ 1068 &Token{Kind: gauge.SpecKind, Value: "Spec Heading"}, 1069 &Token{Kind: gauge.TableHeader, Args: []string{"id", "name"}, LineNo: 3}, 1070 &Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading"}, 1071 } 1072 1073 _, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary(), "") 1074 1075 c.Assert(result.Ok, Equals, false) 1076 c.Assert(result.ParseErrors[0].Message, Equals, "Data table should have at least 1 data row") 1077 c.Assert(result.ParseErrors[0].LineNo, Equals, 3) 1078 } 1079 1080 func (s *MySuite) TestWarningWhenParsingMultipleDataTable(c *C) { 1081 tokens := []*Token{ 1082 &Token{Kind: gauge.SpecKind, Value: "Spec Heading"}, 1083 &Token{Kind: gauge.CommentKind, Value: "Comment before data table"}, 1084 &Token{Kind: gauge.TableHeader, Args: []string{"id", "name"}}, 1085 &Token{Kind: gauge.TableRow, Args: []string{"1", "foo"}}, 1086 &Token{Kind: gauge.TableRow, Args: []string{"2", "bar"}}, 1087 &Token{Kind: gauge.CommentKind, Value: "Comment before data table"}, 1088 &Token{Kind: gauge.TableHeader, Args: []string{"phone"}, LineNo: 7}, 1089 &Token{Kind: gauge.TableRow, Args: []string{"1"}}, 1090 &Token{Kind: gauge.TableRow, Args: []string{"2"}}, 1091 &Token{Kind: gauge.ScenarioKind, Value: "Scenario heading"}, 1092 &Token{Kind: gauge.StepKind, Value: "my step"}, 1093 } 1094 1095 _, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary(), "foo.spec") 1096 1097 c.Assert(result.Ok, Equals, true) 1098 c.Assert(len(result.Warnings), Equals, 1) 1099 c.Assert(result.Warnings[0].String(), Equals, "foo.spec:7 Multiple data table present, ignoring table") 1100 1101 } 1102 1103 func (s *MySuite) TestParseErrorWhenCouldNotResolveExternalDataTable(c *C) { 1104 tokens := []*Token{ 1105 &Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1}, 1106 &Token{Kind: gauge.CommentKind, Value: "Comment before data table", LineNo: 2}, 1107 &Token{Kind: gauge.DataTableKind, Value: "table: foo", LineNo: 3, LineText: "table: foo"}, 1108 &Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 4}, 1109 &Token{Kind: gauge.StepKind, Value: "Step", LineNo: 5}, 1110 } 1111 1112 _, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary(), "foo.spec") 1113 1114 c.Assert(result.Ok, Equals, false) 1115 c.Assert(len(result.Warnings), Equals, 0) 1116 c.Assert(result.Errors()[0], Equals, "[ParseError] foo.spec:3 Could not resolve table from table: foo => 'table: foo'") 1117 1118 } 1119 1120 func (s *MySuite) TestWarningWhenParsingTableOccursWithoutStep(c *C) { 1121 tokens := []*Token{ 1122 &Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1}, 1123 &Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 2}, 1124 &Token{Kind: gauge.TableHeader, Args: []string{"id", "name"}, LineNo: 3}, 1125 &Token{Kind: gauge.TableRow, Args: []string{"1", "foo"}, LineNo: 4}, 1126 &Token{Kind: gauge.TableRow, Args: []string{"2", "bar"}, LineNo: 5}, 1127 &Token{Kind: gauge.StepKind, Value: "Step", LineNo: 6}, 1128 &Token{Kind: gauge.CommentKind, Value: "comment in between", LineNo: 7}, 1129 &Token{Kind: gauge.TableHeader, Args: []string{"phone"}, LineNo: 8}, 1130 &Token{Kind: gauge.TableRow, Args: []string{"1"}}, 1131 &Token{Kind: gauge.TableRow, Args: []string{"2"}}, 1132 } 1133 1134 _, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary(), "foo.spec") 1135 c.Assert(result.Ok, Equals, true) 1136 c.Assert(len(result.Warnings), Equals, 2) 1137 c.Assert(result.Warnings[0].String(), Equals, "foo.spec:3 Table not associated with a step, ignoring table") 1138 c.Assert(result.Warnings[1].String(), Equals, "foo.spec:8 Table not associated with a step, ignoring table") 1139 1140 } 1141 1142 func (s *MySuite) TestAddSpecTags(c *C) { 1143 tokens := []*Token{ 1144 &Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1}, 1145 &Token{Kind: gauge.TagKind, Args: []string{"tag1", "tag2"}, LineNo: 2}, 1146 &Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 3}, 1147 &Token{Kind: gauge.StepKind, Value: "Step"}, 1148 } 1149 1150 spec, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary(), "") 1151 1152 c.Assert(result.Ok, Equals, true) 1153 c.Assert(len(spec.Tags.Values()), Equals, 2) 1154 c.Assert(spec.Tags.Values()[0], Equals, "tag1") 1155 c.Assert(spec.Tags.Values()[1], Equals, "tag2") 1156 } 1157 1158 func (s *MySuite) TestAddSpecTagsAndScenarioTags(c *C) { 1159 tokens := []*Token{ 1160 &Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1}, 1161 &Token{Kind: gauge.TagKind, Args: []string{"tag1", "tag2"}, LineNo: 2}, 1162 &Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 3}, 1163 &Token{Kind: gauge.TagKind, Args: []string{"tag3", "tag4"}, LineNo: 2}, 1164 &Token{Kind: gauge.StepKind, Value: "Step"}, 1165 } 1166 1167 spec, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary(), "") 1168 1169 c.Assert(result.Ok, Equals, true) 1170 1171 c.Assert(len(spec.Tags.Values()), Equals, 2) 1172 c.Assert(spec.Tags.Values()[0], Equals, "tag1") 1173 c.Assert(spec.Tags.Values()[1], Equals, "tag2") 1174 1175 tags := spec.Scenarios[0].Tags 1176 c.Assert(len(tags.Values()), Equals, 2) 1177 c.Assert(tags.Values()[0], Equals, "tag3") 1178 c.Assert(tags.Values()[1], Equals, "tag4") 1179 } 1180 1181 func (s *MySuite) TestErrorOnAddingDynamicParamterWithoutADataTable(c *C) { 1182 tokens := []*Token{ 1183 &Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1}, 1184 &Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 2}, 1185 &Token{Kind: gauge.StepKind, Value: "Step with a {dynamic}", Args: []string{"foo"}, LineNo: 3, LineText: "*Step with a <foo>"}, 1186 &Token{Kind: gauge.StepKind, Value: "Step"}, 1187 } 1188 1189 _, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary(), "") 1190 1191 c.Assert(result.Ok, Equals, false) 1192 c.Assert(result.ParseErrors[0].Message, Equals, "Dynamic parameter <foo> could not be resolved") 1193 c.Assert(result.ParseErrors[0].LineNo, Equals, 3) 1194 1195 } 1196 1197 func (s *MySuite) TestErrorOnAddingDynamicParamterWithoutDataTableHeaderValue(c *C) { 1198 tokens := []*Token{ 1199 &Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1}, 1200 &Token{Kind: gauge.TableHeader, Args: []string{"id, name"}, LineNo: 2}, 1201 &Token{Kind: gauge.TableRow, Args: []string{"123, hello"}, LineNo: 3}, 1202 &Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 4}, 1203 &Token{Kind: gauge.StepKind, Value: "Step with a {dynamic}", Args: []string{"foo"}, LineNo: 5, LineText: "*Step with a <foo>"}, 1204 &Token{Kind: gauge.StepKind, Value: "Step"}, 1205 } 1206 1207 _, result := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary(), "") 1208 1209 c.Assert(result.Ok, Equals, false) 1210 c.Assert(result.ParseErrors[0].Message, Equals, "Dynamic parameter <foo> could not be resolved") 1211 c.Assert(result.ParseErrors[0].LineNo, Equals, 5) 1212 1213 } 1214 1215 func (s *MySuite) TestCreateStepFromSimpleConcept(c *C) { 1216 tokens := []*Token{ 1217 &Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1}, 1218 &Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 2}, 1219 &Token{Kind: gauge.StepKind, Value: "test concept step 1", LineNo: 3}, 1220 } 1221 1222 conceptDictionary := gauge.NewConceptDictionary() 1223 path, _ := filepath.Abs(filepath.Join("testdata", "concept.cpt")) 1224 AddConcepts([]string{path}, conceptDictionary) 1225 spec, result := new(SpecParser).CreateSpecification(tokens, conceptDictionary, "") 1226 c.Assert(result.Ok, Equals, true) 1227 1228 c.Assert(len(spec.Scenarios[0].Steps), Equals, 1) 1229 specConceptStep := spec.Scenarios[0].Steps[0] 1230 c.Assert(specConceptStep.IsConcept, Equals, true) 1231 assertStepEqual(c, &gauge.Step{LineNo: 2, Value: "step 1", LineText: "step 1"}, specConceptStep.ConceptSteps[0]) 1232 } 1233 1234 func (s *MySuite) TestCreateStepFromConceptWithParameters(c *C) { 1235 tokens := []*Token{ 1236 &Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1}, 1237 &Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 2}, 1238 &Token{Kind: gauge.StepKind, Value: "assign id {static} and name {static}", Args: []string{"foo", "foo1"}, LineNo: 3}, 1239 &Token{Kind: gauge.StepKind, Value: "assign id {static} and name {static}", Args: []string{"bar", "bar1"}, LineNo: 4}, 1240 } 1241 1242 conceptDictionary := gauge.NewConceptDictionary() 1243 path, _ := filepath.Abs(filepath.Join("testdata", "dynamic_param_concept.cpt")) 1244 AddConcepts([]string{path}, conceptDictionary) 1245 1246 spec, result := new(SpecParser).CreateSpecification(tokens, conceptDictionary, "") 1247 c.Assert(result.Ok, Equals, true) 1248 1249 c.Assert(len(spec.Scenarios[0].Steps), Equals, 2) 1250 1251 firstConceptStep := spec.Scenarios[0].Steps[0] 1252 c.Assert(firstConceptStep.IsConcept, Equals, true) 1253 c.Assert(firstConceptStep.ConceptSteps[0].Value, Equals, "add id {}") 1254 c.Assert(firstConceptStep.ConceptSteps[0].Args[0].Value, Equals, "userid") 1255 c.Assert(firstConceptStep.ConceptSteps[1].Value, Equals, "add name {}") 1256 c.Assert(firstConceptStep.ConceptSteps[1].Args[0].Value, Equals, "username") 1257 c.Assert(firstConceptStep.GetArg("username").Value, Equals, "foo1") 1258 c.Assert(firstConceptStep.GetArg("userid").Value, Equals, "foo") 1259 1260 secondConceptStep := spec.Scenarios[0].Steps[1] 1261 c.Assert(secondConceptStep.IsConcept, Equals, true) 1262 c.Assert(secondConceptStep.ConceptSteps[0].Value, Equals, "add id {}") 1263 c.Assert(secondConceptStep.ConceptSteps[0].Args[0].Value, Equals, "userid") 1264 c.Assert(secondConceptStep.ConceptSteps[1].Value, Equals, "add name {}") 1265 c.Assert(secondConceptStep.ConceptSteps[1].Args[0].Value, Equals, "username") 1266 c.Assert(secondConceptStep.GetArg("username").Value, Equals, "bar1") 1267 c.Assert(secondConceptStep.GetArg("userid").Value, Equals, "bar") 1268 1269 } 1270 1271 func (s *MySuite) TestCreateStepFromConceptWithDynamicParameters(c *C) { 1272 tokens := []*Token{ 1273 &Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1}, 1274 &Token{Kind: gauge.TableHeader, Args: []string{"id", "description"}, LineNo: 2}, 1275 &Token{Kind: gauge.TableRow, Args: []string{"123", "Admin fellow"}, LineNo: 3}, 1276 &Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 4}, 1277 &Token{Kind: gauge.StepKind, Value: "assign id {dynamic} and name {dynamic}", Args: []string{"id", "description"}, LineNo: 5}, 1278 } 1279 1280 conceptDictionary := gauge.NewConceptDictionary() 1281 path, _ := filepath.Abs(filepath.Join("testdata", "dynamic_param_concept.cpt")) 1282 AddConcepts([]string{path}, conceptDictionary) 1283 spec, result := new(SpecParser).CreateSpecification(tokens, conceptDictionary, "") 1284 c.Assert(result.Ok, Equals, true) 1285 1286 c.Assert(len(spec.Items), Equals, 2) 1287 c.Assert(spec.Items[0], DeepEquals, &spec.DataTable) 1288 c.Assert(spec.Items[1], Equals, spec.Scenarios[0]) 1289 1290 scenarioItems := (spec.Items[1]).(*gauge.Scenario).Items 1291 c.Assert(scenarioItems[0], Equals, spec.Scenarios[0].Steps[0]) 1292 1293 c.Assert(len(spec.Scenarios[0].Steps), Equals, 1) 1294 1295 firstConcept := spec.Scenarios[0].Steps[0] 1296 c.Assert(firstConcept.IsConcept, Equals, true) 1297 c.Assert(firstConcept.ConceptSteps[0].Value, Equals, "add id {}") 1298 c.Assert(firstConcept.ConceptSteps[0].Args[0].ArgType, Equals, gauge.Dynamic) 1299 c.Assert(firstConcept.ConceptSteps[0].Args[0].Value, Equals, "userid") 1300 c.Assert(firstConcept.ConceptSteps[1].Value, Equals, "add name {}") 1301 c.Assert(firstConcept.ConceptSteps[1].Args[0].Value, Equals, "username") 1302 c.Assert(firstConcept.ConceptSteps[1].Args[0].ArgType, Equals, gauge.Dynamic) 1303 1304 arg1 := firstConcept.Lookup.GetArg("userid") 1305 c.Assert(arg1.Value, Equals, "id") 1306 c.Assert(arg1.ArgType, Equals, gauge.Dynamic) 1307 1308 arg2 := firstConcept.Lookup.GetArg("username") 1309 c.Assert(arg2.Value, Equals, "description") 1310 c.Assert(arg2.ArgType, Equals, gauge.Dynamic) 1311 } 1312 1313 func (s *MySuite) TestCreateStepFromConceptWithInlineTable(c *C) { 1314 tokens := []*Token{ 1315 &Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1}, 1316 &Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 4}, 1317 &Token{Kind: gauge.StepKind, Value: "assign id {static} and name", Args: []string{"sdf"}, LineNo: 3}, 1318 &Token{Kind: gauge.TableHeader, Args: []string{"id", "description"}, LineNo: 4}, 1319 &Token{Kind: gauge.TableRow, Args: []string{"123", "Admin"}, LineNo: 5}, 1320 &Token{Kind: gauge.TableRow, Args: []string{"456", "normal fellow"}, LineNo: 6}, 1321 } 1322 1323 conceptDictionary := gauge.NewConceptDictionary() 1324 path, _ := filepath.Abs(filepath.Join("testdata", "dynamic_param_concept.cpt")) 1325 AddConcepts([]string{path}, conceptDictionary) 1326 spec, result := new(SpecParser).CreateSpecification(tokens, conceptDictionary, "") 1327 c.Assert(result.Ok, Equals, true) 1328 1329 steps := spec.Scenarios[0].Steps 1330 c.Assert(len(steps), Equals, 1) 1331 c.Assert(steps[0].IsConcept, Equals, true) 1332 c.Assert(steps[0].Value, Equals, "assign id {} and name {}") 1333 c.Assert(len(steps[0].Args), Equals, 2) 1334 c.Assert(steps[0].Args[1].ArgType, Equals, gauge.TableArg) 1335 c.Assert(len(steps[0].ConceptSteps), Equals, 2) 1336 } 1337 1338 func (s *MySuite) TestCreateStepFromConceptWithInlineTableHavingDynamicParam(c *C) { 1339 tokens := []*Token{ 1340 &Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1}, 1341 &Token{Kind: gauge.TableHeader, Args: []string{"id", "description"}, LineNo: 2}, 1342 &Token{Kind: gauge.TableRow, Args: []string{"123", "Admin"}, LineNo: 3}, 1343 &Token{Kind: gauge.TableRow, Args: []string{"456", "normal fellow"}, LineNo: 4}, 1344 &Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 5}, 1345 &Token{Kind: gauge.StepKind, Value: "assign id {static} and name", Args: []string{"sdf"}, LineNo: 6}, 1346 &Token{Kind: gauge.TableHeader, Args: []string{"user-id", "description", "name"}, LineNo: 7}, 1347 &Token{Kind: gauge.TableRow, Args: []string{"<id>", "<description>", "root"}, LineNo: 8}, 1348 } 1349 1350 conceptDictionary := gauge.NewConceptDictionary() 1351 path, _ := filepath.Abs(filepath.Join("testdata", "dynamic_param_concept.cpt")) 1352 AddConcepts([]string{path}, conceptDictionary) 1353 spec, result := new(SpecParser).CreateSpecification(tokens, conceptDictionary, "") 1354 c.Assert(result.Ok, Equals, true) 1355 1356 steps := spec.Scenarios[0].Steps 1357 c.Assert(len(steps), Equals, 1) 1358 c.Assert(steps[0].IsConcept, Equals, true) 1359 c.Assert(steps[0].Value, Equals, "assign id {} and name {}") 1360 c.Assert(len(steps[0].Args), Equals, 2) 1361 c.Assert(steps[0].Args[1].ArgType, Equals, gauge.TableArg) 1362 table := steps[0].Args[1].Table 1363 c.Assert(table.Get("user-id")[0].Value, Equals, "id") 1364 c.Assert(table.Get("user-id")[0].CellType, Equals, gauge.Dynamic) 1365 c.Assert(table.Get("description")[0].Value, Equals, "description") 1366 c.Assert(table.Get("description")[0].CellType, Equals, gauge.Dynamic) 1367 c.Assert(table.Get("name")[0].Value, Equals, "root") 1368 c.Assert(table.Get("name")[0].CellType, Equals, gauge.Static) 1369 c.Assert(len(steps[0].ConceptSteps), Equals, 2) 1370 } 1371 1372 func (s *MySuite) TestCreateInValidSpecialArgInStep(c *C) { 1373 tokens := []*Token{ 1374 &Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1}, 1375 &Token{Kind: gauge.TableHeader, Args: []string{"unknown:foo", "description"}, LineNo: 2}, 1376 &Token{Kind: gauge.TableRow, Args: []string{"123", "Admin"}, LineNo: 3}, 1377 &Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 2}, 1378 &Token{Kind: gauge.StepKind, Value: "Example {special} step", LineNo: 3, Args: []string{"unknown:foo"}}, 1379 } 1380 spec, parseResults := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary(), "") 1381 c.Assert(spec.Scenarios[0].Steps[0].Args[0].ArgType, Equals, gauge.Dynamic) 1382 c.Assert(len(parseResults.Warnings), Equals, 1) 1383 c.Assert(parseResults.Warnings[0].Message, Equals, "Could not resolve special param type <unknown:foo>. Treating it as dynamic param.") 1384 } 1385 1386 func (s *MySuite) TestTearDownSteps(c *C) { 1387 tokens := []*Token{ 1388 &Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1}, 1389 &Token{Kind: gauge.CommentKind, Value: "A comment with some text and **bold** characters", LineNo: 2}, 1390 &Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 3}, 1391 &Token{Kind: gauge.CommentKind, Value: "Another comment", LineNo: 4}, 1392 &Token{Kind: gauge.StepKind, Value: "Example step", LineNo: 5}, 1393 &Token{Kind: gauge.CommentKind, Value: "Third comment", LineNo: 6}, 1394 &Token{Kind: gauge.TearDownKind, Value: "____", LineNo: 7}, 1395 &Token{Kind: gauge.StepKind, Value: "Example step1", LineNo: 8}, 1396 &Token{Kind: gauge.CommentKind, Value: "Fourth comment", LineNo: 9}, 1397 &Token{Kind: gauge.StepKind, Value: "Example step2", LineNo: 10}, 1398 } 1399 1400 spec, _ := new(SpecParser).CreateSpecification(tokens, gauge.NewConceptDictionary(), "") 1401 c.Assert(len(spec.TearDownSteps), Equals, 2) 1402 c.Assert(spec.TearDownSteps[0].Value, Equals, "Example step1") 1403 c.Assert(spec.TearDownSteps[0].LineNo, Equals, 8) 1404 c.Assert(spec.TearDownSteps[1].Value, Equals, "Example step2") 1405 c.Assert(spec.TearDownSteps[1].LineNo, Equals, 10) 1406 } 1407 1408 func (s *MySuite) TestParsingOfTableWithHyphens(c *C) { 1409 p := new(SpecParser) 1410 1411 text := SpecBuilder().specHeading("My Spec Heading").text("|id|").text("|--|").text("|1 |").text("|- |").String() 1412 tokens, _ := p.GenerateTokens(text, "") 1413 1414 spec, _ := p.CreateSpecification(tokens, gauge.NewConceptDictionary(), "") 1415 c.Assert((len(spec.DataTable.Table.Get("id"))), Equals, 2) 1416 c.Assert(spec.DataTable.Table.Get("id")[0].Value, Equals, "1") 1417 c.Assert(spec.DataTable.Table.Get("id")[1].Value, Equals, "-") 1418 } 1419 1420 func (s *MySuite) TestCreateStepWithNewlineBetweenTextAndTable(c *C) { 1421 tokens := []*Token{ 1422 &Token{Kind: gauge.SpecKind, Value: "Spec Heading", LineNo: 1}, 1423 &Token{Kind: gauge.ScenarioKind, Value: "Scenario Heading", LineNo: 2}, 1424 &Token{Kind: gauge.StepKind, Value: "some random step\n", LineNo: 3}, 1425 &Token{Kind: gauge.TableHeader, Args: []string{"id", "description"}, LineNo: 5}, 1426 &Token{Kind: gauge.TableRow, Args: []string{"123", "Admin"}, LineNo: 6}, 1427 &Token{Kind: gauge.TableRow, Args: []string{"456", "normal fellow"}, LineNo: 7}, 1428 } 1429 1430 conceptDictionary := gauge.NewConceptDictionary() 1431 spec, _ := new(SpecParser).CreateSpecification(tokens, conceptDictionary, "") 1432 1433 c.Assert(spec.Scenarios[0].Steps[0].HasInlineTable, Equals, true) 1434 } 1435 1436 func (s *MySuite) TestSpecParsingWhenSpecHeadingIsNotPresentAndDynamicParseError(c *C) { 1437 p := new(SpecParser) 1438 1439 _, res := p.Parse(`# 1440 Scenario Heading 1441 ---------------- 1442 * def <a> 1443 `, gauge.NewConceptDictionary(), "foo.spec") 1444 1445 c.Assert(len(res.ParseErrors), Equals, 2) 1446 c.Assert(res.ParseErrors[0].Error(), Equals, "foo.spec:1 Spec heading should have at least one character => ''") 1447 c.Assert(res.ParseErrors[1].Error(), Equals, "foo.spec:4 Dynamic parameter <a> could not be resolved => 'def <a>'") 1448 } 1449 1450 func (s *MySuite) TestSpecParsingWhenSpecHeadingIsNotPresent(c *C) { 1451 p := new(SpecParser) 1452 1453 _, res := p.Parse(`# 1454 Scenario Heading 1455 ---------------- 1456 * def "sad" 1457 `, gauge.NewConceptDictionary(), "foo.spec") 1458 1459 c.Assert(len(res.ParseErrors), Equals, 1) 1460 c.Assert(res.ParseErrors[0].Error(), Equals, "foo.spec:1 Spec heading should have at least one character => ''") 1461 } 1462 1463 func (s *MySuite) TestSpecParsingWhenUnderlinedSpecHeadingIsNotPresent(c *C) { 1464 p := new(SpecParser) 1465 1466 _, res := p.Parse(`====== 1467 Scenario Heading 1468 ---------------- 1469 * def "sd" 1470 `, gauge.NewConceptDictionary(), "foo.spec") 1471 1472 c.Assert(len(res.ParseErrors), Equals, 2) 1473 c.Assert(res.ParseErrors[0].Error(), Equals, "foo.spec:1 Spec heading not found => ''") 1474 c.Assert(res.ParseErrors[1].Error(), Equals, "foo.spec:2 Scenario should be defined after the spec heading => 'Scenario Heading'") 1475 } 1476 1477 func (s *MySuite) TestProcessingTokensGivesErrorWhenSpecHeadingHasOnlySpaces(c *C) { 1478 p := new(SpecParser) 1479 1480 _, res := p.Parse("#"+" "+` 1481 Scenario Heading 1482 ---------------- 1483 * def "sd" 1484 `, gauge.NewConceptDictionary(), "foo.spec") 1485 1486 c.Assert(len(res.ParseErrors), Equals, 1) 1487 c.Assert(res.ParseErrors[0].Error(), Equals, "foo.spec:1 Spec heading should have at least one character => ''") 1488 } 1489 1490 func (s *MySuite) TestProcessingTokensGivesErrorWhenScenarioHeadingIsEmpty(c *C) { 1491 p := new(SpecParser) 1492 1493 _, res := p.Parse(`# dfgdfg 1494 ## 1495 * def "sd" 1496 `, gauge.NewConceptDictionary(), "foo.spec") 1497 1498 c.Assert(len(res.ParseErrors), Equals, 1) 1499 c.Assert(res.ParseErrors[0].Error(), Equals, "foo.spec:2 Scenario heading should have at least one character => ''") 1500 } 1501 1502 func (s *MySuite) TestProcessingTokensGivesErrorWhenScenarioHeadingHasOnlySpaces(c *C) { 1503 p := new(SpecParser) 1504 1505 _, res := p.Parse(`# dfgs 1506 ##`+" "+` 1507 * def "sd" 1508 `, gauge.NewConceptDictionary(), "foo.spec") 1509 1510 c.Assert(len(res.ParseErrors), Equals, 1) 1511 c.Assert(res.ParseErrors[0].Error(), Equals, "foo.spec:2 Scenario heading should have at least one character => ''") 1512 } 1513 1514 func (s *MySuite) TestScenarioProcessingToHaveScenarioSpan(c *C) { 1515 p := new(SpecParser) 1516 1517 spec, _ := p.Parse(`# Spec 1 1518 ## Scenario 1 1519 * def "sd" 1520 comment1 1521 * def "sd" 1522 1523 1524 ## Scenario 2 1525 * def "sd" 1526 comment2 1527 * def "sd" 1528 1529 1530 ## Scenario 3 1531 * def "sd" 1532 comment3 1533 * def "sd" 1534 `, gauge.NewConceptDictionary(), "") 1535 1536 c.Assert(len(spec.Scenarios), Equals, 3) 1537 c.Assert(spec.Scenarios[0].Span.Start, Equals, 2) 1538 c.Assert(spec.Scenarios[0].Span.End, Equals, 7) 1539 c.Assert(spec.Scenarios[1].Span.Start, Equals, 8) 1540 c.Assert(spec.Scenarios[1].Span.End, Equals, 13) 1541 c.Assert(spec.Scenarios[2].Span.Start, Equals, 14) 1542 c.Assert(spec.Scenarios[2].Span.End, Equals, 17) 1543 } 1544 1545 func (s *MySuite) TestParsingWhenTearDownHAsOnlyTable(c *C) { 1546 p := new(SpecParser) 1547 1548 spec, _ := p.Parse(`Specification Heading 1549 ===================== 1550 * Vowels in English language are "aeiou". 1551 Vowel counts in single word 1552 --------------------------- 1553 * The word "gauge" has "3" vowels. 1554 ___ 1555 |Word |Vowel Count| 1556 |------|-----------| 1557 |Gauge |3 | 1558 |Mingle|2 | 1559 |Snap |1 | 1560 |GoCD |1 | 1561 |Rhythm|0 | 1562 1563 `, gauge.NewConceptDictionary(), "") 1564 1565 c.Assert(len(spec.TearDownSteps), Equals, 0) 1566 c.Assert(len(spec.Comments), Equals, 7) 1567 } 1568 1569 func (s *MySuite) TestSpecWithRepeatedTagDefinitions(c *C) { 1570 p := new(SpecParser) 1571 spec, parseRes := p.Parse(`Spec Heading 1572 ============== 1573 tags: foo, bar 1574 1575 * step 1576 tags: blah 1577 1578 Scenario 1579 -------- 1580 * step 1581 `, gauge.NewConceptDictionary(), "") 1582 c.Assert(len(parseRes.ParseErrors), Equals, 1) 1583 c.Assert(parseRes.ParseErrors[0].Message, Equals, "Tags can be defined only once per specification") 1584 c.Assert(len(spec.Tags.Values()), Equals, 2) 1585 c.Assert(spec.Tags.Values()[0], Equals, "foo") 1586 c.Assert(spec.Tags.Values()[1], Equals, "bar") 1587 } 1588 1589 func (s *MySuite) TestScenarioWithRepeatedTagDefinitions(c *C) { 1590 p := new(SpecParser) 1591 spec, parseRes := p.Parse(`Spec Heading 1592 ============== 1593 tags: tag1 1594 1595 * step 1596 1597 Scenario 1598 -------- 1599 tags: foo, bar 1600 * step 1601 tags: blah 1602 `, gauge.NewConceptDictionary(), "") 1603 c.Assert(len(parseRes.ParseErrors), Equals, 1) 1604 c.Assert(parseRes.ParseErrors[0].Message, Equals, "Tags can be defined only once per scenario") 1605 c.Assert(len(spec.Scenarios[0].Tags.Values()), Equals, 2) 1606 c.Assert(spec.Scenarios[0].Tags.Values()[0], Equals, "foo") 1607 c.Assert(spec.Scenarios[0].Tags.Values()[1], Equals, "bar") 1608 c.Assert(len(spec.Tags.Values()), Equals, 1) 1609 c.Assert(spec.Tags.Values()[0], Equals, "tag1") 1610 } 1611 1612 func (s *MySuite) TestDatatTableWithEmptyHeaders(c *C) { 1613 p := new(SpecParser) 1614 _, parseRes := p.Parse(`Something 1615 ========= 1616 1617 ||a|||a| 1618 |-------| 1619 |dsf|dsf|dsf|dsf|dsf| 1620 1621 Scenario Heading 1622 ---------------- 1623 * Vowels in English language are "aeiou". 1624 `, gauge.NewConceptDictionary(), "") 1625 1626 c.Assert(len(parseRes.ParseErrors), Equals, 4) 1627 c.Assert(parseRes.ParseErrors[0].Message, Equals, "Table header should not be blank") 1628 c.Assert(parseRes.ParseErrors[1].Message, Equals, "Table header should not be blank") 1629 c.Assert(parseRes.ParseErrors[2].Message, Equals, "Table header should not be blank") 1630 c.Assert(parseRes.ParseErrors[3].Message, Equals, "Table header cannot have repeated column values") 1631 } 1632 1633 func (s *MySuite) TestExtractStepArgsFromToken(c *C) { 1634 token := &Token{Kind: gauge.StepKind, LineText: `my step with "Static" and <Dynamic> params`, Value: `my step with {static} and {dynamic} params`, Args: []string{"Static", "Dynamic"}} 1635 1636 args, err := ExtractStepArgsFromToken(token) 1637 if err != nil { 1638 c.Fatalf("Error while extracting step args : %s", err.Error()) 1639 } 1640 c.Assert(len(args), Equals, 2) 1641 c.Assert(args[0].Value, Equals, "Static") 1642 c.Assert(args[0].ArgType, Equals, gauge.Static) 1643 c.Assert(args[1].Value, Equals, "Dynamic") 1644 c.Assert(args[1].ArgType, Equals, gauge.Dynamic) 1645 }