1<?php 2/** 3 * base include file for SimpleTest 4 * @package SimpleTest 5 * @subpackage UnitTester 6 * @version $Id$ 7 */ 8 9/**#@+ 10 * include other SimpleTest class files 11 */ 12require_once(dirname(__FILE__) . '/test_case.php'); 13require_once(dirname(__FILE__) . '/dumper.php'); 14/**#@-*/ 15 16/** 17 * Standard unit test class for day to day testing 18 * of PHP code XP style. Adds some useful standard 19 * assertions. 20 * @package SimpleTest 21 * @subpackage UnitTester 22 */ 23class UnitTestCase extends SimpleTestCase { 24 25 /** 26 * Creates an empty test case. Should be subclassed 27 * with test methods for a functional test case. 28 * @param string $label Name of test case. Will use 29 * the class name if none specified. 30 * @access public 31 */ 32 function __construct($label = false) { 33 if (! $label) { 34 $label = get_class($this); 35 } 36 parent::__construct($label); 37 } 38 39 /** 40 * Called from within the test methods to register 41 * passes and failures. 42 * @param boolean $result Pass on true. 43 * @param string $message Message to display describing 44 * the test state. 45 * @return boolean True on pass 46 * @access public 47 */ 48 function assertTrue($result, $message = '%s') { 49 return $this->assert(new TrueExpectation(), $result, $message); 50 } 51 52 /** 53 * Will be true on false and vice versa. False 54 * is the PHP definition of false, so that null, 55 * empty strings, zero and an empty array all count 56 * as false. 57 * @param boolean $result Pass on false. 58 * @param string $message Message to display. 59 * @return boolean True on pass 60 * @access public 61 */ 62 function assertFalse($result, $message = '%s') { 63 return $this->assert(new FalseExpectation(), $result, $message); 64 } 65 66 /** 67 * Will be true if the value is null. 68 * @param null $value Supposedly null value. 69 * @param string $message Message to display. 70 * @return boolean True on pass 71 * @access public 72 */ 73 function assertNull($value, $message = '%s') { 74 $dumper = new SimpleDumper(); 75 $message = sprintf( 76 $message, 77 '[' . $dumper->describeValue($value) . '] should be null'); 78 return $this->assertTrue(! isset($value), $message); 79 } 80 81 /** 82 * Will be true if the value is set. 83 * @param mixed $value Supposedly set value. 84 * @param string $message Message to display. 85 * @return boolean True on pass. 86 * @access public 87 */ 88 function assertNotNull($value, $message = '%s') { 89 $dumper = new SimpleDumper(); 90 $message = sprintf( 91 $message, 92 '[' . $dumper->describeValue($value) . '] should not be null'); 93 return $this->assertTrue(isset($value), $message); 94 } 95 96 /** 97 * Type and class test. Will pass if class 98 * matches the type name or is a subclass or 99 * if not an object, but the type is correct. 100 * @param mixed $object Object to test. 101 * @param string $type Type name as string. 102 * @param string $message Message to display. 103 * @return boolean True on pass. 104 * @access public 105 */ 106 function assertIsA($object, $type, $message = '%s') { 107 return $this->assert( 108 new IsAExpectation($type), 109 $object, 110 $message); 111 } 112 113 /** 114 * Type and class mismatch test. Will pass if class 115 * name or underling type does not match the one 116 * specified. 117 * @param mixed $object Object to test. 118 * @param string $type Type name as string. 119 * @param string $message Message to display. 120 * @return boolean True on pass. 121 * @access public 122 */ 123 function assertNotA($object, $type, $message = '%s') { 124 return $this->assert( 125 new NotAExpectation($type), 126 $object, 127 $message); 128 } 129 130 /** 131 * Will trigger a pass if the two parameters have 132 * the same value only. Otherwise a fail. 133 * @param mixed $first Value to compare. 134 * @param mixed $second Value to compare. 135 * @param string $message Message to display. 136 * @return boolean True on pass 137 * @access public 138 */ 139 function assertEqual($first, $second, $message = '%s') { 140 return $this->assert( 141 new EqualExpectation($first), 142 $second, 143 $message); 144 } 145 146 /** 147 * Will trigger a pass if the two parameters have 148 * a different value. Otherwise a fail. 149 * @param mixed $first Value to compare. 150 * @param mixed $second Value to compare. 151 * @param string $message Message to display. 152 * @return boolean True on pass 153 * @access public 154 */ 155 function assertNotEqual($first, $second, $message = '%s') { 156 return $this->assert( 157 new NotEqualExpectation($first), 158 $second, 159 $message); 160 } 161 162 /** 163 * Will trigger a pass if the if the first parameter 164 * is near enough to the second by the margin. 165 * @param mixed $first Value to compare. 166 * @param mixed $second Value to compare. 167 * @param mixed $margin Fuzziness of match. 168 * @param string $message Message to display. 169 * @return boolean True on pass 170 * @access public 171 */ 172 function assertWithinMargin($first, $second, $margin, $message = '%s') { 173 return $this->assert( 174 new WithinMarginExpectation($first, $margin), 175 $second, 176 $message); 177 } 178 179 /** 180 * Will trigger a pass if the two parameters differ 181 * by more than the margin. 182 * @param mixed $first Value to compare. 183 * @param mixed $second Value to compare. 184 * @param mixed $margin Fuzziness of match. 185 * @param string $message Message to display. 186 * @return boolean True on pass 187 * @access public 188 */ 189 function assertOutsideMargin($first, $second, $margin, $message = '%s') { 190 return $this->assert( 191 new OutsideMarginExpectation($first, $margin), 192 $second, 193 $message); 194 } 195 196 /** 197 * Will trigger a pass if the two parameters have 198 * the same value and same type. Otherwise a fail. 199 * @param mixed $first Value to compare. 200 * @param mixed $second Value to compare. 201 * @param string $message Message to display. 202 * @return boolean True on pass 203 * @access public 204 */ 205 function assertIdentical($first, $second, $message = '%s') { 206 return $this->assert( 207 new IdenticalExpectation($first), 208 $second, 209 $message); 210 } 211 212 /** 213 * Will trigger a pass if the two parameters have 214 * the different value or different type. 215 * @param mixed $first Value to compare. 216 * @param mixed $second Value to compare. 217 * @param string $message Message to display. 218 * @return boolean True on pass 219 * @access public 220 */ 221 function assertNotIdentical($first, $second, $message = '%s') { 222 return $this->assert( 223 new NotIdenticalExpectation($first), 224 $second, 225 $message); 226 } 227 228 /** 229 * Will trigger a pass if both parameters refer 230 * to the same object or value. Fail otherwise. 231 * This will cause problems testing objects under 232 * E_STRICT. 233 * TODO: Replace with expectation. 234 * @param mixed $first Reference to check. 235 * @param mixed $second Hopefully the same variable. 236 * @param string $message Message to display. 237 * @return boolean True on pass 238 * @access public 239 */ 240 function assertReference(&$first, &$second, $message = '%s') { 241 $dumper = new SimpleDumper(); 242 $message = sprintf( 243 $message, 244 '[' . $dumper->describeValue($first) . 245 '] and [' . $dumper->describeValue($second) . 246 '] should reference the same object'); 247 return $this->assertTrue( 248 SimpleTestCompatibility::isReference($first, $second), 249 $message); 250 } 251 252 /** 253 * Will trigger a pass if both parameters refer 254 * to the same object. Fail otherwise. This has 255 * the same semantics at the PHPUnit assertSame. 256 * That is, if values are passed in it has roughly 257 * the same affect as assertIdentical. 258 * TODO: Replace with expectation. 259 * @param mixed $first Object reference to check. 260 * @param mixed $second Hopefully the same object. 261 * @param string $message Message to display. 262 * @return boolean True on pass 263 * @access public 264 */ 265 function assertSame($first, $second, $message = '%s') { 266 $dumper = new SimpleDumper(); 267 $message = sprintf( 268 $message, 269 '[' . $dumper->describeValue($first) . 270 '] and [' . $dumper->describeValue($second) . 271 '] should reference the same object'); 272 return $this->assertTrue($first === $second, $message); 273 } 274 275 /** 276 * Will trigger a pass if both parameters refer 277 * to different objects. Fail otherwise. The objects 278 * have to be identical though. 279 * @param mixed $first Object reference to check. 280 * @param mixed $second Hopefully not the same object. 281 * @param string $message Message to display. 282 * @return boolean True on pass 283 * @access public 284 */ 285 function assertClone($first, $second, $message = '%s') { 286 $dumper = new SimpleDumper(); 287 $message = sprintf( 288 $message, 289 '[' . $dumper->describeValue($first) . 290 '] and [' . $dumper->describeValue($second) . 291 '] should not be the same object'); 292 $identical = new IdenticalExpectation($first); 293 return $this->assertTrue( 294 $identical->test($second) && ! ($first === $second), 295 $message); 296 } 297 298 /** 299 * Will trigger a pass if both parameters refer 300 * to different variables. Fail otherwise. The objects 301 * have to be identical references though. 302 * This will fail under E_STRICT with objects. Use 303 * assertClone() for this. 304 * @param mixed $first Object reference to check. 305 * @param mixed $second Hopefully not the same object. 306 * @param string $message Message to display. 307 * @return boolean True on pass 308 * @access public 309 */ 310 function assertCopy(&$first, &$second, $message = "%s") { 311 $dumper = new SimpleDumper(); 312 $message = sprintf( 313 $message, 314 "[" . $dumper->describeValue($first) . 315 "] and [" . $dumper->describeValue($second) . 316 "] should not be the same object"); 317 return $this->assertFalse( 318 SimpleTestCompatibility::isReference($first, $second), 319 $message); 320 } 321 322 /** 323 * Will trigger a pass if the Perl regex pattern 324 * is found in the subject. Fail otherwise. 325 * @param string $pattern Perl regex to look for including 326 * the regex delimiters. 327 * @param string $subject String to search in. 328 * @param string $message Message to display. 329 * @return boolean True on pass 330 * @access public 331 */ 332 function assertPattern($pattern, $subject, $message = '%s') { 333 return $this->assert( 334 new PatternExpectation($pattern), 335 $subject, 336 $message); 337 } 338 339 /** 340 * Will trigger a pass if the perl regex pattern 341 * is not present in subject. Fail if found. 342 * @param string $pattern Perl regex to look for including 343 * the regex delimiters. 344 * @param string $subject String to search in. 345 * @param string $message Message to display. 346 * @return boolean True on pass 347 * @access public 348 */ 349 function assertNoPattern($pattern, $subject, $message = '%s') { 350 return $this->assert( 351 new NoPatternExpectation($pattern), 352 $subject, 353 $message); 354 } 355 356 /** 357 * Prepares for an error. If the error mismatches it 358 * passes through, otherwise it is swallowed. Any 359 * left over errors trigger failures. 360 * @param SimpleExpectation/string $expected The error to match. 361 * @param string $message Message on failure. 362 * @access public 363 */ 364 function expectError($expected = false, $message = '%s') { 365 $queue = SimpleTest::getContext()->get('SimpleErrorQueue'); 366 $queue->expectError($this->coerceExpectation($expected), $message); 367 } 368 369 /** 370 * Prepares for an exception. If the error mismatches it 371 * passes through, otherwise it is swallowed. Any 372 * left over errors trigger failures. 373 * @param SimpleExpectation/Exception $expected The error to match. 374 * @param string $message Message on failure. 375 * @access public 376 */ 377 function expectException($expected = false, $message = '%s') { 378 $queue = SimpleTest::getContext()->get('SimpleExceptionTrap'); 379 $line = $this->getAssertionLine(); 380 $queue->expectException($expected, $message . $line); 381 } 382 383 /** 384 * Tells SimpleTest to ignore an upcoming exception as not relevant 385 * to the current test. It doesn't affect the test, whether thrown or 386 * not. 387 * @param SimpleExpectation/Exception $ignored The error to ignore. 388 * @access public 389 */ 390 function ignoreException($ignored = false) { 391 SimpleTest::getContext()->get('SimpleExceptionTrap')->ignoreException($ignored); 392 } 393 394 /** 395 * Creates an equality expectation if the 396 * object/value is not already some type 397 * of expectation. 398 * @param mixed $expected Expected value. 399 * @return SimpleExpectation Expectation object. 400 * @access private 401 */ 402 protected function coerceExpectation($expected) { 403 if ($expected == false) { 404 return new TrueExpectation(); 405 } 406 if (SimpleTestCompatibility::isA($expected, 'SimpleExpectation')) { 407 return $expected; 408 } 409 return new EqualExpectation( 410 is_string($expected) ? str_replace('%', '%%', $expected) : $expected); 411 } 412} 413?>