CakePHP
  • Documentation
    • Book
    • API
    • Videos
    • Logos & Trademarks
  • Business Solutions
  • Swag
  • Road Trip
  • Team
  • Community
    • Community
    • Team
    • Issues (Github)
    • YouTube Channel
    • Get Involved
    • Bakery
    • Featured Resources
    • Newsletter
    • Certification
    • My CakePHP
    • CakeFest
    • Facebook
    • Twitter
    • Help & Support
    • Forum
    • Stack Overflow
    • IRC
    • Slack
    • Paid Support
CakePHP

C CakePHP 3.7 Red Velvet API

  • Overview
  • Tree
  • Deprecated
  • Version:
    • 3.7
      • 3.7
      • 3.6
      • 3.5
      • 3.4
      • 3.3
      • 3.2
      • 3.1
      • 3.0
      • 2.10
      • 2.9
      • 2.8
      • 2.7
      • 2.6
      • 2.5
      • 2.4
      • 2.3
      • 2.2
      • 2.1
      • 2.0
      • 1.3
      • 1.2

Namespaces

  • Cake
    • Auth
      • Storage
    • Cache
      • Engine
    • Collection
      • Iterator
    • Command
    • Console
      • Exception
    • Controller
      • Component
      • Exception
    • Core
      • Configure
        • Engine
      • Exception
      • Retry
    • Database
      • Driver
      • Exception
      • Expression
      • Schema
      • Statement
      • Type
    • Datasource
      • Exception
    • Error
      • Middleware
    • Event
      • Decorator
    • Filesystem
    • Form
    • Http
      • Client
        • Adapter
        • Auth
      • Cookie
      • Exception
      • Middleware
      • Session
    • I18n
      • Formatter
      • Middleware
      • Parser
    • Log
      • Engine
    • Mailer
      • Exception
      • Transport
    • Network
      • Exception
    • ORM
      • Association
      • Behavior
        • Translate
      • Exception
      • Locator
      • Rule
    • Routing
      • Exception
      • Filter
      • Middleware
      • Route
    • Shell
      • Helper
      • Task
    • TestSuite
      • Fixture
      • Stub
    • Utility
      • Exception
    • Validation
    • View
      • Exception
      • Form
      • Helper
      • Widget
  • None

Classes

  • ConsoleIntegrationTestCase
  • IntegrationTestCase
  • LegacyCommandRunner
  • LegacyShellDispatcher
  • TestCase
  • TestEmailTransport
  • TestSuite

