Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
13532 anikendra 1
<?php
2
/**
3
 * CakeTestCase file
4
 *
5
 * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
6
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
7
 *
8
 * Licensed under The MIT License
9
 * For full copyright and license information, please see the LICENSE.txt
10
 * Redistributions of files must retain the above copyright notice
11
 *
12
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
13
 * @link          http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
14
 * @package       Cake.TestSuite
15
 * @since         CakePHP(tm) v 1.2.0.4667
16
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
 */
18
 
19
App::uses('CakeFixtureManager', 'TestSuite/Fixture');
20
App::uses('CakeTestFixture', 'TestSuite/Fixture');
21
 
22
/**
23
 * CakeTestCase class
24
 *
25
 * @package       Cake.TestSuite
26
 */
27
abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
28
 
29
/**
30
 * The class responsible for managing the creation, loading and removing of fixtures
31
 *
32
 * @var CakeFixtureManager
33
 */
34
	public $fixtureManager = null;
35
 
36
/**
37
 * By default, all fixtures attached to this class will be truncated and reloaded after each test.
38
 * Set this to false to handle manually
39
 *
40
 * @var array
41
 */
42
	public $autoFixtures = true;
43
 
44
/**
45
 * Control table create/drops on each test method.
46
 *
47
 * Set this to false to avoid tables to be dropped if they already exist
48
 * between each test method. Tables will still be dropped at the
49
 * end of each test runner execution.
50
 *
51
 * @var boolean
52
 */
53
	public $dropTables = true;
54
 
55
/**
56
 * Configure values to restore at end of test.
57
 *
58
 * @var array
59
 */
60
	protected $_configure = array();
61
 
62
/**
63
 * Path settings to restore at the end of the test.
64
 *
65
 * @var array
66
 */
67
	protected $_pathRestore = array();
68
 
69
/**
70
 * Runs the test case and collects the results in a TestResult object.
71
 * If no TestResult object is passed a new one will be created.
72
 * This method is run for each test method in this class
73
 *
74
 * @param PHPUnit_Framework_TestResult $result
75
 * @return PHPUnit_Framework_TestResult
76
 * @throws InvalidArgumentException
77
 */
78
	public function run(PHPUnit_Framework_TestResult $result = null) {
79
		if (!empty($this->fixtureManager)) {
80
			$this->fixtureManager->load($this);
81
		}
82
		$result = parent::run($result);
83
		if (!empty($this->fixtureManager)) {
84
			$this->fixtureManager->unload($this);
85
		}
86
		return $result;
87
	}
88
 
89
/**
90
 * Called when a test case method is about to start (to be overridden when needed.)
91
 *
92
 * @param string $method Test method about to get executed.
93
 * @return void
94
 */
95
	public function startTest($method) {
96
	}
97
 
98
/**
99
 * Called when a test case method has been executed (to be overridden when needed.)
100
 *
101
 * @param string $method Test method about that was executed.
102
 * @return void
103
 */
104
	public function endTest($method) {
105
	}
106
 
107
/**
108
 * Overrides SimpleTestCase::skipIf to provide a boolean return value
109
 *
110
 * @param boolean $shouldSkip
111
 * @param string $message
112
 * @return boolean
113
 */
114
	public function skipIf($shouldSkip, $message = '') {
115
		if ($shouldSkip) {
116
			$this->markTestSkipped($message);
117
		}
118
		return $shouldSkip;
119
	}
120
 
121
/**
122
 * Setup the test case, backup the static object values so they can be restored.
123
 * Specifically backs up the contents of Configure and paths in App if they have
124
 * not already been backed up.
125
 *
126
 * @return void
127
 */
128
	public function setUp() {
129
		parent::setUp();
130
 
131
		if (empty($this->_configure)) {
132
			$this->_configure = Configure::read();
133
		}
134
		if (empty($this->_pathRestore)) {
135
			$this->_pathRestore = App::paths();
136
		}
137
		if (class_exists('Router', false)) {
138
			Router::reload();
139
		}
140
	}
141
 
