1// These tests check that the foundations of gocheck are working properly. 2// They already assume that fundamental failing is working already, though, 3// since this was tested in bootstrap_test.go. Even then, some care may 4// still have to be taken when using external functions, since they should 5// of course not rely on functionality tested here. 6 7package check_test 8 9import ( 10 "fmt" 11 "gopkg.in/check.v1" 12 "log" 13 "os" 14 "regexp" 15 "strings" 16) 17 18// ----------------------------------------------------------------------- 19// Foundation test suite. 20 21type FoundationS struct{} 22 23var foundationS = check.Suite(&FoundationS{}) 24 25func (s *FoundationS) TestCountSuite(c *check.C) { 26 suitesRun += 1 27} 28 29func (s *FoundationS) TestErrorf(c *check.C) { 30 // Do not use checkState() here. It depends on Errorf() working. 31 expectedLog := fmt.Sprintf("foundation_test.go:%d:\n"+ 32 " c.Errorf(\"Error %%v!\", \"message\")\n"+ 33 "... Error: Error message!\n\n", 34 getMyLine()+1) 35 c.Errorf("Error %v!", "message") 36 failed := c.Failed() 37 c.Succeed() 38 if log := c.GetTestLog(); log != expectedLog { 39 c.Logf("Errorf() logged %#v rather than %#v", log, expectedLog) 40 c.Fail() 41 } 42 if !failed { 43 c.Logf("Errorf() didn't put the test in a failed state") 44 c.Fail() 45 } 46} 47 48func (s *FoundationS) TestError(c *check.C) { 49 expectedLog := fmt.Sprintf("foundation_test.go:%d:\n"+ 50 " c\\.Error\\(\"Error \", \"message!\"\\)\n"+ 51 "\\.\\.\\. Error: Error message!\n\n", 52 getMyLine()+1) 53 c.Error("Error ", "message!") 54 checkState(c, nil, 55 &expectedState{ 56 name: "Error(`Error `, `message!`)", 57 failed: true, 58 log: expectedLog, 59 }) 60} 61 62func (s *FoundationS) TestFailNow(c *check.C) { 63 defer (func() { 64 if !c.Failed() { 65 c.Error("FailNow() didn't fail the test") 66 } else { 67 c.Succeed() 68 if c.GetTestLog() != "" { 69 c.Error("Something got logged:\n" + c.GetTestLog()) 70 } 71 } 72 })() 73 74 c.FailNow() 75 c.Log("FailNow() didn't stop the test") 76} 77 78func (s *FoundationS) TestSucceedNow(c *check.C) { 79 defer (func() { 80 if c.Failed() { 81 c.Error("SucceedNow() didn't succeed the test") 82 } 83 if c.GetTestLog() != "" { 84 c.Error("Something got logged:\n" + c.GetTestLog()) 85 } 86 })() 87 88 c.Fail() 89 c.SucceedNow() 90 c.Log("SucceedNow() didn't stop the test") 91} 92 93func (s *FoundationS) TestFailureHeader(c *check.C) { 94 output := String{} 95 failHelper := FailHelper{} 96 check.Run(&failHelper, &check.RunConf{Output: &output}) 97 header := fmt.Sprintf(""+ 98 "\n-----------------------------------"+ 99 "-----------------------------------\n"+ 100 "FAIL: check_test.go:%d: FailHelper.TestLogAndFail\n", 101 failHelper.testLine) 102 if strings.Index(output.value, header) == -1 { 103 c.Errorf(""+ 104 "Failure didn't print a proper header.\n"+ 105 "... Got:\n%s... Expected something with:\n%s", 106 output.value, header) 107 } 108} 109 110func (s *FoundationS) TestFatal(c *check.C) { 111 var line int 112 defer (func() { 113 if !c.Failed() { 114 c.Error("Fatal() didn't fail the test") 115 } else { 116 c.Succeed() 117 expected := fmt.Sprintf("foundation_test.go:%d:\n"+ 118 " c.Fatal(\"Die \", \"now!\")\n"+ 119 "... Error: Die now!\n\n", 120 line) 121 if c.GetTestLog() != expected { 122 c.Error("Incorrect log:", c.GetTestLog()) 123 } 124 } 125 })() 126 127 line = getMyLine() + 1 128 c.Fatal("Die ", "now!") 129 c.Log("Fatal() didn't stop the test") 130} 131 132func (s *FoundationS) TestFatalf(c *check.C) { 133 var line int 134 defer (func() { 135 if !c.Failed() { 136 c.Error("Fatalf() didn't fail the test") 137 } else { 138 c.Succeed() 139 expected := fmt.Sprintf("foundation_test.go:%d:\n"+ 140 " c.Fatalf(\"Die %%s!\", \"now\")\n"+ 141 "... Error: Die now!\n\n", 142 line) 143 if c.GetTestLog() != expected { 144 c.Error("Incorrect log:", c.GetTestLog()) 145 } 146 } 147 })() 148 149 line = getMyLine() + 1 150 c.Fatalf("Die %s!", "now") 151 c.Log("Fatalf() didn't stop the test") 152} 153 154func (s *FoundationS) TestCallerLoggingInsideTest(c *check.C) { 155 log := fmt.Sprintf(""+ 156 "foundation_test.go:%d:\n"+ 157 " result := c.Check\\(10, check.Equals, 20\\)\n"+ 158 "\\.\\.\\. obtained int = 10\n"+ 159 "\\.\\.\\. expected int = 20\n\n", 160 getMyLine()+1) 161 result := c.Check(10, check.Equals, 20) 162 checkState(c, result, 163 &expectedState{ 164 name: "Check(10, Equals, 20)", 165 result: false, 166 failed: true, 167 log: log, 168 }) 169} 170 171func (s *FoundationS) TestCallerLoggingInDifferentFile(c *check.C) { 172 result, line := checkEqualWrapper(c, 10, 20) 173 testLine := getMyLine() - 1 174 log := fmt.Sprintf(""+ 175 "foundation_test.go:%d:\n"+ 176 " result, line := checkEqualWrapper\\(c, 10, 20\\)\n"+ 177 "check_test.go:%d:\n"+ 178 " return c.Check\\(obtained, check.Equals, expected\\), getMyLine\\(\\)\n"+ 179 "\\.\\.\\. obtained int = 10\n"+ 180 "\\.\\.\\. expected int = 20\n\n", 181 testLine, line) 182 checkState(c, result, 183 &expectedState{ 184 name: "Check(10, Equals, 20)", 185 result: false, 186 failed: true, 187 log: log, 188 }) 189} 190 191// ----------------------------------------------------------------------- 192// ExpectFailure() inverts the logic of failure. 193 194type ExpectFailureSucceedHelper struct{} 195 196func (s *ExpectFailureSucceedHelper) TestSucceed(c *check.C) { 197 c.ExpectFailure("It booms!") 198 c.Error("Boom!") 199} 200 201type ExpectFailureFailHelper struct{} 202 203func (s *ExpectFailureFailHelper) TestFail(c *check.C) { 204 c.ExpectFailure("Bug #XYZ") 205} 206 207func (s *FoundationS) TestExpectFailureFail(c *check.C) { 208 helper := ExpectFailureFailHelper{} 209 output := String{} 210 result := check.Run(&helper, &check.RunConf{Output: &output}) 211 212 expected := "" + 213 "^\n-+\n" + 214 "FAIL: foundation_test\\.go:[0-9]+:" + 215 " ExpectFailureFailHelper\\.TestFail\n\n" + 216 "\\.\\.\\. Error: Test succeeded, but was expected to fail\n" + 217 "\\.\\.\\. Reason: Bug #XYZ\n$" 218 219 matched, err := regexp.MatchString(expected, output.value) 220 if err != nil { 221 c.Error("Bad expression: ", expected) 222 } else if !matched { 223 c.Error("ExpectFailure() didn't log properly:\n", output.value) 224 } 225 226 c.Assert(result.ExpectedFailures, check.Equals, 0) 227} 228 229func (s *FoundationS) TestExpectFailureSucceed(c *check.C) { 230 helper := ExpectFailureSucceedHelper{} 231 output := String{} 232 result := check.Run(&helper, &check.RunConf{Output: &output}) 233 234 c.Assert(output.value, check.Equals, "") 235 c.Assert(result.ExpectedFailures, check.Equals, 1) 236} 237 238func (s *FoundationS) TestExpectFailureSucceedVerbose(c *check.C) { 239 helper := ExpectFailureSucceedHelper{} 240 output := String{} 241 result := check.Run(&helper, &check.RunConf{Output: &output, Verbose: true}) 242 243 expected := "" + 244 "FAIL EXPECTED: foundation_test\\.go:[0-9]+:" + 245 " ExpectFailureSucceedHelper\\.TestSucceed \\(It booms!\\)\t *[.0-9]+s\n" 246 247 matched, err := regexp.MatchString(expected, output.value) 248 if err != nil { 249 c.Error("Bad expression: ", expected) 250 } else if !matched { 251 c.Error("ExpectFailure() didn't log properly:\n", output.value) 252 } 253 254 c.Assert(result.ExpectedFailures, check.Equals, 1) 255} 256 257// ----------------------------------------------------------------------- 258// Skip() allows stopping a test without positive/negative results. 259 260type SkipTestHelper struct{} 261 262func (s *SkipTestHelper) TestFail(c *check.C) { 263 c.Skip("Wrong platform or whatever") 264 c.Error("Boom!") 265} 266 267func (s *FoundationS) TestSkip(c *check.C) { 268 helper := SkipTestHelper{} 269 output := String{} 270 check.Run(&helper, &check.RunConf{Output: &output}) 271 272 if output.value != "" { 273 c.Error("Skip() logged something:\n", output.value) 274 } 275} 276 277func (s *FoundationS) TestSkipVerbose(c *check.C) { 278 helper := SkipTestHelper{} 279 output := String{} 280 check.Run(&helper, &check.RunConf{Output: &output, Verbose: true}) 281 282 expected := "SKIP: foundation_test\\.go:[0-9]+: SkipTestHelper\\.TestFail" + 283 " \\(Wrong platform or whatever\\)" 284 matched, err := regexp.MatchString(expected, output.value) 285 if err != nil { 286 c.Error("Bad expression: ", expected) 287 } else if !matched { 288 c.Error("Skip() didn't log properly:\n", output.value) 289 } 290} 291 292// ----------------------------------------------------------------------- 293// Check minimum *log.Logger interface provided by *check.C. 294 295type minLogger interface { 296 Output(calldepth int, s string) error 297} 298 299func (s *BootstrapS) TestMinLogger(c *check.C) { 300 var logger minLogger 301 logger = log.New(os.Stderr, "", 0) 302 logger = c 303 logger.Output(0, "Hello there") 304 expected := `\[LOG\] [0-9]+:[0-9][0-9]\.[0-9][0-9][0-9] +Hello there\n` 305 output := c.GetTestLog() 306 c.Assert(output, check.Matches, expected) 307} 308 309// ----------------------------------------------------------------------- 310// Ensure that suites with embedded types are working fine, including the 311// the workaround for issue 906. 312 313type EmbeddedInternalS struct { 314 called bool 315} 316 317type EmbeddedS struct { 318 EmbeddedInternalS 319} 320 321var embeddedS = check.Suite(&EmbeddedS{}) 322 323func (s *EmbeddedS) TestCountSuite(c *check.C) { 324 suitesRun += 1 325} 326 327func (s *EmbeddedInternalS) TestMethod(c *check.C) { 328 c.Error("TestMethod() of the embedded type was called!?") 329} 330 331func (s *EmbeddedS) TestMethod(c *check.C) { 332 // http://code.google.com/p/go/issues/detail?id=906 333 c.Check(s.called, check.Equals, false) // Go issue 906 is affecting the runner? 334 s.called = true 335} 336