github.com/ezbuy/gauge@v0.9.4-0.20171013092048-7ac5bd3931cd/api/infoGatherer/specDetails_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 infoGatherer
    19  
    20  import (
    21  	"io/ioutil"
    22  	"os"
    23  	"path/filepath"
    24  	"testing"
    25  
    26  	"github.com/getgauge/gauge/config"
    27  	"github.com/getgauge/gauge/gauge"
    28  	"github.com/getgauge/gauge/util"
    29  	. "gopkg.in/check.v1"
    30  )
    31  
    32  func Test(t *testing.T) { TestingT(t) }
    33  
    34  const specDir = "specs"
    35  
    36  var _ = Suite(&MySuite{})
    37  
    38  var concept1 []byte
    39  var concept2 []byte
    40  var concept3 []byte
    41  var spec1 []byte
    42  var spec2 []byte
    43  var spec3 []byte
    44  
    45  type MySuite struct {
    46  	specsDir   string
    47  	projectDir string
    48  }
    49  
    50  func (s *MySuite) SetUpTest(c *C) {
    51  	s.projectDir, _ = ioutil.TempDir("_testdata", "gaugeTest")
    52  	s.specsDir, _ = createDirIn(s.projectDir, specDir)
    53  	config.ProjectRoot = s.projectDir
    54  
    55  	s.buildTestData()
    56  }
    57  
    58  func (s *MySuite) TearDownTest(c *C) {
    59  	os.RemoveAll(s.projectDir)
    60  }
    61  
    62  func (s *MySuite) buildTestData() {
    63  	concept1 = make([]byte, 0)
    64  	concept1 = append(concept1, `# foo bar
    65  * first step with "foo"
    66  * say "hello" to me
    67  * a "final" step
    68  `...)
    69  
    70  	concept2 = make([]byte, 0)
    71  	concept2 = append(concept2, `# bar
    72  * first step with "foo"
    73  * say "hello" to me
    74  * a "final" step
    75  `...)
    76  
    77  	concept3 = make([]byte, 0)
    78  	concept3 = append(concept3, `# foo bar with <param> having errors
    79  * first step with "foo"
    80  * say <param> to me
    81  * a <final> step
    82  `...)
    83  
    84  	spec1 = make([]byte, 0)
    85  	spec1 = append(spec1, `Specification Heading
    86  =====================
    87  Scenario 1
    88  ----------
    89  * say hello
    90  * say "hello" to me
    91  `...)
    92  
    93  	spec2 = make([]byte, 0)
    94  	spec2 = append(spec2, `Specification Heading
    95  =====================
    96  Scenario 1
    97  ----------
    98  * say hello
    99  * say "hello" to me
   100  * say "bye" to me
   101  `...)
   102  
   103  	spec3 = make([]byte, 0)
   104  	spec3 = append(spec3, `Specification Heading
   105  =====================
   106  |Col1|Col2|
   107  |----|----|
   108  |Val1|Val2|
   109  
   110  Scenario with parse errors
   111  ----------
   112  * say hello
   113  * say "hello" to me
   114  * say <bye> to me
   115  `...)
   116  }
   117  
   118  func (s *MySuite) TestGetParsedSpecs(c *C) {
   119  	_, err := createFileIn(s.specsDir, "spec1.spec", spec1)
   120  	c.Assert(err, Equals, nil)
   121  	specInfoGatherer := &SpecInfoGatherer{SpecDirs: []string{specDir}}
   122  
   123  	specFiles := util.FindSpecFilesIn(s.specsDir)
   124  	details := specInfoGatherer.getParsedSpecs(specFiles)
   125  
   126  	c.Assert(len(details), Equals, 1)
   127  	c.Assert(details[0].Spec.Heading.Value, Equals, "Specification Heading")
   128  }
   129  
   130  func (s *MySuite) TestGetParsedSpecsForInvalidFile(c *C) {
   131  	specInfoGatherer := &SpecInfoGatherer{SpecDirs: []string{specDir}}
   132  
   133  	details := specInfoGatherer.getParsedSpecs([]string{"spec1.spec"})
   134  
   135  	c.Assert(len(details), Equals, 1)
   136  	c.Assert(len(details[0].Errs), Equals, 1)
   137  	c.Assert(details[0].Errs[0].Message, Equals, "File spec1.spec doesn't exist.")
   138  }
   139  
   140  func (s *MySuite) TestGetParsedConcepts(c *C) {
   141  	_, err := createFileIn(s.specsDir, "concept.cpt", concept1)
   142  	c.Assert(err, Equals, nil)
   143  	specInfoGatherer := &SpecInfoGatherer{SpecDirs: []string{s.projectDir + string(filepath.Separator) + specDir}}
   144  
   145  	conceptsMap := specInfoGatherer.getParsedConcepts()
   146  
   147  	c.Assert(len(conceptsMap), Equals, 1)
   148  	c.Assert(conceptsMap["foo bar"], NotNil)
   149  	c.Assert(specInfoGatherer.conceptDictionary, NotNil)
   150  }
   151  
   152  func (s *MySuite) TestGetParsedStepValues(c *C) {
   153  	steps := []*gauge.Step{
   154  		&gauge.Step{Value: "Step with a {}", LineText: "Step with a <table>", IsConcept: true, HasInlineTable: true},
   155  		&gauge.Step{Value: "A context step", LineText: "A context step", IsConcept: false},
   156  		&gauge.Step{Value: "Say {} to {}", LineText: "Say \"hello\" to \"gauge\"", IsConcept: false,
   157  			Args: []*gauge.StepArg{
   158  				&gauge.StepArg{Name: "first", Value: "hello", ArgType: gauge.Static},
   159  				&gauge.StepArg{Name: "second", Value: "gauge", ArgType: gauge.Static}},
   160  		},
   161  	}
   162  
   163  	stepValues := getParsedStepValues(steps)
   164  
   165  	c.Assert(len(stepValues), Equals, 2)
   166  	c.Assert(stepValues[0].StepValue, Equals, "A context step")
   167  	c.Assert(stepValues[1].StepValue, Equals, "Say {} to {}")
   168  }
   169  
   170  func (s *MySuite) TestInitSpecsCache(c *C) {
   171  	_, err := createFileIn(s.specsDir, "spec1.spec", spec1)
   172  	c.Assert(err, Equals, nil)
   173  	specInfoGatherer := &SpecInfoGatherer{SpecDirs: []string{s.specsDir}}
   174  	specInfoGatherer.waitGroup.Add(1)
   175  
   176  	specInfoGatherer.initSpecsCache()
   177  
   178  	c.Assert(len(specInfoGatherer.specsCache.specDetails), Equals, 1)
   179  }
   180  
   181  func (s *MySuite) TestInitConceptsCache(c *C) {
   182  	_, err := createFileIn(s.specsDir, "concept1.cpt", concept1)
   183  	c.Assert(err, Equals, nil)
   184  	_, err = createFileIn(s.specsDir, "concept2.cpt", concept2)
   185  	c.Assert(err, Equals, nil)
   186  	specInfoGatherer := &SpecInfoGatherer{SpecDirs: []string{s.projectDir + string(filepath.Separator) + specDir}}
   187  	specInfoGatherer.waitGroup.Add(1)
   188  
   189  	specInfoGatherer.initConceptsCache()
   190  
   191  	c.Assert(len(specInfoGatherer.conceptsCache.concepts), Equals, 2)
   192  }
   193  
   194  func (s *MySuite) TestInitStepsCache(c *C) {
   195  	f, _ := createFileIn(s.specsDir, "spec1.spec", spec1)
   196  	f, _ = filepath.Abs(f)
   197  	f1, _ := createFileIn(s.specsDir, "concept2.cpt", concept2)
   198  	f1, _ = filepath.Abs(f1)
   199  	specInfoGatherer := &SpecInfoGatherer{SpecDirs: []string{s.specsDir}}
   200  	specInfoGatherer.waitGroup.Add(3)
   201  
   202  	specInfoGatherer.initConceptsCache()
   203  	specInfoGatherer.initSpecsCache()
   204  	specInfoGatherer.initStepsCache()
   205  	c.Assert(len(specInfoGatherer.stepsCache.stepValues[f]), Equals, 2)
   206  	c.Assert(len(specInfoGatherer.stepsCache.stepValues[f1]), Equals, 3)
   207  
   208  }
   209  
   210  func (s *MySuite) TestGetStepsFromCachedSpecs(c *C) {
   211  	var stepsFromSpecsMap = make(map[string][]*gauge.StepValue, 0)
   212  	f, _ := createFileIn(s.specsDir, "spec1.spec", spec1)
   213  	f, _ = filepath.Abs(f)
   214  	specInfoGatherer := &SpecInfoGatherer{SpecDirs: []string{s.specsDir}}
   215  	specInfoGatherer.waitGroup.Add(3)
   216  	specInfoGatherer.initSpecsCache()
   217  
   218  	stepsFromSpecsMap = specInfoGatherer.getStepsFromCachedSpecs()
   219  	c.Assert(len(stepsFromSpecsMap[f]), Equals, 2)
   220  	c.Assert(stepsFromSpecsMap[f][0].StepValue, Equals, "say hello")
   221  	c.Assert(stepsFromSpecsMap[f][1].StepValue, Equals, "say {} to me")
   222  }
   223  
   224  func (s *MySuite) TestGetStepsFromCachedConcepts(c *C) {
   225  	var stepsFromConceptsMap = make(map[string][]*gauge.StepValue, 0)
   226  	f, _ := createFileIn(s.specsDir, "concept1.cpt", concept1)
   227  	f, _ = filepath.Abs(f)
   228  	specInfoGatherer := &SpecInfoGatherer{SpecDirs: []string{s.specsDir}}
   229  	specInfoGatherer.waitGroup.Add(3)
   230  	specInfoGatherer.initSpecsCache()
   231  	specInfoGatherer.initConceptsCache()
   232  
   233  	stepsFromConceptsMap = specInfoGatherer.getStepsFromCachedConcepts()
   234  	c.Assert(len(stepsFromConceptsMap[f]), Equals, 3)
   235  	c.Assert(stepsFromConceptsMap[f][0].StepValue, Equals, "first step with {}")
   236  	c.Assert(stepsFromConceptsMap[f][1].StepValue, Equals, "say {} to me")
   237  	c.Assert(stepsFromConceptsMap[f][2].StepValue, Equals, "a {} step")
   238  }
   239  
   240  func (s *MySuite) TestGetAvailableSteps(c *C) {
   241  	var stepValues []*gauge.StepValue
   242  	createFileIn(s.specsDir, "spec1.spec", spec1)
   243  	specInfoGatherer := &SpecInfoGatherer{SpecDirs: []string{s.specsDir}}
   244  	specInfoGatherer.waitGroup.Add(2)
   245  	specInfoGatherer.initSpecsCache()
   246  	specInfoGatherer.initStepsCache()
   247  
   248  	stepValues = specInfoGatherer.Steps()
   249  	c.Assert(len(stepValues), Equals, 2)
   250  	if !hasStep(stepValues, "say hello") {
   251  		c.Fatalf("Step value not found %s", "say hello")
   252  	}
   253  	if !hasStep(stepValues, "say {} to me") {
   254  		c.Fatalf("Step value not found %s", "say {} to me")
   255  	}
   256  }
   257  
   258  func (s *MySuite) TestGetAvailableStepsShouldFilterDuplicates(c *C) {
   259  	var stepValues []*gauge.StepValue
   260  	createFileIn(s.specsDir, "spec2.spec", spec2)
   261  	specInfoGatherer := &SpecInfoGatherer{SpecDirs: []string{s.specsDir}}
   262  	specInfoGatherer.waitGroup.Add(2)
   263  	specInfoGatherer.initSpecsCache()
   264  	specInfoGatherer.initStepsCache()
   265  
   266  	stepValues = specInfoGatherer.Steps()
   267  	c.Assert(len(stepValues), Equals, 2)
   268  	if !hasStep(stepValues, "say hello") {
   269  		c.Fatalf("Step value not found %s", "say hello")
   270  	}
   271  	if !hasStep(stepValues, "say {} to me") {
   272  		c.Fatalf("Step value not found %s", "say {} to me")
   273  	}
   274  }
   275  
   276  func hasStep(stepValues []*gauge.StepValue, step string) bool {
   277  	for _, value := range stepValues {
   278  		if value.StepValue == step {
   279  			return true
   280  		}
   281  	}
   282  	return false
   283  }
   284  
   285  func (s *MySuite) TestHasSpecForSpecDetail(c *C) {
   286  	c.Assert((&SpecDetail{}).HasSpec(), Equals, false)
   287  	c.Assert((&SpecDetail{Spec: &gauge.Specification{}}).HasSpec(), Equals, false)
   288  	c.Assert((&SpecDetail{Spec: &gauge.Specification{Heading: &gauge.Heading{}}}).HasSpec(), Equals, true)
   289  }
   290  
   291  func (s *MySuite) TestGetAvailableSpecDetails(c *C) {
   292  	_, err := createFileIn(s.specsDir, "spec1.spec", spec1)
   293  	c.Assert(err, Equals, nil)
   294  	sig := &SpecInfoGatherer{SpecDirs: []string{s.specsDir}, specsCache: specsCache{specDetails: make(map[string]*SpecDetail)}}
   295  	specFiles := util.FindSpecFilesIn(s.specsDir)
   296  	sig.specsCache.specDetails[specFiles[0]] = &SpecDetail{Spec: &gauge.Specification{Heading: &gauge.Heading{Value: "Specification Heading"}}}
   297  
   298  	details := sig.GetAvailableSpecDetails(specFiles)
   299  
   300  	c.Assert(len(details), Equals, 1)
   301  	c.Assert(details[0].Spec.Heading.Value, Equals, "Specification Heading")
   302  }
   303  
   304  func (s *MySuite) TestGetAvailableSpecDetailsInDefaultDir(c *C) {
   305  	_, err := createFileIn(s.specsDir, "spec1.spec", spec1)
   306  	c.Assert(err, Equals, nil)
   307  	wd, _ := os.Getwd()
   308  	os.Chdir(s.projectDir)
   309  	defer os.Chdir(wd)
   310  	sig := &SpecInfoGatherer{SpecDirs: []string{s.specsDir}, specsCache: specsCache{specDetails: make(map[string]*SpecDetail)}}
   311  	specFiles := util.FindSpecFilesIn(specDir)
   312  	sig.specsCache.specDetails[specFiles[0]] = &SpecDetail{Spec: &gauge.Specification{Heading: &gauge.Heading{Value: "Specification Heading"}}}
   313  
   314  	details := sig.GetAvailableSpecDetails([]string{})
   315  
   316  	c.Assert(len(details), Equals, 1)
   317  	c.Assert(details[0].Spec.Heading.Value, Equals, "Specification Heading")
   318  }
   319  
   320  func (s *MySuite) TestGetAvailableSpecDetailsWithEmptyCache(c *C) {
   321  	_, err := createFileIn(s.specsDir, "spec1.spec", spec1)
   322  	c.Assert(err, Equals, nil)
   323  	sig := &SpecInfoGatherer{SpecDirs: []string{s.specsDir}}
   324  
   325  	details := sig.GetAvailableSpecDetails([]string{})
   326  
   327  	c.Assert(len(details), Equals, 0)
   328  }
   329  
   330  func (s *MySuite) TestParamsForStepFile(c *C) {
   331  	file, _ := createFileIn(s.specsDir, "spec3.spec", spec3)
   332  	file, _ = filepath.Abs(file)
   333  	specInfoGatherer := &SpecInfoGatherer{SpecDirs: []string{s.specsDir}}
   334  	specInfoGatherer.waitGroup.Add(2)
   335  	specInfoGatherer.initConceptsCache()
   336  	specInfoGatherer.initSpecsCache()
   337  	specInfoGatherer.initStepsCache()
   338  	specInfoGatherer.initParamsCache()
   339  
   340  	staticParams := specInfoGatherer.Params(file, gauge.Static)
   341  	c.Assert(len(staticParams), Equals, 1)
   342  	dynamicParams := specInfoGatherer.Params(file, gauge.Dynamic)
   343  	c.Assert(len(dynamicParams), Equals, 3)
   344  	hasParam := func(param string, list []gauge.StepArg) bool {
   345  		for _, p := range list {
   346  			if p.ArgValue() == param {
   347  				return true
   348  			}
   349  		}
   350  		return false
   351  	}
   352  	if !hasParam("hello", staticParams) {
   353  		c.Errorf(`Param "hello" not found`)
   354  	}
   355  	if !hasParam("bye", dynamicParams) {
   356  		c.Errorf(`Param "bye" not found`)
   357  	}
   358  	if !hasParam("Col1", dynamicParams) {
   359  		c.Errorf(`Param "Col1" not found`)
   360  	}
   361  	if !hasParam("Col2", dynamicParams) {
   362  		c.Errorf(`Param "Col1" not found`)
   363  	}
   364  }
   365  
   366  func (s *MySuite) TestParamsForConceptFile(c *C) {
   367  	file, _ := createFileIn(s.specsDir, "concept3.cpt", concept3)
   368  	file, _ = filepath.Abs(file)
   369  	specInfoGatherer := &SpecInfoGatherer{SpecDirs: []string{s.specsDir}}
   370  	specInfoGatherer.waitGroup.Add(2)
   371  	specInfoGatherer.initConceptsCache()
   372  	specInfoGatherer.initSpecsCache()
   373  	specInfoGatherer.initStepsCache()
   374  	specInfoGatherer.initParamsCache()
   375  
   376  	staticParams := specInfoGatherer.Params(file, gauge.Static)
   377  	c.Assert(len(staticParams), Equals, 1)
   378  	dynamicParams := specInfoGatherer.Params(file, gauge.Dynamic)
   379  	c.Assert(len(dynamicParams), Equals, 2)
   380  	hasParam := func(param string, list []gauge.StepArg) bool {
   381  		for _, p := range list {
   382  			if p.ArgValue() == param {
   383  				return true
   384  			}
   385  		}
   386  		return false
   387  	}
   388  	if !hasParam("foo", staticParams) {
   389  		c.Errorf(`Param "foo" not found`)
   390  	}
   391  	if !hasParam("param", dynamicParams) {
   392  		c.Errorf(`Param "param" not found`)
   393  	}
   394  	if !hasParam("final", dynamicParams) {
   395  		c.Errorf(`Param "final" not found`)
   396  	}
   397  }
   398  
   399  func createFileIn(dir string, fileName string, data []byte) (string, error) {
   400  	os.MkdirAll(dir, 0755)
   401  	err := ioutil.WriteFile(filepath.Join(dir, fileName), data, 0644)
   402  	return filepath.Join(dir, fileName), err
   403  }
   404  
   405  func createDirIn(dir string, dirName string) (string, error) {
   406  	tempDir, err := ioutil.TempDir(dir, dirName)
   407  	fullDirName := filepath.Join(dir, dirName)
   408  	err = os.Rename(tempDir, fullDirName)
   409  	return fullDirName, err
   410  }