142
/**
143
 * teardown any static object changes and restore them.
144
 *
145
 * @return void
146
 */
147
	public function tearDown() {
148
		parent::tearDown();
149
		App::build($this->_pathRestore, App::RESET);
150
		if (class_exists('ClassRegistry', false)) {
151
			ClassRegistry::flush();
152
		}
153
		if (!empty($this->_configure)) {
154
			Configure::clear();
155
			Configure::write($this->_configure);
156
		}
157
		if (isset($_GET['debug']) && $_GET['debug']) {
158
			ob_flush();
159
		}
160
	}
161
 
162
/**
163
 * See CakeTestSuiteDispatcher::date()
164
 *
165
 * @param string $format format to be used.
166
 * @return string
167
 */
168
	public static function date($format = 'Y-m-d H:i:s') {
169
		return CakeTestSuiteDispatcher::date($format);
170
	}
171
 
172
// @codingStandardsIgnoreStart PHPUnit overrides don't match CakePHP
173
 
174
/**
175
 * Announces the start of a test.
176
 *
177
 * @return void
178
 */
179
	protected function assertPreConditions() {
180
		parent::assertPreConditions();
181
		$this->startTest($this->getName());
182
	}
183
 
184
/**
185
 * Announces the end of a test.
186
 *
187
 * @return void
188
 */
189
	protected function assertPostConditions() {
190
		parent::assertPostConditions();
191
		$this->endTest($this->getName());
192
	}
193
 
194
// @codingStandardsIgnoreEnd
195
 
196
/**
197
 * Chooses which fixtures to load for a given test
198
 *
199
 * @param string $fixture Each parameter is a model name that corresponds to a
200
 *                        fixture, i.e. 'Post', 'Author', etc.
201
 * @return void
202
 * @see CakeTestCase::$autoFixtures
203
 * @throws Exception when no fixture manager is available.
204
 */
205
	public function loadFixtures() {
206
		if (empty($this->fixtureManager)) {
207
			throw new Exception(__d('cake_dev', 'No fixture manager to load the test fixture'));
208
		}
209
		$args = func_get_args();
210
		foreach ($args as $class) {
211
			$this->fixtureManager->loadSingle($class, null, $this->dropTables);
212
		}
213
	}
214
 
215
/**
216
 * Assert text equality, ignoring differences in newlines.
217
 * Helpful for doing cross platform tests of blocks of text.
218
 *
219
 * @param string $expected The expected value.
220
 * @param string $result The actual value.
221
 * @param message The message to use for failure.
222
 * @return boolean
223
 */
224
	public function assertTextNotEquals($expected, $result, $message = '') {
225
		$expected = str_replace(array("\r\n", "\r"), "\n", $expected);
226
		$result = str_replace(array("\r\n", "\r"), "\n", $result);
227
		return $this->assertNotEquals($expected, $result, $message);
228
	}
229
 
230
/**
231
 * Assert text equality, ignoring differences in newlines.
232
 * Helpful for doing cross platform tests of blocks of text.
233
 *
234
 * @param string $expected The expected value.
235
 * @param string $result The actual value.
236
 * @param message The message to use for failure.
237
 * @return boolean
238
 */
239
	public function assertTextEquals($expected, $result, $message = '') {
240
		$expected = str_replace(array("\r\n", "\r"), "\n", $expected);
241
		$result = str_replace(array("\r\n", "\r"), "\n", $result);
242
		return $this->assertEquals($expected, $result, $message);
243
	}
244
 
245
/**
246
 * Asserts that a string starts with a given prefix, ignoring differences in newlines.
247
 * Helpful for doing cross platform tests of blocks of text.
248
 *
249
 * @param string $prefix
250
 * @param string $string
251
 * @param string $message
252
 * @return boolean
253
 */
254
	public function assertTextStartsWith($prefix, $string, $message = '') {
255
		$prefix = str_replace(array("\r\n", "\r"), "\n", $prefix);
256
		$string = str_replace(array("\r\n", "\r"), "\n", $string);
257
		return $this->assertStringStartsWith($prefix, $string, $message);
258
	}
259
 
