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.8 Red Velvet API

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