Traits

  • ConsoleIntegrationTestTrait
  • EmailAssertTrait
  • EmailTrait
  • IntegrationTestTrait
  • StringCompareTrait
  1: <?php
  2: /**
  3:  * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
  4:  * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  5:  *
  6:  * Licensed under The MIT License
  7:  * For full copyright and license information, please see the LICENSE.txt
  8:  * Redistributions of files must retain the above copyright notice
  9:  *
 10:  * @copyright     Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
 11:  * @since         1.2.0
 12:  * @license       https://opensource.org/licenses/mit-license.php MIT License
 13:  */
 14: namespace Cake\TestSuite;
 15: 
 16: use Cake\Core\App;
 17: use Cake\Core\Configure;
 18: use Cake\Core\Plugin;
 19: use Cake\Datasource\ConnectionManager;
 20: use Cake\Event\EventManager;
 21: use Cake\Http\BaseApplication;
 22: use Cake\ORM\Entity;
 23: use Cake\ORM\Exception\MissingTableClassException;
 24: use Cake\ORM\Locator\LocatorAwareTrait;
 25: use Cake\Routing\Router;
 26: use Cake\TestSuite\Constraint\EventFired;
 27: use Cake\TestSuite\Constraint\EventFiredWith;
 28: use Cake\Utility\Inflector;
 29: use Exception;
 30: use PHPUnit\Framework\TestCase as BaseTestCase;
 31: 
 32: /**
 33:  * Cake TestCase class
 34:  */
 35: abstract class TestCase extends BaseTestCase
 36: {
 37: 
 38:     use LocatorAwareTrait;
 39: 
 40:     /**
 41:      * The class responsible for managing the creation, loading and removing of fixtures
 42:      *
 43:      * @var \Cake\TestSuite\Fixture\FixtureManager|null
 44:      */
 45:     public $fixtureManager;
 46: 
 47:     /**
 48:      * By default, all fixtures attached to this class will be truncated and reloaded after each test.
 49:      * Set this to false to handle manually
 50:      *
 51:      * @var bool
 52:      */
 53:     public $autoFixtures = true;
 54: 
 55:     /**
 56:      * Control table create/drops on each test method.
 57:      *
 58:      * If true, tables will still be dropped at the
 59:      * end of each test runner execution.
 60:      *
 61:      * @var bool
 62:      */
 63:     public $dropTables = false;
 64: 
 65:     /**
 66:      * Configure values to restore at end of test.
 67:      *
 68:      * @var array
 69:      */
 70:     protected $_configure = [];
 71: 
 72:     /**
 73:      * Path settings to restore at the end of the test.
 74:      *
 75:      * @var array
 76:      */
 77:     protected $_pathRestore = [];
 78: 
 79:     /**
 80:      * Overrides SimpleTestCase::skipIf to provide a boolean return value
 81:      *
 82:      * @param bool $shouldSkip Whether or not the test should be skipped.
 83:      * @param string $message The message to display.
 84:      * @return bool
 85:      */
 86:     public function skipIf($shouldSkip, $message = '')
 87:     {
 88:         if ($shouldSkip) {
 89:             $this->markTestSkipped($message);
 90:         }
 91: 
 92:         return $shouldSkip;
 93:     }
 94: 
 95:     /**
 96:      * Helper method for tests that needs to use error_reporting()
 97:      *
 98:      * @param int $errorLevel value of error_reporting() that needs to use
 99:      * @param callable $callable callable function that will receive asserts
100:      * @return void
101:      */
102:     public function withErrorReporting($errorLevel, $callable)
103:     {
104:         $default = error_reporting();
105:         error_reporting($errorLevel);
106:         try {
107:             $callable();
108:         } finally {
109:             error_reporting($default);
110:         }
111:     }
112: 
113:     /**
114:      * Helper method for check deprecation methods
115:      *
116:      * @param callable $callable callable function that will receive asserts
117:      * @return void
118:      */
119:     public function deprecated($callable)
120:     {
121:         $errorLevel = error_reporting();
122:         error_reporting(E_ALL ^ E_USER_DEPRECATED);
123:         try {
124:             $callable();
125:         } finally {
126:             error_reporting($errorLevel);
127:         }
128:     }
129: 
130:     /**
131:      * Setup the test case, backup the static object values so they can be restored.
132:      * Specifically backs up the contents of Configure and paths in App if they have
133:      * not already been backed up.
134:      *
135:      * @return void
136:      */
137:     public function setUp()
138:     {
139:         parent::setUp();
140: 
141:         if (!$this->_configure) {
142:             $this->_configure = Configure::read();
143:         }
144:         if (class_exists('Cake\Routing\Router', false)) {
145:             Router::reload();
146:         }
147: 
148:         EventManager::instance(new EventManager());
149:     }
150: 
151:     /**
152:      * teardown any static object changes and restore them.
153:      *
154:      * @return void
155:      */
156:     public function tearDown()
157:     {
158:         parent::tearDown();
159:         if ($this->_configure) {
160:             Configure::clear();
161:             Configure::write($this->_configure);
162:         }
163:         $this->getTableLocator()->clear();
164:     }
165: 
166:     /**
167:      * Chooses which fixtures to load for a given test
168:      *
169:      * Each parameter is a model name that corresponds to a fixture, i.e. 'Posts', 'Authors', etc.
170:      * Passing no parameters will cause all fixtures on the test case to load.
171:      *
172:      * @return void
173:      * @see \Cake\TestSuite\TestCase::$autoFixtures
174:      * @throws \Exception when no fixture manager is available.
175:      */
176:     public function loadFixtures()
177:     {
178:         if ($this->fixtureManager === null) {
179:             throw new Exception('No fixture manager to load the test fixture');
180:         }
181:         $args = func_get_args();
182:         foreach ($args as $class) {
183:             $this->fixtureManager->loadSingle($class, null, $this->dropTables);
184:         }
185: 
186:         if (empty($args)) {
187:             $autoFixtures = $this->autoFixtures;
188:             $this->autoFixtures = true;
189:             $this->fixtureManager->load($this);
190:             $this->autoFixtures = $autoFixtures;
191:         }
192:     }
193: 
194:     /**
195:      * Load plugins into a simulated application.
196:      *
197:      * Useful to test how plugins being loaded/not loaded interact with other
198:      * elements in CakePHP or applications.
199:      *
200:      * @param array $plugins List of Plugins to load.
201:      * @return \Cake\Http\BaseApplication
202:      */
203:     public function loadPlugins(array $plugins = [])
204:     {
205:         /** @var \Cake\Http\BaseApplication $app */
206:         $app = $this->getMockForAbstractClass(
207:             BaseApplication::class,
208:             ['']
209:         );
210: 
211:         foreach ($plugins as $pluginName => $config) {
212:             if (is_array($config)) {
213:                 $app->addPlugin($pluginName, $config);
214:             } else {
215:                 $app->addPlugin($config);
216:             }
217:         }
218:         $app->pluginBootstrap();
219:         $builder = Router::createRouteBuilder('/');
220:         $app->pluginRoutes($builder);
221: 
222:         return $app;
223:     }
224: 
225:     /**
226:      * Remove plugins from the global plugin collection.
227:      *
228:      * Useful in test case teardown methods.
229:      *
230:      * @param array $plugins A list of plugins you want to remove.
231:      * @return void
232:      */
233:     public function removePlugins(array $plugins = [])
234:     {
235:         $collection = Plugin::getCollection();
236:         foreach ($plugins as $plugin) {
237:             $collection->remove($plugin);
238:         }
239:     }
240: 
241:     /**
242:      * Clear all plugins from the global plugin collection.
243:      *
244:      * Useful in test case teardown methods.
245:      *
246:      * @return void
247:      */
248:     public function clearPlugins()
249:     {
250:         Plugin::getCollection()->clear();
251:     }
252: 
253:     /**
254:      * Asserts that a global event was fired. You must track events in your event manager for this assertion to work
255:      *
256:      * @param string $name Event name
257:      * @param EventManager|null $eventManager Event manager to check, defaults to global event manager
258:      * @param string $message Assertion failure message
259:      * @return void
260:      */
261:     public function assertEventFired($name, $eventManager = null, $message = '')
262:     {
263:         if (!$eventManager) {
264:             $eventManager = EventManager::instance();
265:         }
266:         $this->assertThat($name, new EventFired($eventManager), $message);
267:     }
268: 
269:     /**
270:      * Asserts an event was fired with data
271:      *
272:      * If a third argument is passed, that value is used to compare with the value in $dataKey
273:      *
274:      * @param string $name Event name
275:      * @param string $dataKey Data key
276:      * @param string $dataValue Data value
277:      * @param EventManager|null $eventManager Event manager to check, defaults to global event manager
278:      * @param string $message Assertion failure message
279:      * @return void
280:      */
281:     public function assertEventFiredWith($name, $dataKey, $dataValue, $eventManager = null, $message = '')
282:     {
283:         if (!$eventManager) {
284:             $eventManager = EventManager::instance();
285:         }
286:         $this->assertThat($name, new EventFiredWith($eventManager, $dataKey, $dataValue), $message);
287:     }
288: 
289:     /**
290:      * Assert text equality, ignoring differences in newlines.
291:      * Helpful for doing cross platform tests of blocks of text.
292:      *
293:      * @param string $expected The expected value.
294:      * @param string $result The actual value.
295:      * @param string $message The message to use for failure.
296:      * @return void
297:      */
298:     public function assertTextNotEquals($expected, $result, $message = '')
299:     {
300:         $expected = str_replace(["\r\n", "\r"], "\n", $expected);
301:         $result = str_replace(["\r\n", "\r"], "\n", $result);
302:         $this->assertNotEquals($expected, $result, $message);
303:     }
304: 
305:     /**
306:      * Assert text equality, ignoring differences in newlines.
307:      * Helpful for doing cross platform tests of blocks of text.
308:      *
309:      * @param string $expected The expected value.
310:      * @param string $result The actual value.
311:      * @param string $message The message to use for failure.
312:      * @return void
313:      */
314:     public function assertTextEquals($expected, $result, $message = '')
315:     {
316:         $expected = str_replace(["\r\n", "\r"], "\n", $expected);
317:         $result = str_replace(["\r\n", "\r"], "\n", $result);
318:         $this->assertEquals($expected, $result, $message);
319:     }
320: 
321:     /**
322:      * Asserts that a string starts with a given prefix, ignoring differences in newlines.
323:      * Helpful for doing cross platform tests of blocks of text.
324:      *
325:      * @param string $prefix The prefix to check for.
326:      * @param string $string The string to search in.
327:      * @param string $message The message to use for failure.
328:      * @return void
329:      */
330:     public function assertTextStartsWith($prefix, $string, $message = '')
331:     {
332:         $prefix = str_replace(["\r\n", "\r"], "\n", $prefix);
333:         $string = str_replace(["\r\n", "\r"], "\n", $string);
334:         $this->assertStringStartsWith($prefix, $string, $message);
335:     }
336: 
337:     /**
338:      * Asserts that a string starts not with a given prefix, ignoring differences in newlines.
339:      * Helpful for doing cross platform tests of blocks of text.
340:      *
341:      * @param string $prefix The prefix to not find.
342:      * @param string $string The string to search.
343:      * @param string $message The message to use for failure.
344:      * @return void
345:      */
346:     public function assertTextStartsNotWith($prefix, $string, $message = '')
347:     {
348:         $prefix = str_replace(["\r\n", "\r"], "\n", $prefix);
349:         $string = str_replace(["\r\n", "\r"], "\n", $string);
350:         $this->assertStringStartsNotWith($prefix, $string, $message);
351:     }
352: 
353:     /**
354:      * Asserts that a string ends with a given prefix, ignoring differences in newlines.
355:      * Helpful for doing cross platform tests of blocks of text.
356:      *
357:      * @param string $suffix The suffix to find.
358:      * @param string $string The string to search.
359:      * @param string $message The message to use for failure.
360:      * @return void
361:      */
362:     public function assertTextEndsWith($suffix, $string, $message = '')
363:     {
364:         $suffix = str_replace(["\r\n", "\r"], "\n", $suffix);
365:         $string = str_replace(["\r\n", "\r"], "\n", $string);
366:         $this->assertStringEndsWith($suffix, $string, $message);
367:     }
368: 
369:     /**
370:      * Asserts that a string ends not with a given prefix, ignoring differences in newlines.
371:      * Helpful for doing cross platform tests of blocks of text.
372:      *
373:      * @param string $suffix The suffix to not find.
374:      * @param string $string The string to search.
375:      * @param string $message The message to use for failure.
376:      * @return void
377:      */
378:     public function assertTextEndsNotWith($suffix, $string, $message = '')
379:     {
380:         $suffix = str_replace(["\r\n", "\r"], "\n", $suffix);
381:         $string = str_replace(["\r\n", "\r"], "\n", $string);
382:         $this->assertStringEndsNotWith($suffix, $string, $message);
383:     }
384: 
385:     /**
386:      * Assert that a string contains another string, ignoring differences in newlines.
387:      * Helpful for doing cross platform tests of blocks of text.
388:      *
389:      * @param string $needle The string to search for.
390:      * @param string $haystack The string to search through.
391:      * @param string $message The message to display on failure.
392:      * @param bool $ignoreCase Whether or not the search should be case-sensitive.
393:      * @return void
394:      */
395:     public function assertTextContains($needle, $haystack, $message = '', $ignoreCase = false)
396:     {
397:         $needle = str_replace(["\r\n", "\r"], "\n", $needle);
398:         $haystack = str_replace(["\r\n", "\r"], "\n", $haystack);
399:         $this->assertContains($needle, $haystack, $message, $ignoreCase);
400:     }
401: 
402:     /**
403:      * Assert that a text doesn't contain another text, ignoring differences in newlines.
404:      * Helpful for doing cross platform tests of blocks of text.
405:      *
406:      * @param string $needle The string to search for.
407:      * @param string $haystack The string to search through.
408:      * @param string $message The message to display on failure.
409:      * @param bool $ignoreCase Whether or not the search should be case-sensitive.
410:      * @return void
411:      */
412:     public function assertTextNotContains($needle, $haystack, $message = '', $ignoreCase = false)
413:     {
414:         $needle = str_replace(["\r\n", "\r"], "\n", $needle);
415:         $haystack = str_replace(["\r\n", "\r"], "\n", $haystack);
416:         $this->assertNotContains($needle, $haystack, $message, $ignoreCase);
417:     }
418: 
419:     /**
420:      * Asserts HTML tags.
421:      *
422:      * @param string $string An HTML/XHTML/XML string
423:      * @param array $expected An array, see above
424:      * @param bool $fullDebug Whether or not more verbose output should be used.
425:      * @return void
426:      * @deprecated 3.0. Use assertHtml() instead.
427:      */
428:     public function assertTags($string, $expected, $fullDebug = false)
429:     {
430:         deprecationWarning('TestCase::assertTags() is deprecated. Use TestCase::assertHtml() instead.');
431:         $this->assertHtml($expected, $string, $fullDebug);
432:     }
433: 
434:     /**
435:      * Asserts HTML tags.
436:      *
437:      * Takes an array $expected and generates a regex from it to match the provided $string.
438:      * Samples for $expected:
439:      *
440:      * Checks for an input tag with a name attribute (contains any non-empty value) and an id
441:      * attribute that contains 'my-input':
442:      *
443:      * ```
444:      * ['input' => ['name', 'id' => 'my-input']]
445:      * ```
446:      *
447:      * Checks for two p elements with some text in them:
448:      *
449:      * ```
450:      * [
451:      *   ['p' => true],
452:      *   'textA',
453:      *   '/p',
454:      *   ['p' => true],
455:      *   'textB',
456:      *   '/p'
457:      * ]
458:      * ```
459:      *
460:      * You can also specify a pattern expression as part of the attribute values, or the tag
461:      * being defined, if you prepend the value with preg: and enclose it with slashes, like so:
462:      *
463:      * ```
464:      * [
465:      *   ['input' => ['name', 'id' => 'preg:/FieldName\d+/']],
466:      *   'preg:/My\s+field/'
467:      * ]
468:      * ```
469:      *
470:      * Important: This function is very forgiving about whitespace and also accepts any
471:      * permutation of attribute order. It will also allow whitespace between specified tags.
472:      *
473:      * @param array $expected An array, see above
474:      * @param string $string An HTML/XHTML/XML string
475:      * @param bool $fullDebug Whether or not more verbose output should be used.
476:      * @return bool
477:      */
478:     public function assertHtml($expected, $string, $fullDebug = false)
479:     {
480:         $regex = [];
481:         $normalized = [];
482:         foreach ((array)$expected as $key => $val) {
483:             if (!is_numeric($key)) {
484:                 $normalized[] = [$key => $val];
485:             } else {
486:                 $normalized[] = $val;
487:             }
488:         }
489:         $i = 0;
490:         foreach ($normalized as $tags) {
491:             if (!is_array($tags)) {
492:                 $tags = (string)$tags;
493:             }
494:             $i++;
495:             if (is_string($tags) && $tags{0} === '<') {
496:                 $tags = [substr($tags, 1) => []];
497:             } elseif (is_string($tags)) {
498:                 $tagsTrimmed = preg_replace('/\s+/m', '', $tags);
499: 
500:                 if (preg_match('/^\*?\//', $tags, $match) && $tagsTrimmed !== '//') {
501:                     $prefix = [null, null];
502: 
503:                     if ($match[0] === '*/') {
504:                         $prefix = ['Anything, ', '.*?'];
505:                     }
506:                     $regex[] = [
507:                         sprintf('%sClose %s tag', $prefix[0], substr($tags, strlen($match[0]))),
508:                         sprintf('%s\s*<[\s]*\/[\s]*%s[\s]*>[\n\r]*', $prefix[1], substr($tags, strlen($match[0]))),
509:                         $i,
510:                     ];
511:                     continue;
512:                 }
513:                 if (!empty($tags) && preg_match('/^preg\:\/(.+)\/$/i', $tags, $matches)) {
514:                     $tags = $matches[1];
515:                     $type = 'Regex matches';
516:                 } else {
517:                     $tags = '\s*' . preg_quote($tags, '/');
518:                     $type = 'Text equals';
519:                 }
520:                 $regex[] = [
521:                     sprintf('%s "%s"', $type, $tags),
522:                     $tags,
523:                     $i,
524:                 ];
525:                 continue;
526:             }
527:             foreach ($tags as $tag => $attributes) {
528:                 $regex[] = [
529:                     sprintf('Open %s tag', $tag),
530:                     sprintf('[\s]*<%s', preg_quote($tag, '/')),
531:                     $i,
532:                 ];
533:                 if ($attributes === true) {
534:                     $attributes = [];
535:                 }
536:                 $attrs = [];
537:                 $explanations = [];
538:                 $i = 1;
539:                 foreach ($attributes as $attr => $val) {
540:                     if (is_numeric($attr) && preg_match('/^preg\:\/(.+)\/$/i', $val, $matches)) {
541:                         $attrs[] = $matches[1];
542:                         $explanations[] = sprintf('Regex "%s" matches', $matches[1]);
543:                         continue;
544:                     }
545: 
546:                     $quotes = '["\']';
547:                     if (is_numeric($attr)) {
548:                         $attr = $val;
549:                         $val = '.+?';
550:                         $explanations[] = sprintf('Attribute "%s" present', $attr);
551:                     } elseif (!empty($val) && preg_match('/^preg\:\/(.+)\/$/i', $val, $matches)) {
552:                         $val = str_replace(
553:                             ['.*', '.+'],
554:                             ['.*?', '.+?'],
555:                             $matches[1]
556:                         );
557:                         $quotes = $val !== $matches[1] ? '["\']' : '["\']?';
558: 
559:                         $explanations[] = sprintf('Attribute "%s" matches "%s"', $attr, $val);
560:                     } else {
561:                         $explanations[] = sprintf('Attribute "%s" == "%s"', $attr, $val);
562:                         $val = preg_quote($val, '/');
563:                     }
564:                     $attrs[] = '[\s]+' . preg_quote($attr, '/') . '=' . $quotes . $val . $quotes;
565:                     $i++;
566:                 }
567:                 if ($attrs) {
568:                     $regex[] = [
569:                         'explains' => $explanations,
570:                         'attrs' => $attrs,
571:                     ];
572:                 }
573:                 $regex[] = [
574:                     sprintf('End %s tag', $tag),
575:                     '[\s]*\/?[\s]*>[\n\r]*',
576:                     $i,
577:                 ];
578:             }
579:         }
580:         foreach ($regex as $i => $assertion) {
581:             $matches = false;
582:             if (isset($assertion['attrs'])) {
583:                 $string = $this->_assertAttributes($assertion, $string, $fullDebug, $regex);
584:                 if ($fullDebug === true && $string === false) {
585:                     debug($string, true);
586:                     debug($regex, true);
587:                 }
588:                 continue;
589:             }
590: 
591:             list($description, $expressions, $itemNum) = $assertion;
592:             $expression = null;
593:             foreach ((array)$expressions as $expression) {
594:                 $expression = sprintf('/^%s/s', $expression);
595:                 if (preg_match($expression, $string, $match)) {
596:                     $matches = true;
597:                     $string = substr($string, strlen($match[0]));
598:                     break;
599:                 }
600:             }
601:             if (!$matches) {
602:                 if ($fullDebug === true) {
603:                     debug($string);
604:                     debug($regex);
605:                 }
606:                 $this->assertRegExp($expression, $string, sprintf('Item #%d / regex #%d failed: %s', $itemNum, $i, $description));
607: 
608:                 return false;
609:             }
610:         }
611: 
612:         $this->assertTrue(true, '%s');
613: 
614:         return true;
615:     }
616: 
617:     /**
618:      * Check the attributes as part of an assertTags() check.
619:      *
620:      * @param array $assertions Assertions to run.
621:      * @param string $string The HTML string to check.
622:      * @param bool $fullDebug Whether or not more verbose output should be used.
623:      * @param array|string $regex Full regexp from `assertHtml`
624:      * @return string|bool
625:      */
626:     protected function _assertAttributes($assertions, $string, $fullDebug = false, $regex = '')
627:     {
628:         $asserts = $assertions['attrs'];
629:         $explains = $assertions['explains'];
630:         do {
631:             $matches = false;
632:             $j = null;
633:             foreach ($asserts as $j => $assert) {
634:                 if (preg_match(sprintf('/^%s/s', $assert), $string, $match)) {
635:                     $matches = true;
636:                     $string = substr($string, strlen($match[0]));
637:                     array_splice($asserts, $j, 1);
638:                     array_splice($explains, $j, 1);
639:                     break;
640:                 }
641:             }
642:             if ($matches === false) {
643:                 if ($fullDebug === true) {
644:                     debug($string);
645:                     debug($regex);
646:                 }
647:                 $this->assertTrue(false, 'Attribute did not match. Was expecting ' . $explains[$j]);
648:             }
649:             $len = count($asserts);
650:         } while ($len > 0);
651: 
652:         return $string;
653:     }
654: 
655:     /**
656:      * Normalize a path for comparison.
657:      *
658:      * @param string $path Path separated by "/" slash.
659:      * @return string Normalized path separated by DIRECTORY_SEPARATOR.
660:      */
661:     protected function _normalizePath($path)
662:     {
663:         return str_replace('/', DIRECTORY_SEPARATOR, $path);
664:     }
665: 
666: // @codingStandardsIgnoreStart
667: 
668:     /**
669:      * Compatibility function to test if a value is between an acceptable range.
670:      *
671:      * @param float $expected
672:      * @param float $result
673:      * @param float $margin the rage of acceptation
674:      * @param string $message the text to display if the assertion is not correct
675:      * @return void
676:      */
677:     protected static function assertWithinRange($expected, $result, $margin, $message = '')
678:     {
679:         $upper = $result + $margin;
680:         $lower = $result - $margin;
681:         static::assertTrue(($expected <= $upper) && ($expected >= $lower), $message);
682:     }
683: 
684:     /**
685:      * Compatibility function to test if a value is not between an acceptable range.
686:      *
687:      * @param float $expected
688:      * @param float $result
689:      * @param float $margin the rage of acceptation
690:      * @param string $message the text to display if the assertion is not correct
691:      * @return void
692:      */
693:     protected static function assertNotWithinRange($expected, $result, $margin, $message = '')
694:     {
695:         $upper = $result + $margin;
696:         $lower = $result - $margin;
697:         static::assertTrue(($expected > $upper) || ($expected < $lower), $message);
698:     }
699: 
700:     /**
701:      * Compatibility function to test paths.
702:      *
703:      * @param string $expected
704:      * @param string $result
705:      * @param string $message the text to display if the assertion is not correct
706:      * @return void
707:      */
708:     protected static function assertPathEquals($expected, $result, $message = '')
709:     {
710:         $expected = str_replace(DIRECTORY_SEPARATOR, '/', $expected);
711:         $result = str_replace(DIRECTORY_SEPARATOR, '/', $result);
712:         static::assertEquals($expected, $result, $message);
713:     }
714: 
715:     /**
716:      * Compatibility function for skipping.
717:      *
718:      * @param bool $condition Condition to trigger skipping
719:      * @param string $message Message for skip
720:      * @return bool
721:      */
722:     protected function skipUnless($condition, $message = '')
723:     {
724:         if (!$condition) {
725:             $this->markTestSkipped($message);
726:         }
727: 
728:         return $condition;
729:     }
730: 
731: // @codingStandardsIgnoreEnd
732: 
733:     /**
734:      * Mock a model, maintain fixtures and table association
735:      *
736:      * @param string $alias The model to get a mock for.
737:      * @param array|null $methods The list of methods to mock
738:      * @param array $options The config data for the mock's constructor.
739:      * @throws \Cake\ORM\Exception\MissingTableClassException
740:      * @return \Cake\ORM\Table|\PHPUnit_Framework_MockObject_MockObject
741:      */
742:     public function getMockForModel($alias, $methods = [], array $options = [])
743:     {
744:         /** @var \Cake\ORM\Table $className */
745:         $className = $this->_getTableClassName($alias, $options);
746:         $connectionName = $className::defaultConnectionName();
747:         $connection = ConnectionManager::get($connectionName);
748: 
749:         $locator = $this->getTableLocator();
750: 
751:         list(, $baseClass) = pluginSplit($alias);
752:         $options += ['alias' => $baseClass, 'connection' => $connection];
753:         $options += $locator->getConfig($alias);
754: 
755:         /** @var \Cake\ORM\Table|\PHPUnit_Framework_MockObject_MockObject $mock */
756:         $mock = $this->getMockBuilder($className)
757:             ->setMethods($methods)
758:             ->setConstructorArgs([$options])
759:             ->getMock();
760: 
761:         if (empty($options['entityClass']) && $mock->getEntityClass() === Entity::class) {
762:             $parts = explode('\\', $className);
763:             $entityAlias = Inflector::classify(Inflector::underscore(substr(array_pop($parts), 0, -5)));
764:             $entityClass = implode('\\', array_slice($parts, 0, -1)) . '\\Entity\\' . $entityAlias;
765:             if (class_exists($entityClass)) {
766:                 $mock->setEntityClass($entityClass);
767:             }
768:         }
769: 
770:         if (stripos($mock->getTable(), 'mock') === 0) {
771:             $mock->setTable(Inflector::tableize($baseClass));
772:         }
773: 
774:         $locator->set($baseClass, $mock);
775:         $locator->set($alias, $mock);
776: 
777:         return $mock;
778:     }
779: 
780:     /**
781:      * Gets the class name for the table.
782:      *
783:      * @param string $alias The model to get a mock for.
784:      * @param array $options The config data for the mock's constructor.
785:      * @return string
786:      * @throws \Cake\ORM\Exception\MissingTableClassException
787:      */
788:     protected function _getTableClassName($alias, array $options)
789:     {
790:         if (empty($options['className'])) {
791:             $class = Inflector::camelize($alias);
792:             $className = App::className($class, 'Model/Table', 'Table');
793:             if (!$className) {
794:                 throw new MissingTableClassException([$alias]);
795:             }
796:             $options['className'] = $className;
797:         }
798: 
799:         return $options['className'];
800:     }
801: 
802:     /**
803:      * Set the app namespace
804:      *
805:      * @param string $appNamespace The app namespace, defaults to "TestApp".
806:      * @return void
807:      */
808:     public static function setAppNamespace($appNamespace = 'TestApp')
809:     {
810:         Configure::write('App.namespace', $appNamespace);
811:     }
812: }
813: 
Follow @CakePHP
#IRC
OpenHub
Rackspace
  • Business Solutions
  • Showcase
  • Documentation
  • Book
  • API
  • Videos
  • Logos & Trademarks
  • Community
  • Team
  • Issues (Github)
  • YouTube Channel
  • Get Involved
  • Bakery
  • Featured Resources
  • Newsletter
  • Certification
  • My CakePHP
  • CakeFest
  • Facebook
  • Twitter
  • Help & Support
  • Forum
  • Stack Overflow
  • IRC
  • Slack
  • Paid Support

Generated using CakePHP API Docs