launchpad.net/gocheck@v0.0.0-20140225173054-000000000087/foundation_test.go (about)

     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  
     7  package gocheck_test
     8  
     9  import (
    10  	"fmt"
    11  	"launchpad.net/gocheck"
    12  	"log"
    13  	"os"
    14  	"regexp"
    15  	"strings"
    16  )
    17  
    18  // -----------------------------------------------------------------------
    19  // Foundation test suite.
    20  
    21  type FoundationS struct{}
    22  
    23  var foundationS = gocheck.Suite(&FoundationS{})
    24  
    25  func (s *FoundationS) TestCountSuite(c *gocheck.C) {
    26  	suitesRun += 1
    27  }
    28  
    29  func (s *FoundationS) TestErrorf(c *gocheck.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  
    48  func (s *FoundationS) TestError(c *gocheck.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  
    62  func (s *FoundationS) TestFailNow(c *gocheck.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  
    78  func (s *FoundationS) TestSucceedNow(c *gocheck.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  
    93  func (s *FoundationS) TestFailureHeader(c *gocheck.C) {
    94  	output := String{}
    95  	failHelper := FailHelper{}
    96  	gocheck.Run(&failHelper, &gocheck.RunConf{Output: &output})
    97  	header := fmt.Sprintf(""+
    98  		"\n-----------------------------------"+
    99  		"-----------------------------------\n"+
   100  		"FAIL: gocheck_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  
   110  func (s *FoundationS) TestFatal(c *gocheck.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  
   132  func (s *FoundationS) TestFatalf(c *gocheck.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  
   154  func (s *FoundationS) TestCallerLoggingInsideTest(c *gocheck.C) {
   155  	log := fmt.Sprintf(""+
   156  		"foundation_test.go:%d:\n"+
   157  		"    result := c.Check\\(10, gocheck.Equals, 20\\)\n"+
   158  		"\\.\\.\\. obtained int = 10\n"+
   159  		"\\.\\.\\. expected int = 20\n\n",
   160  		getMyLine()+1)
   161  	result := c.Check(10, gocheck.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  
   171  func (s *FoundationS) TestCallerLoggingInDifferentFile(c *gocheck.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  		"gocheck_test.go:%d:\n"+
   178  		"    return c.Check\\(obtained, gocheck.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  
   194  type ExpectFailureSucceedHelper struct{}
   195  
   196  func (s *ExpectFailureSucceedHelper) TestSucceed(c *gocheck.C) {
   197  	c.ExpectFailure("It booms!")
   198  	c.Error("Boom!")
   199  }
   200  
   201  type ExpectFailureFailHelper struct{}
   202  
   203  func (s *ExpectFailureFailHelper) TestFail(c *gocheck.C) {
   204  	c.ExpectFailure("Bug #XYZ")
   205  }
   206  
   207  func (s *FoundationS) TestExpectFailureFail(c *gocheck.C) {
   208  	helper := ExpectFailureFailHelper{}
   209  	output := String{}
   210  	result := gocheck.Run(&helper, &gocheck.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, gocheck.Equals, 0)
   227  }
   228  
   229  func (s *FoundationS) TestExpectFailureSucceed(c *gocheck.C) {
   230  	helper := ExpectFailureSucceedHelper{}
   231  	output := String{}
   232  	result := gocheck.Run(&helper, &gocheck.RunConf{Output: &output})
   233  
   234  	c.Assert(output.value, gocheck.Equals, "")
   235  	c.Assert(result.ExpectedFailures, gocheck.Equals, 1)
   236  }
   237  
   238  func (s *FoundationS) TestExpectFailureSucceedVerbose(c *gocheck.C) {
   239  	helper := ExpectFailureSucceedHelper{}
   240  	output := String{}
   241  	result := gocheck.Run(&helper, &gocheck.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, gocheck.Equals, 1)
   255  }
   256  
   257  // -----------------------------------------------------------------------
   258  // Skip() allows stopping a test without positive/negative results.
   259  
   260  type SkipTestHelper struct{}
   261  
   262  func (s *SkipTestHelper) TestFail(c *gocheck.C) {
   263  	c.Skip("Wrong platform or whatever")
   264  	c.Error("Boom!")
   265  }
   266  
   267  func (s *FoundationS) TestSkip(c *gocheck.C) {
   268  	helper := SkipTestHelper{}
   269  	output := String{}
   270  	gocheck.Run(&helper, &gocheck.RunConf{Output: &output})
   271  
   272  	if output.value != "" {
   273  		c.Error("Skip() logged something:\n", output.value)
   274  	}
   275  }
   276  
   277  func (s *FoundationS) TestSkipVerbose(c *gocheck.C) {
   278  	helper := SkipTestHelper{}
   279  	output := String{}
   280  	gocheck.Run(&helper, &gocheck.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 *gocheck.C.
   294  
   295  type minLogger interface {
   296  	Output(calldepth int, s string) error
   297  }
   298  
   299  func (s *BootstrapS) TestMinLogger(c *gocheck.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, gocheck.Matches, expected)
   307  }
   308  
   309  // -----------------------------------------------------------------------
   310  // Ensure that suites with embedded types are working fine, including the
   311  // the workaround for issue 906.
   312  
   313  type EmbeddedInternalS struct {
   314  	called bool
   315  }
   316  
   317  type EmbeddedS struct {
   318  	EmbeddedInternalS
   319  }
   320  
   321  var embeddedS = gocheck.Suite(&EmbeddedS{})
   322  
   323  func (s *EmbeddedS) TestCountSuite(c *gocheck.C) {
   324  	suitesRun += 1
   325  }
   326  
   327  func (s *EmbeddedInternalS) TestMethod(c *gocheck.C) {
   328  	c.Error("TestMethod() of the embedded type was called!?")
   329  }
   330  
   331  func (s *EmbeddedS) TestMethod(c *gocheck.C) {
   332  	// http://code.google.com/p/go/issues/detail?id=906
   333  	c.Check(s.called, gocheck.Equals, false) // Go issue 906 is affecting the runner?
   334  	s.called = true
   335  }