1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
20:
21: App::uses('CakeFixtureManager', 'TestSuite/Fixture');
22: App::uses('CakeTestFixture', 'TestSuite/Fixture');
23:
24: 25: 26: 27: 28:
29: abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
30:
31: 32: 33: 34: 35:
36: public $fixtureManager = null;
37:
38: 39: 40: 41: 42: 43:
44: public $autoFixtures = true;
45:
46: 47: 48: 49: 50: 51: 52: 53: 54:
55: public $dropTables = true;
56:
57: 58: 59: 60: 61:
62: protected $_configure = array();
63:
64: 65: 66: 67: 68:
69: protected $_pathRestore = array();
70:
71: 72: 73: 74: 75: 76: 77: 78: 79:
80: public function run(PHPUnit_Framework_TestResult $result = null) {
81: if (!empty($this->fixtureManager)) {
82: $this->fixtureManager->load($this);
83: }
84: $result = parent::run($result);
85: if (!empty($this->fixtureManager)) {
86: $this->fixtureManager->unload($this);
87: }
88: return $result;
89: }
90:
91: 92: 93: 94: 95: 96:
97: public function startTest($method) {
98: }
99:
100: 101: 102: 103: 104: 105:
106: public function endTest($method) {
107: }
108:
109: 110: 111: 112: 113: 114: 115:
116: public function skipIf($shouldSkip, $message = '') {
117: if ($shouldSkip) {
118: $this->markTestSkipped($message);
119: }
120: return $shouldSkip;
121: }
122:
123: 124: 125: 126: 127: 128: 129:
130: public function setUp() {
131: parent::setUp();
132:
133: if (empty($this->_configure)) {
134: $this->_configure = Configure::read();
135: }
136: if (empty($this->_pathRestore)) {
137: $this->_pathRestore = App::paths();
138: }
139: if (class_exists('Router', false)) {
140: Router::reload();
141: }
142: }
143:
144: 145: 146: 147: 148:
149: public function tearDown() {
150: parent::tearDown();
151: App::build($this->_pathRestore, App::RESET);
152: if (class_exists('ClassRegistry', false)) {
153: ClassRegistry::flush();
154: }
155: if (!empty($this->_configure)) {
156: Configure::clear();
157: Configure::write($this->_configure);
158: }
159: if (isset($_GET['debug']) && $_GET['debug']) {
160: ob_flush();
161: }
162: }
163:
164: 165: 166: 167: 168: 169:
170: public static function date($format = 'Y-m-d H:i:s') {
171: return CakeTestSuiteDispatcher::date($format);
172: }
173:
174:
175:
176: 177: 178: 179: 180:
181: protected function assertPreConditions() {
182: parent::assertPreConditions();
183: $this->startTest($this->getName());
184: }
185:
186: 187: 188: 189: 190:
191: protected function assertPostConditions() {
192: parent::assertPostConditions();
193: $this->endTest($this->getName());
194: }
195:
196:
197:
198: 199: 200: 201: 202: 203: 204: 205: 206:
207: public function loadFixtures() {
208: if (empty($this->fixtureManager)) {
209: throw new Exception(__d('cake_dev', 'No fixture manager to load the test fixture'));
210: }
211: $args = func_get_args();
212: foreach ($args as $class) {
213: $this->fixtureManager->loadSingle($class, null, $this->dropTables);
214: }
215: }
216:
217: 218: 219: 220: 221: 222: 223: 224: 225:
226: public function assertTextNotEquals($expected, $result, $message = '') {
227: $expected = str_replace(array("\r\n", "\r"), "\n", $expected);
228: $result = str_replace(array("\r\n", "\r"), "\n", $result);
229: return $this->assertNotEquals($expected, $result, $message);
230: }
231:
232: 233: 234: 235: 236: 237: 238: 239: 240:
241: public function assertTextEquals($expected, $result, $message = '') {
242: $expected = str_replace(array("\r\n", "\r"), "\n", $expected);
243: $result = str_replace(array("\r\n", "\r"), "\n", $result);
244: return $this->assertEquals($expected, $result, $message);
245: }
246:
247: 248: 249: 250: 251: 252: 253: 254: 255:
256: public function assertTextStartsWith($prefix, $string, $message = '') {
257: $prefix = str_replace(array("\r\n", "\r"), "\n", $prefix);
258: $string = str_replace(array("\r\n", "\r"), "\n", $string);
259: return $this->assertStringStartsWith($prefix, $string, $message);
260: }
261:
262: 263: 264: 265: 266: 267: 268: 269: 270:
271: public function assertTextStartsNotWith($prefix, $string, $message = '') {
272: $prefix = str_replace(array("\r\n", "\r"), "\n", $prefix);
273: $string = str_replace(array("\r\n", "\r"), "\n", $string);
274: return $this->assertStringStartsNotWith($prefix, $string, $message);
275: }
276:
277: 278: 279: 280: 281: 282: 283: 284: 285:
286: public function assertTextEndsWith($suffix, $string, $message = '') {
287: $suffix = str_replace(array("\r\n", "\r"), "\n", $suffix);
288: $string = str_replace(array("\r\n", "\r"), "\n", $string);
289: return $this->assertStringEndsWith($suffix, $string, $message);
290: }
291:
292: 293: 294: 295: 296: 297: 298: 299: 300:
301: public function assertTextEndsNotWith($suffix, $string, $message = '') {
302: $suffix = str_replace(array("\r\n", "\r"), "\n", $suffix);
303: $string = str_replace(array("\r\n", "\r"), "\n", $string);
304: return $this->assertStringEndsNotWith($suffix, $string, $message);
305: }
306:
307: 308: 309: 310: 311: 312: 313: 314: 315: 316:
317: public function assertTextContains($needle, $haystack, $message = '', $ignoreCase = false) {
318: $needle = str_replace(array("\r\n", "\r"), "\n", $needle);
319: $haystack = str_replace(array("\r\n", "\r"), "\n", $haystack);
320: return $this->assertContains($needle, $haystack, $message, $ignoreCase);
321: }
322:
323: 324: 325: 326: 327: 328: 329: 330: 331: 332:
333: public function assertTextNotContains($needle, $haystack, $message = '', $ignoreCase = false) {
334: $needle = str_replace(array("\r\n", "\r"), "\n", $needle);
335: $haystack = str_replace(array("\r\n", "\r"), "\n", $haystack);
336: return $this->assertNotContains($needle, $haystack, $message, $ignoreCase);
337: }
338:
339: 340: 341: 342: 343: 344: 345: 346: 347: 348: 349: 350: 351: 352: 353: 354: 355: 356: 357: 358: 359: 360: 361: 362: 363: 364: 365: 366: 367: 368: 369: 370: 371:
372: public function assertTags($string, $expected, $fullDebug = false) {
373: $regex = array();
374: $normalized = array();
375: foreach ((array)$expected as $key => $val) {
376: if (!is_numeric($key)) {
377: $normalized[] = array($key => $val);
378: } else {
379: $normalized[] = $val;
380: }
381: }
382: $i = 0;
383: foreach ($normalized as $tags) {
384: if (!is_array($tags)) {
385: $tags = (string)$tags;
386: }
387: $i++;
388: if (is_string($tags) && $tags{0} === '<') {
389: $tags = array(substr($tags, 1) => array());
390: } elseif (is_string($tags)) {
391: $tagsTrimmed = preg_replace('/\s+/m', '', $tags);
392:
393: if (preg_match('/^\*?\//', $tags, $match) && $tagsTrimmed !== '//') {
394: $prefix = array(null, null);
395:
396: if ($match[0] === '*/') {
397: $prefix = array('Anything, ', '.*?');
398: }
399: $regex[] = array(
400: sprintf('%sClose %s tag', $prefix[0], substr($tags, strlen($match[0]))),
401: sprintf('%s<[\s]*\/[\s]*%s[\s]*>[\n\r]*', $prefix[1], substr($tags, strlen($match[0]))),
402: $i,
403: );
404: continue;
405: }
406: if (!empty($tags) && preg_match('/^preg\:\/(.+)\/$/i', $tags, $matches)) {
407: $tags = $matches[1];
408: $type = 'Regex matches';
409: } else {
410: $tags = preg_quote($tags, '/');
411: $type = 'Text equals';
412: }
413: $regex[] = array(
414: sprintf('%s "%s"', $type, $tags),
415: $tags,
416: $i,
417: );
418: continue;
419: }
420: foreach ($tags as $tag => $attributes) {
421: $regex[] = array(
422: sprintf('Open %s tag', $tag),
423: sprintf('[\s]*<%s', preg_quote($tag, '/')),
424: $i,
425: );
426: if ($attributes === true) {
427: $attributes = array();
428: }
429: $attrs = array();
430: $explanations = array();
431: $i = 1;
432: foreach ($attributes as $attr => $val) {
433: if (is_numeric($attr) && preg_match('/^preg\:\/(.+)\/$/i', $val, $matches)) {
434: $attrs[] = $matches[1];
435: $explanations[] = sprintf('Regex "%s" matches', $matches[1]);
436: continue;
437: } else {
438: $quotes = '["\']';
439: if (is_numeric($attr)) {
440: $attr = $val;
441: $val = '.+?';
442: $explanations[] = sprintf('Attribute "%s" present', $attr);
443: } elseif (!empty($val) && preg_match('/^preg\:\/(.+)\/$/i', $val, $matches)) {
444: $quotes = '["\']?';
445: $val = $matches[1];
446: $explanations[] = sprintf('Attribute "%s" matches "%s"', $attr, $val);
447: } else {
448: $explanations[] = sprintf('Attribute "%s" == "%s"', $attr, $val);
449: $val = preg_quote($val, '/');
450: }
451: $attrs[] = '[\s]+' . preg_quote($attr, '/') . '=' . $quotes . $val . $quotes;
452: }
453: $i++;
454: }
455: if ($attrs) {
456: $permutations = $this->_arrayPermute($attrs);
457:
458: $permutationTokens = array();
459: foreach ($permutations as $permutation) {
460: $permutationTokens[] = implode('', $permutation);
461: }
462: $regex[] = array(
463: sprintf('%s', implode(', ', $explanations)),
464: $permutationTokens,
465: $i,
466: );
467: }
468: $regex[] = array(
469: sprintf('End %s tag', $tag),
470: '[\s]*\/?[\s]*>[\n\r]*',
471: $i,
472: );
473: }
474: }
475: foreach ($regex as $i => $assertation) {
476: list($description, $expressions, $itemNum) = $assertation;
477: $matches = false;
478: foreach ((array)$expressions as $expression) {
479: if (preg_match(sprintf('/^%s/s', $expression), $string, $match)) {
480: $matches = true;
481: $string = substr($string, strlen($match[0]));
482: break;
483: }
484: }
485: if (!$matches) {
486: $this->assertTrue(false, sprintf('Item #%d / regex #%d failed: %s', $itemNum, $i, $description));
487: if ($fullDebug) {
488: debug($string, true);
489: debug($regex, true);
490: }
491: return false;
492: }
493: }
494:
495: $this->assertTrue(true, '%s');
496: return true;
497: }
498:
499: 500: 501: 502: 503: 504: 505:
506: protected function _arrayPermute($items, $perms = array()) {
507: static $permuted;
508: if (empty($perms)) {
509: $permuted = array();
510: }
511:
512: if (empty($items)) {
513: $permuted[] = $perms;
514: } else {
515: $numItems = count($items) - 1;
516: for ($i = $numItems; $i >= 0; --$i) {
517: $newItems = $items;
518: $newPerms = $perms;
519: list($tmp) = array_splice($newItems, $i, 1);
520: array_unshift($newPerms, $tmp);
521: $this->_arrayPermute($newItems, $newPerms);
522: }
523: return $permuted;
524: }
525: }
526:
527:
528:
529: 530: 531: 532: 533: 534: 535: 536: 537:
538: protected static function assertEqual($result, $expected, $message = '') {
539: return self::assertEquals($expected, $result, $message);
540: }
541:
542: 543: 544: 545: 546: 547: 548: 549:
550: protected static function assertNotEqual($result, $expected, $message = '') {
551: return self::assertNotEquals($expected, $result, $message);
552: }
553:
554: 555: 556: 557: 558: 559: 560: 561:
562: protected static function assertPattern($pattern, $string, $message = '') {
563: return self::assertRegExp($pattern, $string, $message);
564: }
565:
566: 567: 568: 569: 570: 571: 572: 573:
574: protected static function assertIdentical($actual, $expected, $message = '') {
575: return self::assertSame($expected, $actual, $message);
576: }
577:
578: 579: 580: 581: 582: 583: 584: 585:
586: protected static function assertNotIdentical($actual, $expected, $message = '') {
587: return self::assertNotSame($expected, $actual, $message);
588: }
589:
590: 591: 592: 593: 594: 595: 596: 597:
598: protected static function assertNoPattern($pattern, $string, $message = '') {
599: return self::assertNotRegExp($pattern, $string, $message);
600: }
601:
602: 603: 604:
605: protected function assertNoErrors() {
606: }
607:
608: 609: 610: 611: 612: 613: 614:
615: protected function expectError($expected = false, $message = '') {
616: if (!$expected) {
617: $expected = 'Exception';
618: }
619: $this->setExpectedException($expected, $message);
620: }
621:
622: 623: 624: 625: 626: 627: 628:
629: protected function expectException($name = 'Exception', $message = '') {
630: $this->setExpectedException($name, $message);
631: }
632:
633: 634: 635: 636: 637: 638: 639: 640:
641: protected static function assertReference(&$first, &$second, $message = '') {
642: return self::assertSame($first, $second, $message);
643: }
644:
645: 646: 647: 648: 649: 650: 651: 652:
653: protected static function assertIsA($object, $type, $message = '') {
654: return self::assertInstanceOf($type, $object, $message);
655: }
656:
657: 658: 659: 660: 661: 662: 663: 664: 665:
666: protected static function assertWithinMargin($result, $expected, $margin, $message = '') {
667: $upper = $result + $margin;
668: $lower = $result - $margin;
669: return self::assertTrue((($expected <= $upper) && ($expected >= $lower)), $message);
670: }
671:
672: 673: 674: 675: 676: 677: 678:
679: protected function skipUnless($condition, $message = '') {
680: if (!$condition) {
681: $this->markTestSkipped($message);
682: }
683: return $condition;
684: }
685:
686:
687: 688: 689: 690: 691: 692: 693: 694:
695: public function getMockForModel($model, $methods = array(), $config = null) {
696: if ($config === null) {
697: $config = ClassRegistry::config('Model');
698: }
699:
700: list($plugin, $name) = pluginSplit($model, true);
701: App::uses($name, $plugin . 'Model');
702: $config = array_merge((array)$config, array('name' => $name));
703: $mock = $this->getMock($name, $methods, array($config));
704: ClassRegistry::removeObject($name);
705: ClassRegistry::addObject($name, $mock);
706: return $mock;
707: }
708:
709: }
710: