launchpad.net/gocheck@v0.0.0-20140225173054-000000000087/helpers_test.go (about) 1 // These tests verify the inner workings of the helper methods associated 2 // with gocheck.T. 3 4 package gocheck_test 5 6 import ( 7 "launchpad.net/gocheck" 8 "os" 9 "reflect" 10 "runtime" 11 "sync" 12 ) 13 14 var helpersS = gocheck.Suite(&HelpersS{}) 15 16 type HelpersS struct{} 17 18 func (s *HelpersS) TestCountSuite(c *gocheck.C) { 19 suitesRun += 1 20 } 21 22 // ----------------------------------------------------------------------- 23 // Fake checker and bug info to verify the behavior of Assert() and Check(). 24 25 type MyChecker struct { 26 info *gocheck.CheckerInfo 27 params []interface{} 28 names []string 29 result bool 30 error string 31 } 32 33 func (checker *MyChecker) Info() *gocheck.CheckerInfo { 34 if checker.info == nil { 35 return &gocheck.CheckerInfo{Name: "MyChecker", Params: []string{"myobtained", "myexpected"}} 36 } 37 return checker.info 38 } 39 40 func (checker *MyChecker) Check(params []interface{}, names []string) (bool, string) { 41 rparams := checker.params 42 rnames := checker.names 43 checker.params = append([]interface{}{}, params...) 44 checker.names = append([]string{}, names...) 45 if rparams != nil { 46 copy(params, rparams) 47 } 48 if rnames != nil { 49 copy(names, rnames) 50 } 51 return checker.result, checker.error 52 } 53 54 type myCommentType string 55 56 func (c myCommentType) CheckCommentString() string { 57 return string(c) 58 } 59 60 func myComment(s string) myCommentType { 61 return myCommentType(s) 62 } 63 64 // ----------------------------------------------------------------------- 65 // Ensure a real checker actually works fine. 66 67 func (s *HelpersS) TestCheckerInterface(c *gocheck.C) { 68 testHelperSuccess(c, "Check(1, Equals, 1)", true, func() interface{} { 69 return c.Check(1, gocheck.Equals, 1) 70 }) 71 } 72 73 // ----------------------------------------------------------------------- 74 // Tests for Check(), mostly the same as for Assert() following these. 75 76 func (s *HelpersS) TestCheckSucceedWithExpected(c *gocheck.C) { 77 checker := &MyChecker{result: true} 78 testHelperSuccess(c, "Check(1, checker, 2)", true, func() interface{} { 79 return c.Check(1, checker, 2) 80 }) 81 if !reflect.DeepEqual(checker.params, []interface{}{1, 2}) { 82 c.Fatalf("Bad params for check: %#v", checker.params) 83 } 84 } 85 86 func (s *HelpersS) TestCheckSucceedWithoutExpected(c *gocheck.C) { 87 checker := &MyChecker{result: true, info: &gocheck.CheckerInfo{Params: []string{"myvalue"}}} 88 testHelperSuccess(c, "Check(1, checker)", true, func() interface{} { 89 return c.Check(1, checker) 90 }) 91 if !reflect.DeepEqual(checker.params, []interface{}{1}) { 92 c.Fatalf("Bad params for check: %#v", checker.params) 93 } 94 } 95 96 func (s *HelpersS) TestCheckFailWithExpected(c *gocheck.C) { 97 checker := &MyChecker{result: false} 98 log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + 99 " return c\\.Check\\(1, checker, 2\\)\n" + 100 "\\.+ myobtained int = 1\n" + 101 "\\.+ myexpected int = 2\n\n" 102 testHelperFailure(c, "Check(1, checker, 2)", false, false, log, 103 func() interface{} { 104 return c.Check(1, checker, 2) 105 }) 106 } 107 108 func (s *HelpersS) TestCheckFailWithExpectedAndComment(c *gocheck.C) { 109 checker := &MyChecker{result: false} 110 log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + 111 " return c\\.Check\\(1, checker, 2, myComment\\(\"Hello world!\"\\)\\)\n" + 112 "\\.+ myobtained int = 1\n" + 113 "\\.+ myexpected int = 2\n" + 114 "\\.+ Hello world!\n\n" 115 testHelperFailure(c, "Check(1, checker, 2, msg)", false, false, log, 116 func() interface{} { 117 return c.Check(1, checker, 2, myComment("Hello world!")) 118 }) 119 } 120 121 func (s *HelpersS) TestCheckFailWithExpectedAndStaticComment(c *gocheck.C) { 122 checker := &MyChecker{result: false} 123 log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + 124 " // Nice leading comment\\.\n" + 125 " return c\\.Check\\(1, checker, 2\\) // Hello there\n" + 126 "\\.+ myobtained int = 1\n" + 127 "\\.+ myexpected int = 2\n\n" 128 testHelperFailure(c, "Check(1, checker, 2, msg)", false, false, log, 129 func() interface{} { 130 // Nice leading comment. 131 return c.Check(1, checker, 2) // Hello there 132 }) 133 } 134 135 func (s *HelpersS) TestCheckFailWithoutExpected(c *gocheck.C) { 136 checker := &MyChecker{result: false, info: &gocheck.CheckerInfo{Params: []string{"myvalue"}}} 137 log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + 138 " return c\\.Check\\(1, checker\\)\n" + 139 "\\.+ myvalue int = 1\n\n" 140 testHelperFailure(c, "Check(1, checker)", false, false, log, 141 func() interface{} { 142 return c.Check(1, checker) 143 }) 144 } 145 146 func (s *HelpersS) TestCheckFailWithoutExpectedAndMessage(c *gocheck.C) { 147 checker := &MyChecker{result: false, info: &gocheck.CheckerInfo{Params: []string{"myvalue"}}} 148 log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + 149 " return c\\.Check\\(1, checker, myComment\\(\"Hello world!\"\\)\\)\n" + 150 "\\.+ myvalue int = 1\n" + 151 "\\.+ Hello world!\n\n" 152 testHelperFailure(c, "Check(1, checker, msg)", false, false, log, 153 func() interface{} { 154 return c.Check(1, checker, myComment("Hello world!")) 155 }) 156 } 157 158 func (s *HelpersS) TestCheckWithMissingExpected(c *gocheck.C) { 159 checker := &MyChecker{result: true} 160 log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + 161 " return c\\.Check\\(1, checker\\)\n" + 162 "\\.+ Check\\(myobtained, MyChecker, myexpected\\):\n" + 163 "\\.+ Wrong number of parameters for MyChecker: " + 164 "want 3, got 2\n\n" 165 testHelperFailure(c, "Check(1, checker, !?)", false, false, log, 166 func() interface{} { 167 return c.Check(1, checker) 168 }) 169 } 170 171 func (s *HelpersS) TestCheckWithTooManyExpected(c *gocheck.C) { 172 checker := &MyChecker{result: true} 173 log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + 174 " return c\\.Check\\(1, checker, 2, 3\\)\n" + 175 "\\.+ Check\\(myobtained, MyChecker, myexpected\\):\n" + 176 "\\.+ Wrong number of parameters for MyChecker: " + 177 "want 3, got 4\n\n" 178 testHelperFailure(c, "Check(1, checker, 2, 3)", false, false, log, 179 func() interface{} { 180 return c.Check(1, checker, 2, 3) 181 }) 182 } 183 184 func (s *HelpersS) TestCheckWithError(c *gocheck.C) { 185 checker := &MyChecker{result: false, error: "Some not so cool data provided!"} 186 log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + 187 " return c\\.Check\\(1, checker, 2\\)\n" + 188 "\\.+ myobtained int = 1\n" + 189 "\\.+ myexpected int = 2\n" + 190 "\\.+ Some not so cool data provided!\n\n" 191 testHelperFailure(c, "Check(1, checker, 2)", false, false, log, 192 func() interface{} { 193 return c.Check(1, checker, 2) 194 }) 195 } 196 197 func (s *HelpersS) TestCheckWithNilChecker(c *gocheck.C) { 198 log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + 199 " return c\\.Check\\(1, nil\\)\n" + 200 "\\.+ Check\\(obtained, nil!\\?, \\.\\.\\.\\):\n" + 201 "\\.+ Oops\\.\\. you've provided a nil checker!\n\n" 202 testHelperFailure(c, "Check(obtained, nil)", false, false, log, 203 func() interface{} { 204 return c.Check(1, nil) 205 }) 206 } 207 208 func (s *HelpersS) TestCheckWithParamsAndNamesMutation(c *gocheck.C) { 209 checker := &MyChecker{result: false, params: []interface{}{3, 4}, names: []string{"newobtained", "newexpected"}} 210 log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + 211 " return c\\.Check\\(1, checker, 2\\)\n" + 212 "\\.+ newobtained int = 3\n" + 213 "\\.+ newexpected int = 4\n\n" 214 testHelperFailure(c, "Check(1, checker, 2) with mutation", false, false, log, 215 func() interface{} { 216 return c.Check(1, checker, 2) 217 }) 218 } 219 220 // ----------------------------------------------------------------------- 221 // Tests for Assert(), mostly the same as for Check() above. 222 223 func (s *HelpersS) TestAssertSucceedWithExpected(c *gocheck.C) { 224 checker := &MyChecker{result: true} 225 testHelperSuccess(c, "Assert(1, checker, 2)", nil, func() interface{} { 226 c.Assert(1, checker, 2) 227 return nil 228 }) 229 if !reflect.DeepEqual(checker.params, []interface{}{1, 2}) { 230 c.Fatalf("Bad params for check: %#v", checker.params) 231 } 232 } 233 234 func (s *HelpersS) TestAssertSucceedWithoutExpected(c *gocheck.C) { 235 checker := &MyChecker{result: true, info: &gocheck.CheckerInfo{Params: []string{"myvalue"}}} 236 testHelperSuccess(c, "Assert(1, checker)", nil, func() interface{} { 237 c.Assert(1, checker) 238 return nil 239 }) 240 if !reflect.DeepEqual(checker.params, []interface{}{1}) { 241 c.Fatalf("Bad params for check: %#v", checker.params) 242 } 243 } 244 245 func (s *HelpersS) TestAssertFailWithExpected(c *gocheck.C) { 246 checker := &MyChecker{result: false} 247 log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + 248 " c\\.Assert\\(1, checker, 2\\)\n" + 249 "\\.+ myobtained int = 1\n" + 250 "\\.+ myexpected int = 2\n\n" 251 testHelperFailure(c, "Assert(1, checker, 2)", nil, true, log, 252 func() interface{} { 253 c.Assert(1, checker, 2) 254 return nil 255 }) 256 } 257 258 func (s *HelpersS) TestAssertFailWithExpectedAndMessage(c *gocheck.C) { 259 checker := &MyChecker{result: false} 260 log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + 261 " c\\.Assert\\(1, checker, 2, myComment\\(\"Hello world!\"\\)\\)\n" + 262 "\\.+ myobtained int = 1\n" + 263 "\\.+ myexpected int = 2\n" + 264 "\\.+ Hello world!\n\n" 265 testHelperFailure(c, "Assert(1, checker, 2, msg)", nil, true, log, 266 func() interface{} { 267 c.Assert(1, checker, 2, myComment("Hello world!")) 268 return nil 269 }) 270 } 271 272 func (s *HelpersS) TestAssertFailWithoutExpected(c *gocheck.C) { 273 checker := &MyChecker{result: false, info: &gocheck.CheckerInfo{Params: []string{"myvalue"}}} 274 log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + 275 " c\\.Assert\\(1, checker\\)\n" + 276 "\\.+ myvalue int = 1\n\n" 277 testHelperFailure(c, "Assert(1, checker)", nil, true, log, 278 func() interface{} { 279 c.Assert(1, checker) 280 return nil 281 }) 282 } 283 284 func (s *HelpersS) TestAssertFailWithoutExpectedAndMessage(c *gocheck.C) { 285 checker := &MyChecker{result: false, info: &gocheck.CheckerInfo{Params: []string{"myvalue"}}} 286 log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + 287 " c\\.Assert\\(1, checker, myComment\\(\"Hello world!\"\\)\\)\n" + 288 "\\.+ myvalue int = 1\n" + 289 "\\.+ Hello world!\n\n" 290 testHelperFailure(c, "Assert(1, checker, msg)", nil, true, log, 291 func() interface{} { 292 c.Assert(1, checker, myComment("Hello world!")) 293 return nil 294 }) 295 } 296 297 func (s *HelpersS) TestAssertWithMissingExpected(c *gocheck.C) { 298 checker := &MyChecker{result: true} 299 log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + 300 " c\\.Assert\\(1, checker\\)\n" + 301 "\\.+ Assert\\(myobtained, MyChecker, myexpected\\):\n" + 302 "\\.+ Wrong number of parameters for MyChecker: " + 303 "want 3, got 2\n\n" 304 testHelperFailure(c, "Assert(1, checker, !?)", nil, true, log, 305 func() interface{} { 306 c.Assert(1, checker) 307 return nil 308 }) 309 } 310 311 func (s *HelpersS) TestAssertWithError(c *gocheck.C) { 312 checker := &MyChecker{result: false, error: "Some not so cool data provided!"} 313 log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + 314 " c\\.Assert\\(1, checker, 2\\)\n" + 315 "\\.+ myobtained int = 1\n" + 316 "\\.+ myexpected int = 2\n" + 317 "\\.+ Some not so cool data provided!\n\n" 318 testHelperFailure(c, "Assert(1, checker, 2)", nil, true, log, 319 func() interface{} { 320 c.Assert(1, checker, 2) 321 return nil 322 }) 323 } 324 325 func (s *HelpersS) TestAssertWithNilChecker(c *gocheck.C) { 326 log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + 327 " c\\.Assert\\(1, nil\\)\n" + 328 "\\.+ Assert\\(obtained, nil!\\?, \\.\\.\\.\\):\n" + 329 "\\.+ Oops\\.\\. you've provided a nil checker!\n\n" 330 testHelperFailure(c, "Assert(obtained, nil)", nil, true, log, 331 func() interface{} { 332 c.Assert(1, nil) 333 return nil 334 }) 335 } 336 337 // ----------------------------------------------------------------------- 338 // Ensure that values logged work properly in some interesting cases. 339 340 func (s *HelpersS) TestValueLoggingWithArrays(c *gocheck.C) { 341 checker := &MyChecker{result: false} 342 log := "(?s)helpers_test.go:[0-9]+:.*\nhelpers_test.go:[0-9]+:\n" + 343 " return c\\.Check\\(\\[\\]byte{1, 2}, checker, \\[\\]byte{1, 3}\\)\n" + 344 "\\.+ myobtained \\[\\]uint8 = \\[\\]byte{0x1, 0x2}\n" + 345 "\\.+ myexpected \\[\\]uint8 = \\[\\]byte{0x1, 0x3}\n\n" 346 testHelperFailure(c, "Check([]byte{1}, chk, []byte{3})", false, false, log, 347 func() interface{} { 348 return c.Check([]byte{1, 2}, checker, []byte{1, 3}) 349 }) 350 } 351 352 func (s *HelpersS) TestValueLoggingWithMultiLine(c *gocheck.C) { 353 checker := &MyChecker{result: false} 354 log := "(?s)helpers_test.go:[0-9]+:.*\nhelpers_test.go:[0-9]+:\n" + 355 " return c\\.Check\\(\"a\\\\nb\\\\n\", checker, \"a\\\\nb\\\\nc\"\\)\n" + 356 "\\.+ myobtained string = \"\" \\+\n" + 357 "\\.+ \"a\\\\n\" \\+\n" + 358 "\\.+ \"b\\\\n\"\n" + 359 "\\.+ myexpected string = \"\" \\+\n" + 360 "\\.+ \"a\\\\n\" \\+\n" + 361 "\\.+ \"b\\\\n\" \\+\n" + 362 "\\.+ \"c\"\n\n" 363 testHelperFailure(c, `Check("a\nb\n", chk, "a\nb\nc")`, false, false, log, 364 func() interface{} { 365 return c.Check("a\nb\n", checker, "a\nb\nc") 366 }) 367 } 368 369 func (s *HelpersS) TestValueLoggingWithMultiLineException(c *gocheck.C) { 370 // If the newline is at the end of the string, don't log as multi-line. 371 checker := &MyChecker{result: false} 372 log := "(?s)helpers_test.go:[0-9]+:.*\nhelpers_test.go:[0-9]+:\n" + 373 " return c\\.Check\\(\"a b\\\\n\", checker, \"a\\\\nb\"\\)\n" + 374 "\\.+ myobtained string = \"a b\\\\n\"\n" + 375 "\\.+ myexpected string = \"\" \\+\n" + 376 "\\.+ \"a\\\\n\" \\+\n" + 377 "\\.+ \"b\"\n\n" 378 testHelperFailure(c, `Check("a b\n", chk, "a\nb")`, false, false, log, 379 func() interface{} { 380 return c.Check("a b\n", checker, "a\nb") 381 }) 382 } 383 384 // ----------------------------------------------------------------------- 385 // MakeDir() tests. 386 387 type MkDirHelper struct { 388 path1 string 389 path2 string 390 isDir1 bool 391 isDir2 bool 392 isDir3 bool 393 isDir4 bool 394 } 395 396 func (s *MkDirHelper) SetUpSuite(c *gocheck.C) { 397 s.path1 = c.MkDir() 398 s.isDir1 = isDir(s.path1) 399 } 400 401 func (s *MkDirHelper) Test(c *gocheck.C) { 402 s.path2 = c.MkDir() 403 s.isDir2 = isDir(s.path2) 404 } 405 406 func (s *MkDirHelper) TearDownSuite(c *gocheck.C) { 407 s.isDir3 = isDir(s.path1) 408 s.isDir4 = isDir(s.path2) 409 } 410 411 func (s *HelpersS) TestMkDir(c *gocheck.C) { 412 helper := MkDirHelper{} 413 output := String{} 414 gocheck.Run(&helper, &gocheck.RunConf{Output: &output}) 415 c.Assert(output.value, gocheck.Equals, "") 416 c.Check(helper.isDir1, gocheck.Equals, true) 417 c.Check(helper.isDir2, gocheck.Equals, true) 418 c.Check(helper.isDir3, gocheck.Equals, true) 419 c.Check(helper.isDir4, gocheck.Equals, true) 420 c.Check(helper.path1, gocheck.Not(gocheck.Equals), 421 helper.path2) 422 c.Check(isDir(helper.path1), gocheck.Equals, false) 423 c.Check(isDir(helper.path2), gocheck.Equals, false) 424 } 425 426 func isDir(path string) bool { 427 if stat, err := os.Stat(path); err == nil { 428 return stat.IsDir() 429 } 430 return false 431 } 432 433 // Concurrent logging should not corrupt the underling buffer. 434 // Use go test -race to detect the race in this test. 435 func (s *HelpersS) TestConcurrentLogging(c *gocheck.C) { 436 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(runtime.NumCPU())) 437 var start, stop sync.WaitGroup 438 start.Add(1) 439 for i, n := 0, runtime.NumCPU()*2; i < n; i++ { 440 stop.Add(1) 441 go func(i int) { 442 start.Wait() 443 for j := 0; j < 30; j++ { 444 c.Logf("Worker %d: line %d", i, j) 445 } 446 stop.Done() 447 }(i) 448 } 449 start.Done() 450 stop.Wait() 451 } 452 453 // ----------------------------------------------------------------------- 454 // A couple of helper functions to test helper functions. :-) 455 456 func testHelperSuccess(c *gocheck.C, name string, expectedResult interface{}, closure func() interface{}) { 457 var result interface{} 458 defer (func() { 459 if err := recover(); err != nil { 460 panic(err) 461 } 462 checkState(c, result, 463 &expectedState{ 464 name: name, 465 result: expectedResult, 466 failed: false, 467 log: "", 468 }) 469 })() 470 result = closure() 471 } 472 473 func testHelperFailure(c *gocheck.C, name string, expectedResult interface{}, shouldStop bool, log string, closure func() interface{}) { 474 var result interface{} 475 defer (func() { 476 if err := recover(); err != nil { 477 panic(err) 478 } 479 checkState(c, result, 480 &expectedState{ 481 name: name, 482 result: expectedResult, 483 failed: true, 484 log: log, 485 }) 486 })() 487 result = closure() 488 if shouldStop { 489 c.Logf("%s didn't stop when it should", name) 490 } 491 }