260
/**
261
 * Asserts that a string starts not with a given prefix, ignoring differences in newlines.
262
 * Helpful for doing cross platform tests of blocks of text.
263
 *
264
 * @param string $prefix
265
 * @param string $string
266
 * @param string $message
267
 * @return boolean
268
 */
269
	public function assertTextStartsNotWith($prefix, $string, $message = '') {
270
		$prefix = str_replace(array("\r\n", "\r"), "\n", $prefix);
271
		$string = str_replace(array("\r\n", "\r"), "\n", $string);
272
		return $this->assertStringStartsNotWith($prefix, $string, $message);
273
	}
274
 
275
/**
276
 * Asserts that a string ends with a given prefix, ignoring differences in newlines.
277
 * Helpful for doing cross platform tests of blocks of text.
278
 *
279
 * @param string $suffix
280
 * @param string $string
281
 * @param string $message
282
 * @return boolean
283
 */
284
	public function assertTextEndsWith($suffix, $string, $message = '') {
285
		$suffix = str_replace(array("\r\n", "\r"), "\n", $suffix);
286
		$string = str_replace(array("\r\n", "\r"), "\n", $string);
287
		return $this->assertStringEndsWith($suffix, $string, $message);
288
	}
289
 
290
/**
291
 * Asserts that a string ends not with a given prefix, ignoring differences in newlines.
292
 * Helpful for doing cross platform tests of blocks of text.
293
 *
294
 * @param string $suffix
295
 * @param string $string
296
 * @param string $message
297
 * @return boolean
298
 */
299
	public function assertTextEndsNotWith($suffix, $string, $message = '') {
300
		$suffix = str_replace(array("\r\n", "\r"), "\n", $suffix);
301
		$string = str_replace(array("\r\n", "\r"), "\n", $string);
302
		return $this->assertStringEndsNotWith($suffix, $string, $message);
303
	}
304
 
305
/**
306
 * Assert that a string contains another string, ignoring differences in newlines.
307
 * Helpful for doing cross platform tests of blocks of text.
308
 *
309
 * @param string $needle
310
 * @param string $haystack
311
 * @param string $message
312
 * @param boolean $ignoreCase
313
 * @return boolean
314
 */
315
	public function assertTextContains($needle, $haystack, $message = '', $ignoreCase = false) {
316
		$needle = str_replace(array("\r\n", "\r"), "\n", $needle);
317
		$haystack = str_replace(array("\r\n", "\r"), "\n", $haystack);
318
		return $this->assertContains($needle, $haystack, $message, $ignoreCase);
319
	}
320
 
321
/**
322
 * Assert that a text doesn't contain another text, ignoring differences in newlines.
323
 * Helpful for doing cross platform tests of blocks of text.
324
 *
325
 * @param string $needle
326
 * @param string $haystack
327
 * @param string $message
328
 * @param boolean $ignoreCase
329
 * @return boolean
330
 */
331
	public function assertTextNotContains($needle, $haystack, $message = '', $ignoreCase = false) {
332
		$needle = str_replace(array("\r\n", "\r"), "\n", $needle);
333
		$haystack = str_replace(array("\r\n", "\r"), "\n", $haystack);
334
		return $this->assertNotContains($needle, $haystack, $message, $ignoreCase);
335
	}
336
 
337
/**
338
 * Takes an array $expected and generates a regex from it to match the provided $string.
339
 * Samples for $expected:
340
 *
341
 * Checks for an input tag with a name attribute (contains any non-empty value) and an id
342
 * attribute that contains 'my-input':
343
 * 	array('input' => array('name', 'id' => 'my-input'))
344
 *
345
 * Checks for two p elements with some text in them:
346
 * 	array(
347
 * 		array('p' => true),
348
 * 		'textA',
349
 * 		'/p',
350
 * 		array('p' => true),
351
 * 		'textB',
352
 * 		'/p'
353
 *	)
354
 *
355
 * You can also specify a pattern expression as part of the attribute values, or the tag
356
 * being defined, if you prepend the value with preg: and enclose it with slashes, like so:
357
 *	array(
358
 *  	array('input' => array('name', 'id' => 'preg:/FieldName\d+/')),
359
 *  	'preg:/My\s+field/'
360
 *	)
361
 *
362
 * Important: This function is very forgiving about whitespace and also accepts any
363
 * permutation of attribute order. It will also allow whitespace between specified tags.
364
 *
365
 * @param string $string An HTML/XHTML/XML string
366
 * @param array $expected An array, see above
367
 * @param string $message SimpleTest failure output string
368
 * @return boolean
369
 */
