// These tests check that the foundations of gocheck are working properly. // They already assume that fundamental failing is working already, though, // since this was tested in bootstrap_test.go. Even then, some care may // still have to be taken when using external functions, since they should // of course not rely on functionality tested here. package check_test import ( "fmt" "gopkg.in/check.v1" "log" "os" "regexp" "strings" ) // ----------------------------------------------------------------------- // Foundation test suite. type FoundationS struct{} var foundationS = check.Suite(&FoundationS{}) func (s *FoundationS) TestCountSuite(c *check.C) { suitesRun += 1 } func (s *FoundationS) TestErrorf(c *check.C) { // Do not use checkState() here. It depends on Errorf() working. expectedLog := fmt.Sprintf("foundation_test.go:%d:\n"+ " c.Errorf(\"Error %%v!\", \"message\")\n"+ "... Error: Error message!\n\n", getMyLine()+1) c.Errorf("Error %v!", "message") failed := c.Failed() c.Succeed() if log := c.GetTestLog(); log != expectedLog { c.Logf("Errorf() logged %#v rather than %#v", log, expectedLog) c.Fail() } if !failed { c.Logf("Errorf() didn't put the test in a failed state") c.Fail() } } func (s *FoundationS) TestError(c *check.C) { expectedLog := fmt.Sprintf("foundation_test.go:%d:\n"+ " c\\.Error\\(\"Error \", \"message!\"\\)\n"+ "\\.\\.\\. Error: Error message!\n\n", getMyLine()+1) c.Error("Error ", "message!") checkState(c, nil, &expectedState{ name: "Error(`Error `, `message!`)", failed: true, log: expectedLog, }) } func (s *FoundationS) TestFailNow(c *check.C) { defer (func() { if !c.Failed() { c.Error("FailNow() didn't fail the test") } else { c.Succeed() if c.GetTestLog() != "" { c.Error("Something got logged:\n" + c.GetTestLog()) } } })() c.FailNow() c.Log("FailNow() didn't stop the test") } func (s *FoundationS) TestSucceedNow(c *check.C) { defer (func() { if c.Failed() { c.Error("SucceedNow() didn't succeed the test") } if c.GetTestLog() != "" { c.Error("Something got logged:\n" + c.GetTestLog()) } })() c.Fail() c.SucceedNow() c.Log("SucceedNow() didn't stop the test") } func (s *FoundationS) TestFailureHeader(c *check.C) { output := String{} failHelper := FailHelper{} check.Run(&failHelper, &check.RunConf{Output: &output}) header := fmt.Sprintf(""+ "\n-----------------------------------"+ "-----------------------------------\n"+ "FAIL: check_test.go:%d: FailHelper.TestLogAndFail\n", failHelper.testLine) if strings.Index(output.value, header) == -1 { c.Errorf(""+ "Failure didn't print a proper header.\n"+ "... Got:\n%s... Expected something with:\n%s", output.value, header) } } func (s *FoundationS) TestFatal(c *check.C) { var line int defer (func() { if !c.Failed() { c.Error("Fatal() didn't fail the test") } else { c.Succeed() expected := fmt.Sprintf("foundation_test.go:%d:\n"+ " c.Fatal(\"Die \", \"now!\")\n"+ "... Error: Die now!\n\n", line) if c.GetTestLog() != expected { c.Error("Incorrect log:", c.GetTestLog()) } } })() line = getMyLine() + 1 c.Fatal("Die ", "now!") c.Log("Fatal() didn't stop the test") } func (s *FoundationS) TestFatalf(c *check.C) { var line int defer (func() { if !c.Failed() { c.Error("Fatalf() didn't fail the test") } else { c.Succeed() expected := fmt.Sprintf("foundation_test.go:%d:\n"+ " c.Fatalf(\"Die %%s!\", \"now\")\n"+ "... Error: Die now!\n\n", line) if c.GetTestLog() != expected { c.Error("Incorrect log:", c.GetTestLog()) } } })() line = getMyLine() + 1 c.Fatalf("Die %s!", "now") c.Log("Fatalf() didn't stop the test") } func (s *FoundationS) TestCallerLoggingInsideTest(c *check.C) { log := fmt.Sprintf(""+ "foundation_test.go:%d:\n"+ " result := c.Check\\(10, check.Equals, 20\\)\n"+ "\\.\\.\\. obtained int = 10\n"+ "\\.\\.\\. expected int = 20\n\n", getMyLine()+1) result := c.Check(10, check.Equals, 20) checkState(c, result, &expectedState{ name: "Check(10, Equals, 20)", result: false, failed: true, log: log, }) } func (s *FoundationS) TestCallerLoggingInDifferentFile(c *check.C) { result, line := checkEqualWrapper(c, 10, 20) testLine := getMyLine() - 1 log := fmt.Sprintf(""+ "foundation_test.go:%d:\n"+ " result, line := checkEqualWrapper\\(c, 10, 20\\)\n"+ "check_test.go:%d:\n"+ " return c.Check\\(obtained, check.Equals, expected\\), getMyLine\\(\\)\n"+ "\\.\\.\\. obtained int = 10\n"+ "\\.\\.\\. expected int = 20\n\n", testLine, line) checkState(c, result, &expectedState{ name: "Check(10, Equals, 20)", result: false, failed: true, log: log, }) } // ----------------------------------------------------------------------- // ExpectFailure() inverts the logic of failure. type ExpectFailureSucceedHelper struct{} func (s *ExpectFailureSucceedHelper) TestSucceed(c *check.C) { c.ExpectFailure("It booms!") c.Error("Boom!") } type ExpectFailureFailHelper struct{} func (s *ExpectFailureFailHelper) TestFail(c *check.C) { c.ExpectFailure("Bug #XYZ") } func (s *FoundationS) TestExpectFailureFail(c *check.C) { helper := ExpectFailureFailHelper{} output := String{} result := check.Run(&helper, &check.RunConf{Output: &output}) expected := "" + "^\n-+\n" + "FAIL: foundation_test\\.go:[0-9]+:" + " ExpectFailureFailHelper\\.TestFail\n\n" + "\\.\\.\\. Error: Test succeeded, but was expected to fail\n" + "\\.\\.\\. Reason: Bug #XYZ\n$" matched, err := regexp.MatchString(expected, output.value) if err != nil { c.Error("Bad expression: ", expected) } else if !matched { c.Error("ExpectFailure() didn't log properly:\n", output.value) } c.Assert(result.ExpectedFailures, check.Equals, 0) } func (s *FoundationS) TestExpectFailureSucceed(c *check.C) { helper := ExpectFailureSucceedHelper{} output := String{} result := check.Run(&helper, &check.RunConf{Output: &output}) c.Assert(output.value, check.Equals, "") c.Assert(result.ExpectedFailures, check.Equals, 1) } func (s *FoundationS) TestExpectFailureSucceedVerbose(c *check.C) { helper := ExpectFailureSucceedHelper{} output := String{} result := check.Run(&helper, &check.RunConf{Output: &output, Verbose: true}) expected := "" + "FAIL EXPECTED: foundation_test\\.go:[0-9]+:" + " ExpectFailureSucceedHelper\\.TestSucceed \\(It booms!\\)\t *[.0-9]+s\n" matched, err := regexp.MatchString(expected, output.value) if err != nil { c.Error("Bad expression: ", expected) } else if !matched { c.Error("ExpectFailure() didn't log properly:\n", output.value) } c.Assert(result.ExpectedFailures, check.Equals, 1) } // ----------------------------------------------------------------------- // Skip() allows stopping a test without positive/negative results. type SkipTestHelper struct{} func (s *SkipTestHelper) TestFail(c *check.C) { c.Skip("Wrong platform or whatever") c.Error("Boom!") } func (s *FoundationS) TestSkip(c *check.C) { helper := SkipTestHelper{} output := String{} check.Run(&helper, &check.RunConf{Output: &output}) if output.value != "" { c.Error("Skip() logged something:\n", output.value) } } func (s *FoundationS) TestSkipVerbose(c *check.C) { helper := SkipTestHelper{} output := String{} check.Run(&helper, &check.RunConf{Output: &output, Verbose: true}) expected := "SKIP: foundation_test\\.go:[0-9]+: SkipTestHelper\\.TestFail" + " \\(Wrong platform or whatever\\)" matched, err := regexp.MatchString(expected, output.value) if err != nil { c.Error("Bad expression: ", expected) } else if !matched { c.Error("Skip() didn't log properly:\n", output.value) } } // ----------------------------------------------------------------------- // Check minimum *log.Logger interface provided by *check.C. type minLogger interface { Output(calldepth int, s string) error } func (s *BootstrapS) TestMinLogger(c *check.C) { var logger minLogger logger = log.New(os.Stderr, "", 0) logger = c logger.Output(0, "Hello there") expected := `\[LOG\] [0-9]+:[0-9][0-9]\.[0-9][0-9][0-9] +Hello there\n` output := c.GetTestLog() c.Assert(output, check.Matches, expected) } // ----------------------------------------------------------------------- // Ensure that suites with embedded types are working fine, including the // the workaround for issue 906. type EmbeddedInternalS struct { called bool } type EmbeddedS struct { EmbeddedInternalS } var embeddedS = check.Suite(&EmbeddedS{}) func (s *EmbeddedS) TestCountSuite(c *check.C) { suitesRun += 1 } func (s *EmbeddedInternalS) TestMethod(c *check.C) { c.Error("TestMethod() of the embedded type was called!?") } func (s *EmbeddedS) TestMethod(c *check.C) { // http://code.google.com/p/go/issues/detail?id=906 c.Check(s.called, check.Equals, false) // Go issue 906 is affecting the runner? s.called = true }