github.com/getgauge/gauge@v1.6.9/api/infoGatherer/specDetails_test.go (about) 1 /*---------------------------------------------------------------- 2 * Copyright (c) ThoughtWorks, Inc. 3 * Licensed under the Apache License, Version 2.0 4 * See LICENSE in the project root for license information. 5 *----------------------------------------------------------------*/ 6 7 package infoGatherer 8 9 import ( 10 "fmt" 11 "os" 12 "path/filepath" 13 "testing" 14 15 "github.com/getgauge/gauge/config" 16 "github.com/getgauge/gauge/gauge" 17 "github.com/getgauge/gauge/util" 18 . "gopkg.in/check.v1" 19 ) 20 21 func Test(t *testing.T) { TestingT(t) } 22 23 const specDir = "specs" 24 25 var _ = Suite(&MySuite{}) 26 27 var concept1 []byte 28 var concept2 []byte 29 var concept3 []byte 30 var concept4 []byte 31 var spec1 []byte 32 var spec2 []byte 33 var spec3 []byte 34 var specWithTags []byte 35 var spec2WithTags []byte 36 var specWithConcept []byte 37 38 type MySuite struct { 39 specsDir string 40 projectDir string 41 } 42 43 func (s *MySuite) SetUpTest(c *C) { 44 s.projectDir, _ = os.MkdirTemp("_testdata", "gaugeTest") 45 s.specsDir, _ = createDirIn(s.projectDir, specDir) 46 config.ProjectRoot = s.projectDir 47 48 s.buildTestData() 49 } 50 51 func (s *MySuite) TearDownTest(c *C) { 52 os.RemoveAll(s.projectDir) 53 } 54 55 func (s *MySuite) buildTestData() { 56 concept1 = make([]byte, 0) 57 concept1 = append(concept1, `# foo bar 58 * first step with "foo" 59 * say "hello" to me 60 * a "final" step 61 `...) 62 63 concept2 = make([]byte, 0) 64 concept2 = append(concept2, `# bar 65 * first step with "foo" 66 * say "hello" to me 67 * a "final" step 68 `...) 69 70 concept3 = make([]byte, 0) 71 concept3 = append(concept3, `# foo bar with <param> having errors 72 * first step with "foo" 73 * say <param> to me 74 * a <final> step 75 `...) 76 77 concept4 = make([]byte, 0) 78 concept4 = append(concept4, `# foo bar with 1 step 79 * say hello 80 `...) 81 82 spec1 = make([]byte, 0) 83 spec1 = append(spec1, `Specification Heading 84 ===================== 85 Scenario 1 86 ---------- 87 * say hello 88 * say "hello" to me 89 `...) 90 91 spec2 = make([]byte, 0) 92 spec2 = append(spec2, `Specification Heading 93 ===================== 94 Scenario 1 95 ---------- 96 * say hello 97 * say "hello" to me 98 * say "bye" to me 99 `...) 100 101 spec3 = make([]byte, 0) 102 spec3 = append(spec3, `Specification Heading 103 ===================== 104 |Col1|Col2| 105 |----|----| 106 |Val1|Val2| 107 108 Scenario with parse errors 109 ---------- 110 * say hello 111 * say "hello" to me 112 * say <bye> to me 113 `...) 114 115 specWithTags = make([]byte, 0) 116 specWithTags = append(specWithTags, `Specification Heading 117 ===================== 118 tags:foo, bar, hello 119 120 Scenario with tags 121 ---------- 122 tags: simple, complex 123 124 * say hello 125 * say "hello" to me 126 * say <bye> to me 127 `...) 128 129 spec2WithTags = make([]byte, 0) 130 spec2WithTags = append(spec2WithTags, `Specification Heading 131 ===================== 132 tags:foo, another 133 134 Scenario with tags 135 ---------- 136 tags: simple, complex 137 138 * say hello 139 * say "hello" to me 140 * say <bye> to me 141 `...) 142 143 specWithConcept = make([]byte, 0) 144 specWithConcept = append(specWithConcept, `Specification Heading 145 ===================== 146 tags:foo, another 147 148 Scenario with tags 149 ---------- 150 tags: simple, complex 151 152 * say hello 153 * foo bar with 1 step 154 `...) 155 156 } 157 158 func (s *MySuite) TestGetParsedSpecs(c *C) { 159 _, err := createFileIn(s.specsDir, "spec1.spec", spec1) 160 c.Assert(err, Equals, nil) 161 specInfoGatherer := &SpecInfoGatherer{SpecDirs: []string{specDir}} 162 163 specFiles := util.FindSpecFilesIn(s.specsDir) 164 details := specInfoGatherer.getParsedSpecs(specFiles) 165 166 c.Assert(len(details), Equals, 1) 167 c.Assert(details[0].Spec.Heading.Value, Equals, "Specification Heading") 168 } 169 170 func (s *MySuite) TestGetParsedSpecsForInvalidFile(c *C) { 171 specInfoGatherer := &SpecInfoGatherer{SpecDirs: []string{specDir}} 172 173 details := specInfoGatherer.getParsedSpecs([]string{"spec1.spec"}) 174 175 c.Assert(len(details), Equals, 1) 176 c.Assert(len(details[0].Errs), Equals, 1) 177 c.Assert(details[0].Errs[0].Message, Equals, "File spec1.spec doesn't exist.") 178 } 179 180 func (s *MySuite) TestGetParsedConcepts(c *C) { 181 _, err := createFileIn(s.specsDir, "concept.cpt", concept1) 182 c.Assert(err, Equals, nil) 183 specInfoGatherer := &SpecInfoGatherer{SpecDirs: []string{s.projectDir + string(filepath.Separator) + specDir}} 184 185 conceptsMap := specInfoGatherer.getParsedConcepts() 186 187 c.Assert(len(conceptsMap), Equals, 1) 188 c.Assert(conceptsMap["foo bar"], NotNil) 189 c.Assert(specInfoGatherer.conceptDictionary, NotNil) 190 } 191 192 func (s *MySuite) TestInitSpecsCache(c *C) { 193 _, err := createFileIn(s.specsDir, "spec1.spec", spec1) 194 c.Assert(err, Equals, nil) 195 specInfoGatherer := &SpecInfoGatherer{SpecDirs: []string{s.specsDir}} 196 specInfoGatherer.waitGroup.Add(1) 197 198 specInfoGatherer.initSpecsCache() 199 200 c.Assert(len(specInfoGatherer.specsCache.specDetails), Equals, 1) 201 } 202 203 func (s *MySuite) TestInitConceptsCache(c *C) { 204 _, err := createFileIn(s.specsDir, "concept1.cpt", concept1) 205 c.Assert(err, Equals, nil) 206 _, err = createFileIn(s.specsDir, "concept2.cpt", concept2) 207 c.Assert(err, Equals, nil) 208 specInfoGatherer := &SpecInfoGatherer{SpecDirs: []string{s.projectDir + string(filepath.Separator) + specDir}} 209 specInfoGatherer.waitGroup.Add(1) 210 211 specInfoGatherer.initConceptsCache() 212 213 c.Assert(len(specInfoGatherer.conceptsCache.concepts), Equals, 2) 214 } 215 216 func (s *MySuite) TestInitStepsCache(c *C) { 217 f, _ := createFileIn(s.specsDir, "spec1.spec", spec1) 218 f, _ = filepath.Abs(f) 219 f1, _ := createFileIn(s.specsDir, "concept2.cpt", concept2) 220 f1, _ = filepath.Abs(f1) 221 specInfoGatherer := &SpecInfoGatherer{SpecDirs: []string{s.specsDir}} 222 specInfoGatherer.waitGroup.Add(3) 223 224 specInfoGatherer.initConceptsCache() 225 specInfoGatherer.initSpecsCache() 226 specInfoGatherer.initStepsCache() 227 c.Assert(len(specInfoGatherer.stepsCache.steps[f]), Equals, 2) 228 c.Assert(len(specInfoGatherer.stepsCache.steps[f1]), Equals, 3) 229 230 } 231 232 func (s *MySuite) TestInitTagsCache(c *C) { 233 _, err := createFileIn(s.specsDir, "specWithTags.spec", specWithTags) 234 if err != nil { 235 c.Error(err) 236 } 237 238 specInfoGatherer := &SpecInfoGatherer{SpecDirs: []string{s.specsDir}} 239 specInfoGatherer.waitGroup.Add(2) 240 241 specInfoGatherer.initSpecsCache() 242 specInfoGatherer.initTagsCache() 243 c.Assert(len(specInfoGatherer.Tags()), Equals, 5) 244 } 245 246 func (s *MySuite) TestInitTagsCacheWithMultipleFiles(c *C) { 247 _, err := createFileIn(s.specsDir, "specWithTags.spec", specWithTags) 248 if err != nil { 249 c.Error(err) 250 } 251 252 _, err = createFileIn(s.specsDir, "spec2WithTags.spec", spec2WithTags) 253 if err != nil { 254 c.Error(err) 255 } 256 257 specInfoGatherer := &SpecInfoGatherer{SpecDirs: []string{s.specsDir}} 258 specInfoGatherer.waitGroup.Add(2) 259 260 specInfoGatherer.initSpecsCache() 261 specInfoGatherer.initTagsCache() 262 c.Assert(len(specInfoGatherer.Tags()), Equals, 6) 263 } 264 265 func (s *MySuite) TestGetStepsFromCachedSpecs(c *C) { 266 f, _ := createFileIn(s.specsDir, "spec1.spec", spec1) 267 f, _ = filepath.Abs(f) 268 specInfoGatherer := &SpecInfoGatherer{SpecDirs: []string{s.specsDir}} 269 specInfoGatherer.waitGroup.Add(3) 270 specInfoGatherer.initSpecsCache() 271 272 stepsFromSpecsMap := specInfoGatherer.getStepsFromCachedSpecs() 273 c.Assert(len(stepsFromSpecsMap[f]), Equals, 2) 274 c.Assert(stepsFromSpecsMap[f][0].Value, Equals, "say hello") 275 c.Assert(stepsFromSpecsMap[f][1].Value, Equals, "say {} to me") 276 } 277 278 func (s *MySuite) TestGetStepsFromCachedConcepts(c *C) { 279 f, _ := createFileIn(s.specsDir, "concept1.cpt", concept1) 280 f, _ = filepath.Abs(f) 281 specInfoGatherer := &SpecInfoGatherer{SpecDirs: []string{s.specsDir}} 282 specInfoGatherer.waitGroup.Add(3) 283 specInfoGatherer.initSpecsCache() 284 specInfoGatherer.initConceptsCache() 285 286 stepsFromConceptsMap := specInfoGatherer.getStepsFromCachedConcepts() 287 c.Assert(len(stepsFromConceptsMap[f]), Equals, 3) 288 c.Assert(stepsFromConceptsMap[f][0].Value, Equals, "first step with {}") 289 c.Assert(stepsFromConceptsMap[f][1].Value, Equals, "say {} to me") 290 c.Assert(stepsFromConceptsMap[f][2].Value, Equals, "a {} step") 291 } 292 293 func (s *MySuite) TestGetAvailableSteps(c *C) { 294 var steps []*gauge.Step 295 _, err := createFileIn(s.specsDir, "spec1.spec", spec1) 296 if err != nil { 297 c.Error(err) 298 } 299 300 specInfoGatherer := &SpecInfoGatherer{SpecDirs: []string{s.specsDir}} 301 specInfoGatherer.waitGroup.Add(2) 302 specInfoGatherer.initSpecsCache() 303 specInfoGatherer.initStepsCache() 304 305 steps = specInfoGatherer.Steps(true) 306 c.Assert(len(steps), Equals, 2) 307 if !hasStep(steps, "say hello") { 308 c.Fatalf("Step value not found %s", "say hello") 309 } 310 if !hasStep(steps, "say {} to me") { 311 c.Fatalf("Step value not found %s", "say {} to me") 312 } 313 } 314 315 func (s *MySuite) TestGetAvailableStepsShouldFilterDuplicates(c *C) { 316 var steps []*gauge.Step 317 _, err := createFileIn(s.specsDir, "spec2.spec", spec2) 318 if err != nil { 319 c.Error(err) 320 } 321 322 specInfoGatherer := &SpecInfoGatherer{SpecDirs: []string{s.specsDir}} 323 specInfoGatherer.waitGroup.Add(2) 324 specInfoGatherer.initSpecsCache() 325 specInfoGatherer.initStepsCache() 326 327 steps = specInfoGatherer.Steps(true) 328 c.Assert(len(steps), Equals, 2) 329 if !hasStep(steps, "say hello") { 330 c.Fatalf("Step value not found %s", "say hello") 331 } 332 if !hasStep(steps, "say {} to me") { 333 c.Fatalf("Step value not found %s", "say {} to me") 334 } 335 } 336 337 func (s *MySuite) TestGetAvailableStepsShouldFilterConcepts(c *C) { 338 var steps []*gauge.Step 339 _, err := createFileIn(s.specsDir, "concept1.cpt", concept4) 340 if err != nil { 341 c.Error(err) 342 } 343 344 _, err = createFileIn(s.specsDir, "spec1.spec", specWithConcept) 345 if err != nil { 346 c.Error(err) 347 } 348 349 specInfoGatherer := &SpecInfoGatherer{SpecDirs: []string{s.specsDir}} 350 specInfoGatherer.waitGroup.Add(3) 351 specInfoGatherer.initConceptsCache() 352 specInfoGatherer.initSpecsCache() 353 specInfoGatherer.initStepsCache() 354 355 steps = specInfoGatherer.Steps(true) 356 c.Assert(len(steps), Equals, 1) 357 if hasStep(steps, "foo bar with 1 step") { 358 c.Fatalf("Step value found %s", "foo bar with 1 step") 359 } 360 steps = specInfoGatherer.Steps(false) 361 c.Assert(len(steps), Equals, 2) 362 if !hasStep(steps, "foo bar with 1 step") { 363 c.Fatalf("Step value not found %s", "foo bar with 1 step") 364 } 365 } 366 367 func (s *MySuite) TestGetAvailableAllStepsShouldFilterConcepts(c *C) { 368 var steps []*gauge.Step 369 _, err := createFileIn(s.specsDir, "concept1.cpt", concept4) 370 if err != nil { 371 c.Error(err) 372 } 373 374 _, err = createFileIn(s.specsDir, "spec1.spec", specWithConcept) 375 if err != nil { 376 c.Error(err) 377 } 378 379 specInfoGatherer := &SpecInfoGatherer{SpecDirs: []string{s.specsDir}} 380 specInfoGatherer.waitGroup.Add(3) 381 specInfoGatherer.initConceptsCache() 382 specInfoGatherer.initSpecsCache() 383 specInfoGatherer.initStepsCache() 384 385 steps = specInfoGatherer.AllSteps(true) 386 c.Assert(len(steps), Equals, 2) 387 if hasStep(steps, "foo bar with 1 step") { 388 c.Fatalf("Step value found %s", "foo bar with 1 step") 389 } 390 steps = specInfoGatherer.AllSteps(false) 391 c.Assert(len(steps), Equals, 3) 392 if !hasStep(steps, "foo bar with 1 step") { 393 c.Fatalf("Step value not found %s", "foo bar with 1 step") 394 } 395 } 396 397 func hasStep(steps []*gauge.Step, stepText string) bool { 398 for _, step := range steps { 399 if step.Value == stepText { 400 return true 401 } 402 } 403 return false 404 } 405 406 func (s *MySuite) TestHasSpecForSpecDetail(c *C) { 407 c.Assert((&SpecDetail{}).HasSpec(), Equals, false) 408 c.Assert((&SpecDetail{Spec: &gauge.Specification{}}).HasSpec(), Equals, false) 409 c.Assert((&SpecDetail{Spec: &gauge.Specification{Heading: &gauge.Heading{}}}).HasSpec(), Equals, true) 410 } 411 412 func (s *MySuite) TestGetAvailableSpecDetails(c *C) { 413 _, err := createFileIn(s.specsDir, "spec1.spec", spec1) 414 c.Assert(err, Equals, nil) 415 sig := &SpecInfoGatherer{SpecDirs: []string{s.specsDir}, specsCache: specsCache{specDetails: make(map[string]*SpecDetail)}} 416 specFiles := util.FindSpecFilesIn(s.specsDir) 417 sig.specsCache.specDetails[specFiles[0]] = &SpecDetail{Spec: &gauge.Specification{Heading: &gauge.Heading{Value: "Specification Heading"}}} 418 419 details := sig.GetAvailableSpecDetails(specFiles) 420 421 c.Assert(len(details), Equals, 1) 422 c.Assert(details[0].Spec.Heading.Value, Equals, "Specification Heading") 423 } 424 425 func (s *MySuite) TestGetAvailableSpecDetailsInDefaultDir(c *C) { 426 _, err := createFileIn(s.specsDir, "spec1.spec", spec1) 427 c.Assert(err, Equals, nil) 428 wd, _ := os.Getwd() 429 err = os.Chdir(s.projectDir) 430 if err != nil { 431 c.Error(err) 432 } 433 defer func() { 434 err := os.Chdir(wd) 435 if err != nil { 436 c.Error(err) 437 } 438 }() 439 sig := &SpecInfoGatherer{SpecDirs: []string{s.specsDir}, specsCache: specsCache{specDetails: make(map[string]*SpecDetail)}} 440 specFiles := util.FindSpecFilesIn(specDir) 441 sig.specsCache.specDetails[specFiles[0]] = &SpecDetail{Spec: &gauge.Specification{Heading: &gauge.Heading{Value: "Specification Heading"}}} 442 443 details := sig.GetAvailableSpecDetails([]string{}) 444 445 c.Assert(len(details), Equals, 1) 446 c.Assert(details[0].Spec.Heading.Value, Equals, "Specification Heading") 447 } 448 449 func (s *MySuite) TestGetAvailableSpecDetailsWithEmptyCache(c *C) { 450 _, err := createFileIn(s.specsDir, "spec1.spec", spec1) 451 c.Assert(err, Equals, nil) 452 sig := &SpecInfoGatherer{SpecDirs: []string{s.specsDir}} 453 454 details := sig.GetAvailableSpecDetails([]string{}) 455 456 c.Assert(len(details), Equals, 0) 457 } 458 459 func (s *MySuite) TestParamsForStepFile(c *C) { 460 file, _ := createFileIn(s.specsDir, "spec3.spec", spec3) 461 file, _ = filepath.Abs(file) 462 specInfoGatherer := &SpecInfoGatherer{SpecDirs: []string{s.specsDir}} 463 specInfoGatherer.waitGroup.Add(2) 464 specInfoGatherer.initConceptsCache() 465 specInfoGatherer.initSpecsCache() 466 specInfoGatherer.initStepsCache() 467 specInfoGatherer.initParamsCache() 468 469 staticParams := specInfoGatherer.Params(file, gauge.Static) 470 c.Assert(len(staticParams), Equals, 1) 471 dynamicParams := specInfoGatherer.Params(file, gauge.Dynamic) 472 c.Assert(len(dynamicParams), Equals, 3) 473 hasParam := func(param string, list []gauge.StepArg) bool { 474 for _, p := range list { 475 if p.ArgValue() == param { 476 return true 477 } 478 } 479 return false 480 } 481 if !hasParam("hello", staticParams) { 482 c.Errorf(`Param "hello" not found`) 483 } 484 if !hasParam("bye", dynamicParams) { 485 c.Errorf(`Param "bye" not found`) 486 } 487 if !hasParam("Col1", dynamicParams) { 488 c.Errorf(`Param "Col1" not found`) 489 } 490 if !hasParam("Col2", dynamicParams) { 491 c.Errorf(`Param "Col1" not found`) 492 } 493 } 494 495 func (s *MySuite) TestParamsForConceptFile(c *C) { 496 file, _ := createFileIn(s.specsDir, "concept3.cpt", concept3) 497 file, _ = filepath.Abs(file) 498 specInfoGatherer := &SpecInfoGatherer{SpecDirs: []string{s.specsDir}} 499 specInfoGatherer.waitGroup.Add(2) 500 specInfoGatherer.initConceptsCache() 501 specInfoGatherer.initSpecsCache() 502 specInfoGatherer.initStepsCache() 503 specInfoGatherer.initParamsCache() 504 505 staticParams := specInfoGatherer.Params(file, gauge.Static) 506 c.Assert(len(staticParams), Equals, 1) 507 dynamicParams := specInfoGatherer.Params(file, gauge.Dynamic) 508 c.Assert(len(dynamicParams), Equals, 2) 509 hasParam := func(param string, list []gauge.StepArg) bool { 510 for _, p := range list { 511 if p.ArgValue() == param { 512 return true 513 } 514 } 515 return false 516 } 517 if !hasParam("foo", staticParams) { 518 c.Errorf(`Param "foo" not found`) 519 } 520 if !hasParam("param", dynamicParams) { 521 c.Errorf(`Param "param" not found`) 522 } 523 if !hasParam("final", dynamicParams) { 524 c.Errorf(`Param "final" not found`) 525 } 526 } 527 528 func (s *MySuite) TestAllStepsOnFileRename(c *C) { 529 _, err := createFileIn(s.specsDir, "spec1.spec", spec1) 530 if err != nil { 531 c.Error(err) 532 } 533 534 specInfoGatherer := &SpecInfoGatherer{SpecDirs: []string{s.specsDir}} 535 specInfoGatherer.initSpecsCache() 536 specInfoGatherer.initStepsCache() 537 538 c.Assert(len(specInfoGatherer.AllSteps(true)), Equals, 2) 539 _, err = renameFileIn(s.specsDir, "spec1.spec", "spec42.spec") 540 if err != nil { 541 c.Error(err) 542 } 543 544 c.Assert(len(specInfoGatherer.AllSteps(true)), Equals, 2) 545 } 546 547 func createFileIn(dir string, fileName string, data []byte) (string, error) { 548 err := os.MkdirAll(dir, 0750) 549 if err != nil { 550 return "", fmt.Errorf("unable to create %s: %s", dir, err.Error()) 551 } 552 553 err = os.WriteFile(filepath.Join(dir, fileName), data, 0644) 554 return filepath.Join(dir, fileName), err 555 } 556 557 func renameFileIn(dir string, oldFileName string, newFileName string) (string, error) { 558 err := os.Rename(filepath.Join(dir, oldFileName), filepath.Join(dir, newFileName)) 559 return filepath.Join(dir, newFileName), err 560 } 561 562 func createDirIn(dir string, dirName string) (string, error) { 563 tempDir, _ := os.MkdirTemp(dir, dirName) 564 fullDirName := filepath.Join(dir, dirName) 565 err := os.Rename(tempDir, fullDirName) 566 return fullDirName, err 567 }