diff options
author | Dries Buytaert <dries@buytaert.net> | 2008-04-20 18:34:43 +0000 |
---|---|---|
committer | Dries Buytaert <dries@buytaert.net> | 2008-04-20 18:34:43 +0000 |
commit | ffc0e93c4eb0555a08f0b58bed0735416e6ba41f (patch) | |
tree | 7f741d0b40124633c5b337dc7210711bfcd4b876 /modules/simpletest/exceptions.php | |
parent | af474609e3e80db9ba1d16b9ad2eae89775f51c8 (diff) | |
download | brdo-ffc0e93c4eb0555a08f0b58bed0735416e6ba41f.tar.gz brdo-ffc0e93c4eb0555a08f0b58bed0735416e6ba41f.tar.bz2 |
- Added a test framework to Drupal along with a first batch of tests for
Drupal core! This is an important milestone for the project so enable
the module and check it out ... :)
Thanks to Rok Žlender, Károly Négyesi, Jimmy Berry, Kevin Bridges, Charlie
Gordon, Douglas Hubler, Miglius Alaburda, Andy Kirkham, Dimitri13, Kieran
Lal, Moshe Weitzman, and the many other people that helped with testing
over the past years and that drove this home.
It all works but it is still rough around the edges (i.e. documentation
is still being written, the coding style is not 100% yet, a number of
tests still fail) but we spent the entire weekend working on it in Paris
and made a ton of progress. The best way to help and to get up to speed,
is to start writing and contributing some tests ... as well as fixing
some of the failures.
For those willing to help with improving the test framework, here are
some next steps and issues to resolve:
- How to best approach unit tests and mock functions?
- How to test drupal_mail() and drupal_http_request()?
- How to improve the admin UI so we have a nice progress bar?
- How best to do code coverage?
- See http://g.d.o/node/10099 for more ...
Diffstat (limited to 'modules/simpletest/exceptions.php')
-rw-r--r-- | modules/simpletest/exceptions.php | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/modules/simpletest/exceptions.php b/modules/simpletest/exceptions.php new file mode 100644 index 000000000..c79aaf318 --- /dev/null +++ b/modules/simpletest/exceptions.php @@ -0,0 +1,171 @@ +<?php +// $Id$ + +class SimpleExceptionTrappingInvoker extends SimpleInvokerDecorator { + + /** + * Stores the invoker to be wrapped. + * @param SimpleInvoker $invoker Test method runner. + */ + function SimpleExceptionTrappingInvoker($invoker) { + $this->SimpleInvokerDecorator($invoker); + } + + /** + * Invokes a test method whilst trapping expected + * exceptions. Any left over unthrown exceptions + * are then reported as failures. + * @param string $method Test method to call. + */ + function invoke($method) { + $trap = SimpleTest::getContext()->get('SimpleExceptionTrap'); + $trap->clear(); + try { + parent::invoke($method); + } + catch (Exception $exception) { + if (!$trap->isExpected($this->getTestCase(), $exception)) { + $this->getTestCase()->exception($exception); + } + $trap->clear(); + $this->_invoker->getTestCase()->tearDown(); + } + if ($message = $trap->getOutstanding()) { + $this->getTestCase()->fail($message); + } + } +} + +/** + * Tests exceptions either by type or the exact + * exception. This could be improved to accept + * a pattern expectation to test the error + * message, but that will have to come later. + * @package SimpleTest + * @subpackage UnitTester + */ +class ExceptionExpectation extends SimpleExpectation { + private$expected; + + /** + * Sets up the conditions to test against. + * If the expected value is a string, then + * it will act as a test of the class name. + * An exception as the comparison will + * trigger an identical match. Writing this + * down now makes it look doubly dumb. I hope + * come up with a better scheme later. + * @param mixed $expected A class name or an actual + * exception to compare with. + * @param string $message Message to display. + */ + function __construct($expected, $message = '%s') { + $this->expected = $expected; + parent::__construct($message); + } + + /** + * Carry out the test. + * @param Exception $compare Value to check. + * @return boolean True if matched. + */ + function test($compare) { + if (is_string($this->expected)) { + return ($compare instanceof $this->expected); + } + if (get_class($compare) != get_class($this->expected)) { + return false; + } + return $compare->getMessage() == $this->expected->getMessage(); + } + + /** + * Create the message to display describing the test. + * @param Exception $compare Exception to match. + * @return string Final message. + */ + function testMessage($compare) { + if (is_string($this->expected)) { + return "Exception [". $this->describeException($compare) ."] should be type [". $this->expected ."]"; + } + return "Exception [". $this->describeException($compare) ."] should match [". $this->describeException($this->expected) ."]"; + } + + /** + * Summary of an Exception object. + * @param Exception $compare Exception to describe. + * @return string Text description. + */ + protected function describeException($exception) { + return get_class($exception) .": ". $exception->getMessage(); + } +} + +/** + * Stores expected exceptions for when they + * get thrown. Saves the irritating try...catch + * block. + * @package SimpleTest + * @subpackage UnitTester + */ +class SimpleExceptionTrap { + private$expected; + private$message; + + /** + * Clears down the queue ready for action. + */ + function __construct() { + $this->clear(); + } + + /** + * Sets up an expectation of an exception. + * This has the effect of intercepting an + * exception that matches. + * @param SimpleExpectation $expected Expected exception to match. + * @param string $message Message to display. + * @access public + */ + function expectException($expected = false, $message = '%s') { + if ($expected === false) { + $expected = new AnythingExpectation(); + } + if (!SimpleExpectation::isExpectation($expected)) { + $expected = new ExceptionExpectation($expected); + } + $this->expected = $expected; + $this->message = $message; + } + + /** + * Compares the expected exception with any + * in the queue. Issues a pass or fail and + * returns the state of the test. + * @param SimpleTestCase $test Test case to send messages to. + * @param Exception $exception Exception to compare. + * @return boolean False on no match. + */ + function isExpected($test, $exception) { + if ($this->expected) { + return $test->assert($this->expected, $exception, $this->message); + } + return false; + } + + /** + * Tests for any left over exception. + * @return string/false The failure message or false if none. + */ + function getOutstanding() { + return sprintf($this->message, 'Failed to trap exception'); + } + + /** + * Discards the contents of the error queue. + */ + function clear() { + $this->expected = false; + $this->message = false; + } +} |