370
	public function assertTags($string, $expected, $fullDebug = false) {
371
		$regex = array();
372
		$normalized = array();
373
		foreach ((array)$expected as $key => $val) {
374
			if (!is_numeric($key)) {
375
				$normalized[] = array($key => $val);
376
			} else {
377
				$normalized[] = $val;
378
			}
379
		}
380
		$i = 0;
381
		foreach ($normalized as $tags) {
382
			if (!is_array($tags)) {
383
				$tags = (string)$tags;
384
			}
385
			$i++;
386
			if (is_string($tags) && $tags{0} === '<') {
387
				$tags = array(substr($tags, 1) => array());
388
			} elseif (is_string($tags)) {
389
				$tagsTrimmed = preg_replace('/\s+/m', '', $tags);
390
 
391
				if (preg_match('/^\*?\//', $tags, $match) && $tagsTrimmed !== '//') {
392
					$prefix = array(null, null);
393
 
394
					if ($match[0] === '*/') {
395
						$prefix = array('Anything, ', '.*?');
396
					}
397
					$regex[] = array(
398
						sprintf('%sClose %s tag', $prefix[0], substr($tags, strlen($match[0]))),
399
						sprintf('%s<[\s]*\/[\s]*%s[\s]*>[\n\r]*', $prefix[1], substr($tags, strlen($match[0]))),
400
						$i,
401
					);
402
					continue;
403
				}
404
				if (!empty($tags) && preg_match('/^preg\:\/(.+)\/$/i', $tags, $matches)) {
405
					$tags = $matches[1];
406
					$type = 'Regex matches';
407
				} else {
408
					$tags = preg_quote($tags, '/');
409
					$type = 'Text equals';
410
				}
411
				$regex[] = array(
412
					sprintf('%s "%s"', $type, $tags),
413
					$tags,
414
					$i,
415
				);
416
				continue;
417
			}
418
			foreach ($tags as $tag => $attributes) {
419
				$regex[] = array(
420
					sprintf('Open %s tag', $tag),
421
					sprintf('[\s]*<%s', preg_quote($tag, '/')),
422
					$i,
423
				);
424
				if ($attributes === true) {
425
					$attributes = array();
426
				}
427
				$attrs = array();
428
				$explanations = array();
429
				$i = 1;
430
				foreach ($attributes as $attr => $val) {
431
					if (is_numeric($attr) && preg_match('/^preg\:\/(.+)\/$/i', $val, $matches)) {
432
						$attrs[] = $matches[1];
433
						$explanations[] = sprintf('Regex "%s" matches', $matches[1]);
434
						continue;
435
					} else {
436
						$quotes = '["\']';
437
						if (is_numeric($attr)) {
438
							$attr = $val;
439
							$val = '.+?';
440
							$explanations[] = sprintf('Attribute "%s" present', $attr);
441
						} elseif (!empty($val) && preg_match('/^preg\:\/(.+)\/$/i', $val, $matches)) {
442
							$quotes = '["\']?';
443
							$val = $matches[1];
444
							$explanations[] = sprintf('Attribute "%s" matches "%s"', $attr, $val);
445
						} else {
446
							$explanations[] = sprintf('Attribute "%s" == "%s"', $attr, $val);
447
							$val = preg_quote($val, '/');
448
						}
449
						$attrs[] = '[\s]+' . preg_quote($attr, '/') . '=' . $quotes . $val . $quotes;
450
					}
451
					$i++;
452
				}
453
				if ($attrs) {
454
					$permutations = $this->_arrayPermute($attrs);
455
 
456
					$permutationTokens = array();
457
					foreach ($permutations as $permutation) {
458
						$permutationTokens[] = implode('', $permutation);
459
					}
460
					$regex[] = array(
461
						sprintf('%s', implode(', ', $explanations)),
462
						$permutationTokens,
463
						$i,
464
					);
465
				}
466
				$regex[] = array(
467
					sprintf('End %s tag', $tag),
468
					'[\s]*\/?[\s]*>[\n\r]*',
469
					$i,
470
				);
471
			}
472
		}
473
		foreach ($regex as $i => $assertation) {
474
			list($description, $expressions, $itemNum) = $assertation;
475
			$matches = false;
476
			foreach ((array)$expressions as $expression) {
477
				if (preg_match(sprintf('/^%s/s', $expression), $string, $match)) {
478
					$matches = true;
479
					$string = substr($string, strlen($match[0]));
480
					break;
481
				}
482
			}
483
			if (!$matches) {
484
				$this->assertTrue(false, sprintf('Item #%d / regex #%d failed: %s', $itemNum, $i, $description));
485
				if ($fullDebug) {
486
					debug($string, true);
487
					debug($regex, true);
488
				}
489
				return false;
490
			}
491
		}
492
 
493
		$this->assertTrue(true, '%s');
494
		return true;
495
	}
