github.com/onsi/ginkgo@v1.16.6-0.20211118180735-4e1925ba4c95/ginkgo/internal/testsuite_test.go (about)

     1  package internal_test
     2  
     3  import (
     4  	"os"
     5  	"path/filepath"
     6  
     7  	. "github.com/onsi/ginkgo"
     8  	. "github.com/onsi/ginkgo/ginkgo/internal"
     9  	"github.com/onsi/ginkgo/types"
    10  	. "github.com/onsi/gomega"
    11  )
    12  
    13  func TS(path string, pkgName string, isGinkgo bool, state TestSuiteState) TestSuite {
    14  	return TestSuite{
    15  		Path:        path,
    16  		PackageName: pkgName,
    17  		IsGinkgo:    isGinkgo,
    18  		Precompiled: false,
    19  		State:       state,
    20  	}
    21  }
    22  
    23  func PTS(path string, pkgName string, isGinkgo bool, pathToCompiledTest string, state TestSuiteState) TestSuite {
    24  	return TestSuite{
    25  		Path:               path,
    26  		PackageName:        pkgName,
    27  		IsGinkgo:           isGinkgo,
    28  		Precompiled:        true,
    29  		PathToCompiledTest: pathToCompiledTest,
    30  		State:              state,
    31  	}
    32  }
    33  
    34  var _ = Describe("TestSuite", func() {
    35  	Describe("Finding Suites", func() {
    36  		var tmpDir string
    37  		var origWd string
    38  		var cliConf types.CLIConfig
    39  
    40  		writeFile := func(folder string, filename string, content string, mode os.FileMode) {
    41  			path := filepath.Join(tmpDir, folder)
    42  			err := os.MkdirAll(path, 0700)
    43  			Ω(err).ShouldNot(HaveOccurred())
    44  
    45  			path = filepath.Join(path, filename)
    46  			os.WriteFile(path, []byte(content), mode)
    47  		}
    48  
    49  		BeforeEach(func() {
    50  			cliConf = types.CLIConfig{}
    51  
    52  			var err error
    53  			tmpDir, err = os.MkdirTemp("/tmp", "ginkgo")
    54  			Ω(err).ShouldNot(HaveOccurred())
    55  
    56  			origWd, err = os.Getwd()
    57  			Ω(err).ShouldNot(HaveOccurred())
    58  			Ω(os.Chdir(tmpDir)).Should(Succeed())
    59  
    60  			//go files in the root directory (no tests)
    61  			writeFile("/", "main.go", "package main", 0666)
    62  
    63  			//non-go files in a nested directory
    64  			writeFile("/redherring", "big_test.jpg", "package ginkgo", 0666)
    65  
    66  			//ginkgo tests in ignored go files
    67  			writeFile("/ignored", ".ignore_dot_test.go", `import "github.com/onsi/ginkgo"`, 0666)
    68  			writeFile("/ignored", "_ignore_underscore_test.go", `import "github.com/onsi/ginkgo"`, 0666)
    69  
    70  			//non-ginkgo tests in a nested directory
    71  			writeFile("/professorplum", "professorplum_test.go", `import "testing"`, 0666)
    72  
    73  			//ginkgo tests in a nested directory
    74  			writeFile("/colonelmustard", "colonelmustard_test.go", `import "github.com/onsi/ginkgo"`, 0666)
    75  
    76  			//ginkgo tests in a deeply nested directory
    77  			writeFile("/colonelmustard/library", "library_test.go", `import "github.com/onsi/ginkgo"`, 0666)
    78  
    79  			//ginkgo tests deeply nested in a vendored dependency
    80  			writeFile("/vendor/mrspeacock/lounge", "lounge_test.go", `import "github.com/onsi/ginkgo"`, 0666)
    81  
    82  			//a precompiled ginkgo test
    83  			writeFile("/precompiled-dir", "precompiled.test", `fake-binary-file`, 0777)
    84  			writeFile("/precompiled-dir", "some-other-binary", `fake-binary-file`, 0777)
    85  			writeFile("/precompiled-dir", "windows.test.exe", `fake-binary-file`, 0666)
    86  			writeFile("/precompiled-dir", "windows.exe", `fake-binary-file`, 0666)
    87  			writeFile("/precompiled-dir", "nonexecutable.test", `fake-binary-file`, 0666)
    88  		})
    89  
    90  		AfterEach(func() {
    91  			Ω(os.Chdir(origWd)).Should(Succeed())
    92  			os.RemoveAll(tmpDir)
    93  		})
    94  
    95  		Context("when passed no args", func() {
    96  			Context("when told to recurse", func() {
    97  				BeforeEach(func() {
    98  					cliConf.Recurse = true
    99  				})
   100  
   101  				It("recurses through the current directory, returning all identified tests and skipping vendored, ignored, and precompiled tests", func() {
   102  					suites := FindSuites([]string{}, cliConf, false)
   103  					Ω(suites).Should(ConsistOf(
   104  						TS("./professorplum", "professorplum", false, TestSuiteStateUncompiled),
   105  						TS("./colonelmustard", "colonelmustard", true, TestSuiteStateUncompiled),
   106  						TS("./colonelmustard/library", "library", true, TestSuiteStateUncompiled),
   107  					))
   108  				})
   109  			})
   110  
   111  			Context("when told to recurse and there is a skip-package filter", func() {
   112  				BeforeEach(func() {
   113  					cliConf.Recurse = true
   114  					cliConf.SkipPackage = "professorplum,library,floop"
   115  				})
   116  
   117  				It("recurses through the current directory, returning all identified tests and skipping vendored, ignored, and precompiled tests", func() {
   118  					suites := FindSuites([]string{}, cliConf, false)
   119  					Ω(suites).Should(ConsistOf(
   120  						TS("./professorplum", "professorplum", false, TestSuiteStateSkippedByFilter),
   121  						TS("./colonelmustard", "colonelmustard", true, TestSuiteStateUncompiled),
   122  						TS("./colonelmustard/library", "library", true, TestSuiteStateSkippedByFilter),
   123  					))
   124  				})
   125  			})
   126  
   127  			Context("when there are no tests in the current directory", func() {
   128  				BeforeEach(func() {
   129  					cliConf.Recurse = false
   130  				})
   131  
   132  				It("returns empty", func() {
   133  					suites := FindSuites([]string{}, cliConf, false)
   134  					Ω(suites).Should(BeEmpty())
   135  				})
   136  			})
   137  
   138  			Context("when told not to recurse", func() {
   139  				BeforeEach(func() {
   140  					Ω(os.Chdir("./colonelmustard")).Should(Succeed())
   141  				})
   142  
   143  				It("returns tests in the current directory if present", func() {
   144  					suites := FindSuites([]string{}, cliConf, false)
   145  					Ω(suites).Should(ConsistOf(
   146  						TS(".", "colonelmustard", true, TestSuiteStateUncompiled),
   147  					))
   148  				})
   149  			})
   150  		})
   151  
   152  		Context("when passed args", func() {
   153  			Context("when told to recurse", func() {
   154  				BeforeEach(func() {
   155  					cliConf.Recurse = true
   156  				})
   157  
   158  				It("recurses through the passed-in directories, returning all identified tests and skipping vendored, ignored, and precompiled tests", func() {
   159  					suites := FindSuites([]string{"precompiled-dir", "colonelmustard"}, cliConf, false)
   160  					Ω(suites).Should(ConsistOf(
   161  						TS("./colonelmustard", "colonelmustard", true, TestSuiteStateUncompiled),
   162  						TS("./colonelmustard/library", "library", true, TestSuiteStateUncompiled),
   163  					))
   164  				})
   165  			})
   166  
   167  			Context("when told to recurse and there is a skip-package filter", func() {
   168  				BeforeEach(func() {
   169  					cliConf.Recurse = true
   170  					cliConf.SkipPackage = "library"
   171  				})
   172  
   173  				It("recurses through the passed-in directories, returning all identified tests and skipping vendored, ignored, and precompiled tests", func() {
   174  					suites := FindSuites([]string{"precompiled-dir", "professorplum", "colonelmustard"}, cliConf, false)
   175  					Ω(suites).Should(ConsistOf(
   176  						TS("./professorplum", "professorplum", false, TestSuiteStateUncompiled),
   177  						TS("./colonelmustard", "colonelmustard", true, TestSuiteStateUncompiled),
   178  						TS("./colonelmustard/library", "library", true, TestSuiteStateSkippedByFilter),
   179  					))
   180  				})
   181  			})
   182  
   183  			Context("when told not to recurse", func() {
   184  				BeforeEach(func() {
   185  					cliConf.Recurse = false
   186  				})
   187  
   188  				It("returns test packages at the passed in arguments", func() {
   189  					suites := FindSuites([]string{"precompiled-dir", "colonelmustard", "professorplum", "ignored"}, cliConf, false)
   190  					Ω(suites).Should(ConsistOf(
   191  						TS("./professorplum", "professorplum", false, TestSuiteStateUncompiled),
   192  						TS("./colonelmustard", "colonelmustard", true, TestSuiteStateUncompiled),
   193  					))
   194  				})
   195  			})
   196  
   197  			Context("when told not to recurse, but an arg has /...", func() {
   198  				BeforeEach(func() {
   199  					cliConf.Recurse = false
   200  				})
   201  
   202  				It("recurses through the directories it is told to recurse through, returning all identified tests and skipping vendored, ignored, and precompiled tests", func() {
   203  					suites := FindSuites([]string{"precompiled-dir", "colonelmustard/...", "professorplum/...", "ignored/..."}, cliConf, false)
   204  					Ω(suites).Should(ConsistOf(
   205  						TS("./professorplum", "professorplum", false, TestSuiteStateUncompiled),
   206  						TS("./colonelmustard", "colonelmustard", true, TestSuiteStateUncompiled),
   207  						TS("./colonelmustard/library", "library", true, TestSuiteStateUncompiled),
   208  					))
   209  				})
   210  			})
   211  
   212  			Context("when told not to recurse and there is a skip-package filter", func() {
   213  				BeforeEach(func() {
   214  					cliConf.Recurse = false
   215  					cliConf.SkipPackage = "library,plum"
   216  				})
   217  
   218  				It("returns skips packages that match", func() {
   219  					suites := FindSuites([]string{"colonelmustard", "professorplum", "colonelmustard/library"}, cliConf, false)
   220  					Ω(suites).Should(ConsistOf(
   221  						TS("./professorplum", "professorplum", false, TestSuiteStateSkippedByFilter),
   222  						TS("./colonelmustard", "colonelmustard", true, TestSuiteStateUncompiled),
   223  						TS("./colonelmustard/library", "library", true, TestSuiteStateSkippedByFilter),
   224  					))
   225  				})
   226  			})
   227  
   228  			Context("when pointed at a directory containing a precompiled test suite", func() {
   229  				It("returns nothing", func() {
   230  					suites := FindSuites([]string{"precompiled-dir"}, cliConf, false)
   231  					Ω(suites).Should(BeEmpty())
   232  				})
   233  			})
   234  
   235  			Context("when pointed at a precompiled test suite specifically", func() {
   236  				It("returns the precompiled suite", func() {
   237  					path, err := filepath.Abs("./precompiled-dir/precompiled.test")
   238  					Ω(err).ShouldNot(HaveOccurred())
   239  					suites := FindSuites([]string{"precompiled-dir/precompiled.test"}, cliConf, true)
   240  					Ω(suites).Should(ConsistOf(
   241  						PTS("./precompiled-dir", "precompiled", true, path, TestSuiteStateCompiled),
   242  					))
   243  				})
   244  			})
   245  
   246  			Context("when pointed at a precompiled test suite on windows", func() {
   247  				It("returns the precompiled suite", func() {
   248  					path, err := filepath.Abs("./precompiled-dir/windows.exe")
   249  					Ω(err).ShouldNot(HaveOccurred())
   250  					suites := FindSuites([]string{"precompiled-dir/windows.exe"}, cliConf, true)
   251  					Ω(suites).Should(ConsistOf(
   252  						PTS("./precompiled-dir", "windows", true, path, TestSuiteStateCompiled),
   253  					))
   254  
   255  					path, err = filepath.Abs("./precompiled-dir/windows.test.exe")
   256  					Ω(err).ShouldNot(HaveOccurred())
   257  					suites = FindSuites([]string{"precompiled-dir/windows.test.exe"}, cliConf, true)
   258  					Ω(suites).Should(ConsistOf(
   259  						PTS("./precompiled-dir", "windows", true, path, TestSuiteStateCompiled),
   260  					))
   261  				})
   262  			})
   263  
   264  			Context("when pointed at a fake precompiled test", func() {
   265  				It("returns nothing", func() {
   266  					suites := FindSuites([]string{"precompiled-dir/some-other-binary"}, cliConf, true)
   267  					Ω(suites).Should(BeEmpty())
   268  
   269  					suites = FindSuites([]string{"precompiled-dir/nonexecutable.test"}, cliConf, true)
   270  					Ω(suites).Should(BeEmpty())
   271  				})
   272  			})
   273  
   274  			Context("when pointed at a precompiled test suite specifically but allowPrecompiled is false", func() {
   275  				It("returns nothing", func() {
   276  					suites := FindSuites([]string{"precompiled-dir/some-other-binary"}, cliConf, false)
   277  					Ω(suites).Should(BeEmpty())
   278  				})
   279  			})
   280  		})
   281  	})
   282  
   283  	Describe("NamespacedName", func() {
   284  		It("generates a name basd on the relative path to the package", func() {
   285  			plum := TS("./professorplum", "professorplum", false, TestSuiteStateUncompiled)
   286  			library := TS("./colonelmustard/library", "library", true, TestSuiteStateUncompiled)
   287  			root := TS(".", "root", true, TestSuiteStateUncompiled)
   288  
   289  			Ω(plum.NamespacedName()).Should(Equal("professorplum"))
   290  			Ω(library.NamespacedName()).Should(Equal("colonelmustard_library"))
   291  			Ω(root.NamespacedName()).Should(Equal("root"))
   292  		})
   293  	})
   294  
   295  	Describe("TestSuiteState", func() {
   296  		Describe("Is", func() {
   297  			It("returns true if it matches one of the passed in states", func() {
   298  				Ω(TestSuiteStateCompiled.Is(TestSuiteStateUncompiled, TestSuiteStateCompiled)).Should(BeTrue())
   299  				Ω(TestSuiteStateCompiled.Is(TestSuiteStateUncompiled, TestSuiteStatePassed)).Should(BeFalse())
   300  			})
   301  		})
   302  
   303  		Describe("TestSuiteStateFailureStates", func() {
   304  			It("should enumerate the failure states", func() {
   305  				Ω(TestSuiteStateFailureStates).Should(ConsistOf(
   306  					TestSuiteStateFailed,
   307  					TestSuiteStateFailedDueToTimeout,
   308  					TestSuiteStateFailedToCompile,
   309  				))
   310  			})
   311  		})
   312  	})
   313  
   314  	Describe("TestSuites", func() {
   315  		var A, B, C, D TestSuite
   316  		var suites TestSuites
   317  		BeforeEach(func() {
   318  			A = TS("/A", "A", true, TestSuiteStateUncompiled)
   319  			B = TS("/B", "B", true, TestSuiteStateUncompiled)
   320  			C = TS("/C", "C", true, TestSuiteStateUncompiled)
   321  			D = TS("/D", "D", true, TestSuiteStateUncompiled)
   322  		})
   323  
   324  		JustBeforeEach(func() {
   325  			suites = TestSuites{A, B, C, D}
   326  		})
   327  
   328  		Describe("AnyHaveProgrammaticFocus", func() {
   329  			Context("when any suites have programmatic focus", func() {
   330  				BeforeEach(func() {
   331  					B.HasProgrammaticFocus = true
   332  				})
   333  
   334  				It("returns true", func() {
   335  					Ω(suites.AnyHaveProgrammaticFocus()).Should(BeTrue())
   336  				})
   337  			})
   338  			Context("when any suites do not have programmatic focus", func() {
   339  				It("returns false", func() {
   340  					Ω(suites.AnyHaveProgrammaticFocus()).Should(BeFalse())
   341  				})
   342  			})
   343  		})
   344  
   345  		Describe("ThatAreGinkgoSuites", func() {
   346  			BeforeEach(func() {
   347  				B.IsGinkgo = false
   348  				D.IsGinkgo = false
   349  			})
   350  			It("returns the subset that are Ginkgo suites", func() {
   351  				Ω(suites.ThatAreGinkgoSuites()).Should(Equal(TestSuites{A, C}))
   352  			})
   353  		})
   354  
   355  		Describe("CountWithState", func() {
   356  			BeforeEach(func() {
   357  				B.State = TestSuiteStateFailed
   358  				D.State = TestSuiteStateFailedToCompile
   359  			})
   360  
   361  			It("returns the number with the matching state", func() {
   362  				Ω(suites.CountWithState(TestSuiteStateFailed)).Should(Equal(1))
   363  				Ω(suites.CountWithState(TestSuiteStateFailed, TestSuiteStateFailedToCompile)).Should(Equal(2))
   364  			})
   365  		})
   366  
   367  		Describe("WithState", func() {
   368  			BeforeEach(func() {
   369  				A.State = TestSuiteStatePassed
   370  				C.State = TestSuiteStateSkippedByFilter
   371  			})
   372  
   373  			It("returns the suites matching the passed-in states", func() {
   374  				Ω(suites.WithState(TestSuiteStatePassed, TestSuiteStateSkippedByFilter)).Should(Equal(TestSuites{A, C}))
   375  			})
   376  		})
   377  
   378  		Describe("WithoutState", func() {
   379  			BeforeEach(func() {
   380  				A.State = TestSuiteStatePassed
   381  				C.State = TestSuiteStateSkippedByFilter
   382  			})
   383  
   384  			It("returns the suites _not_ matching the passed-in states", func() {
   385  				Ω(suites.WithoutState(TestSuiteStatePassed, TestSuiteStateSkippedByFilter)).Should(Equal(TestSuites{B, D}))
   386  			})
   387  		})
   388  
   389  		Describe("ShuffledCopy", func() {
   390  			It("returns a shuffled copy of the test suites", func() {
   391  				shuffled := suites.ShuffledCopy(17)
   392  				Ω(suites).Should(Equal(TestSuites{A, B, C, D}))
   393  				Ω(shuffled).Should(ConsistOf(A, B, C, D))
   394  				Ω(shuffled).ShouldNot(Equal(suites))
   395  			})
   396  		})
   397  	})
   398  })