496
 
497
/**
498
 * Generates all permutation of an array $items and returns them in a new array.
499
 *
500
 * @param array $items An array of items
501
 * @param array $perms
502
 * @return array
503
 */
504
	protected function _arrayPermute($items, $perms = array()) {
505
		static $permuted;
506
		if (empty($perms)) {
507
			$permuted = array();
508
		}
509
 
510
		if (empty($items)) {
511
			$permuted[] = $perms;
512
		} else {
513
			$numItems = count($items) - 1;
514
			for ($i = $numItems; $i >= 0; --$i) {
515
				$newItems = $items;
516
				$newPerms = $perms;
517
				list($tmp) = array_splice($newItems, $i, 1);
518
				array_unshift($newPerms, $tmp);
519
				$this->_arrayPermute($newItems, $newPerms);
520
			}
521
			return $permuted;
522
		}
523
	}
524
 
525
// @codingStandardsIgnoreStart
526
 
527
/**
528
 * Compatibility wrapper function for assertEquals
529
 *
530
 *
531
 * @param mixed $result
532
 * @param mixed $expected
533
 * @param string $message the text to display if the assertion is not correct
534
 * @return void
535
 */
536
	protected static function assertEqual($result, $expected, $message = '') {
537
		return self::assertEquals($expected, $result, $message);
538
	}
539
 
540
/**
541
 * Compatibility wrapper function for assertNotEquals
542
 *
543
 * @param mixed $result
544
 * @param mixed $expected
545
 * @param string $message the text to display if the assertion is not correct
546
 * @return void
547
 */
548
	protected static function assertNotEqual($result, $expected, $message = '') {
549
		return self::assertNotEquals($expected, $result, $message);
550
	}
551
 
552
/**
553
 * Compatibility wrapper function for assertRegexp
554
 *
555
 * @param mixed $pattern a regular expression
556
 * @param string $string the text to be matched
557
 * @param string $message the text to display if the assertion is not correct
558
 * @return void
559
 */
560
	protected static function assertPattern($pattern, $string, $message = '') {
561
		return self::assertRegExp($pattern, $string, $message);
562
	}
563
 
564
/**
565
 * Compatibility wrapper function for assertEquals
566
 *
567
 * @param mixed $actual
568
 * @param mixed $expected
569
 * @param string $message the text to display if the assertion is not correct
570
 * @return void
571
 */
572
	protected static function assertIdentical($actual, $expected, $message = '') {
573
		return self::assertSame($expected, $actual, $message);
574
	}
575
 
576
/**
577
 * Compatibility wrapper function for assertNotEquals
578
 *
579
 * @param mixed $actual
580
 * @param mixed $expected
581
 * @param string $message the text to display if the assertion is not correct
582
 * @return void
583
 */
584
	protected static function assertNotIdentical($actual, $expected, $message = '') {
585
		return self::assertNotSame($expected, $actual, $message);
586
	}
587
 
588
/**
589
 * Compatibility wrapper function for assertNotRegExp
590
 *
591
 * @param mixed $pattern a regular expression
592
 * @param string $string the text to be matched
593
 * @param string $message the text to display if the assertion is not correct
594
 * @return void
595
 */
596
	protected static function assertNoPattern($pattern, $string, $message = '') {
597
		return self::assertNotRegExp($pattern, $string, $message);
598
	}
599
 
600
/**
601
 * assert no errors
602
 */
603
	protected function assertNoErrors() {
604
	}
605
 
606
/**
607
 * Compatibility wrapper function for setExpectedException
608
 *
609
 * @param mixed $expected the name of the Exception or error
610
 * @param string $message the text to display if the assertion is not correct
611
 * @return void
612
 */
613
	protected function expectError($expected = false, $message = '') {
614
		if (!$expected) {
615
			$expected = 'Exception';
616
		}
617
		$this->setExpectedException($expected, $message);
618
	}
619
 
620
/**
621
 * Compatibility wrapper function for setExpectedException
622
 *
623
 * @param mixed $expected the name of the Exception
624
 * @param string $message the text to display if the assertion is not correct
625
 * @return void
626
 */
627
	protected function expectException($name = 'Exception', $message = '') {
628
		$this->setExpectedException($name, $message);
629
	}
630
 
631
/**
632
 * Compatibility wrapper function for assertSame
633
 *
634
 * @param mixed $first
635
 * @param mixed $second
636
 * @param string $message the text to display if the assertion is not correct
637
 * @return void
638
 */
639
	protected static function assertReference(&$first, &$second, $message = '') {
640
		return self::assertSame($first, $second, $message);
641
	}
642
 
643
/**
644
 * Compatibility wrapper for assertIsA
645
 *
646
 * @param string $object
647
 * @param string $type
648
 * @param string $message
649
 * @return void
650
 */
651
	protected static function assertIsA($object, $type, $message = '') {
652
		return self::assertInstanceOf($type, $object, $message);
653
	}
654
 
655
/**
656
 * Compatibility function to test if value is between an acceptable range
657
 *
658
 * @param mixed $result
659
 * @param mixed $expected
660
 * @param mixed $margin the rage of acceptation
661
 * @param string $message the text to display if the assertion is not correct
662
 * @return void
663
 */
664
	protected static function assertWithinMargin($result, $expected, $margin, $message = '') {
665
		$upper = $result + $margin;
666
		$lower = $result - $margin;
667
		return self::assertTrue((($expected <= $upper) && ($expected >= $lower)), $message);
668
	}
669
 
670
/**
671
 * Compatibility function for skipping.
672
 *
673
 * @param boolean $condition Condition to trigger skipping
674
 * @param string $message Message for skip
675
 * @return boolean
676
 */
677
	protected function skipUnless($condition, $message = '') {
678
		if (!$condition) {
679
			$this->markTestSkipped($message);
680
		}
681
		return $condition;
682
	}
683
	// @codingStandardsIgnoreEnd
684
 
685
/**
686
 * Mock a model, maintain fixtures and table association
687
 *
688
 * @param string $model
689
 * @param mixed $methods
690
 * @param array $config
691
 * @throws MissingModelException
692
 * @return Model
693
 */
694
	public function getMockForModel($model, $methods = array(), $config = array()) {
695
		$config += ClassRegistry::config('Model');
696
 
697
		list($plugin, $name) = pluginSplit($model, true);
698
		App::uses($name, $plugin . 'Model');
699
		$config = array_merge((array)$config, array('name' => $name));
700
 
701
		if (!class_exists($name)) {
702
			throw new MissingModelException(array($model));
703
		}
704
 
705
		$mock = $this->getMock($name, $methods, array($config));
706
		ClassRegistry::removeObject($name);
707
		ClassRegistry::addObject($name, $mock);
708
		return $mock;
709
	}
710
 
711
}