/test/Unit.php
PHP | 2020 lines | 1021 code | 125 blank | 874 comment | 122 complexity | a3fdb4860ea2cc3a0f934bac4c043cc7 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- <?php
- /**
- * li₃: the most RAD framework for PHP (http://li3.me)
- *
- * Copyright 2009, Union of RAD. All rights reserved. This source
- * code is distributed under the terms of the BSD 3-Clause License.
- * The full license text can be found in the LICENSE.txt file.
- */
- namespace lithium\test;
- use Error;
- use Exception;
- use ErrorException;
- use ReflectionClass;
- use InvalidArgumentException;
- use lithium\aop\Filters;
- use lithium\util\Text;
- use lithium\core\Libraries;
- use lithium\util\Validator;
- use lithium\analysis\Debugger;
- use lithium\analysis\Inspector;
- use RecursiveDirectoryIterator;
- use RecursiveIteratorIterator;
- /**
- * This is the base class for all test cases. Test are performed using an assertion method.
- * If the assertion is correct, the test passes, otherwise it fails. Most assertions take an
- * expected result, a received result, and a message (to describe the failure) as parameters.
- *
- * Unit tests are used to check a small unit of functionality, such as if a method returns an
- * expected result for a known input, or whether an adapter can successfully open a connection.
- *
- * Available assertions are (see `assert<assertion-name>` methods for details): Equal, False,
- * Identical, NoPattern, NotEqual, Null, Pattern, Tags, True.
- *
- * If an assertion is expected to produce an exception, `assertException()` should be used.
- *
- * @see lithium\test\Unit::assertException()
- */
- class Unit extends \lithium\core\ObjectDeprecated {
- /**
- * The Reference to a test reporter class.
- *
- * @var string
- */
- protected $_reporter = null;
- /**
- * The list of test results.
- *
- * @var string
- */
- protected $_results = [];
- /**
- * Internal types and how to test for them
- *
- * @var array
- */
- protected static $_internalTypes = [
- 'array' => 'is_array',
- 'bool' => 'is_bool',
- 'boolean' => 'is_bool',
- 'callable' => 'is_callable',
- 'double' => 'is_double',
- 'float' => 'is_float',
- 'int' => 'is_int',
- 'integer' => 'is_integer',
- 'long' => 'is_long',
- 'null' => 'is_null',
- 'numeric' => 'is_numeric',
- 'object' => 'is_object',
- 'real' => 'is_real',
- 'resource' => 'is_resource',
- 'scalar' => 'is_scalar',
- 'string' => 'is_string'
- ];
- /**
- * Finds the test case for the corresponding class name.
- *
- * @param string $class A fully-namespaced class reference for which to find a test case.
- * @return string Returns the class name of a test case for `$class`, or `null` if none exists.
- */
- public static function get($class) {
- $parts = explode('\\', $class);
- $library = array_shift($parts);
- $name = array_pop($parts);
- $type = 'tests.cases.' . implode('.', $parts);
- return Libraries::locate($type, $name, compact('library'));
- }
- /**
- * Setup method run before every test method. Override in subclasses.
- *
- * @return void
- */
- public function setUp() {}
- /**
- * Teardown method run after every test method. Override in subclasses.
- *
- * @return void
- */
- public function tearDown() {}
- /**
- * Subclasses should use this method to set conditions that, if failed, terminate further
- * testing.
- *
- * For example:
- * ```
- * public function skip() {
- * $connection = Connections::get('test', ['config' => true]);
- * $this->skipIf(!$connection, 'Test database is unavailable.');
- * }
- * ```
- */
- public function skip() {}
- /**
- * Skips test(s) if the condition is met.
- *
- * When used within a subclass' `skip` method, all tests are ignored if the condition is
- * met, otherwise processing continues as normal. For other methods, only the remainder of
- * the method is skipped, when the condition is met.
- *
- * @throws Exception
- * @param boolean $condition
- * @param string|boolean $message Message to pass if the condition is met.
- * @return mixed
- */
- public function skipIf($condition, $message = false) {
- if ($condition) {
- throw new Exception(is_string($message) ? $message : null);
- }
- }
- /**
- * Returns the class name that is the subject under test for this test case.
- *
- * @return string
- */
- public function subject() {
- return preg_replace('/Test$/', '', str_replace('tests\\cases\\', '', get_class($this)));
- }
- /**
- * Return test methods to run.
- *
- * @return array
- */
- public function methods() {
- static $methods;
- return $methods ?: $methods = array_values(preg_grep('/^test/', get_class_methods($this)));
- }
- /**
- * Returns the current results.
- *
- * @return array The Results... currently.
- */
- public function results() {
- return $this->_results;
- }
- /**
- * Runs the test methods in this test case, with the given options.
- *
- * Installs a temporary error handler that will convert regular errors to
- * exceptions in order to make both errors and exceptions be handled
- * in a unified way. ErrorExceptions created like this, will get the
- * error's code as their severity. As this comes closest to their meaning.
- *
- * The error handler honors the PHP `error_level` and will not convert errors
- * to exceptions if they are masked by the `error_level`. This allows test
- * methods to run assertions against i.e. deprecated functions. Usually
- * the error_level is set by the test runner so that all errors are converted.
- *
- * @link http://php.net/manual/function.error-reporting.php
- * @param array $options The options to use when running the test. Available options are:
- * - `'methods'`: An arbitrary array of method names to execute. If
- * unspecified, all methods starting with 'test' are run.
- * - `'reporter'`: A closure which gets called after each test result,
- * which may modify the results presented.
- * - `'handler'`: A closure which gets registered as the temporary error handler.
- * @return array
- */
- public function run(array $options = []) {
- $defaults = [
- 'methods' => $this->methods(),
- 'reporter' => $this->_reporter,
- 'handler' => function($code, $message, $file = null, $line = null) {
- if (error_reporting() & $code) {
- throw new ErrorException($message, 0, $code, $file, $line);
- }
- }
- ];
- $options += $defaults;
- $this->_results = [];
- $this->_reporter = $options['reporter'];
- try {
- $this->skip();
- } catch (Exception $e) {
- $this->_handleException($e);
- return $this->_results;
- }
- set_error_handler($options['handler']);
- foreach ($options['methods'] as $method) {
- if ($this->_runTestMethod($method, $options) === false) {
- break;
- }
- }
- restore_error_handler();
- return $this->_results;
- }
- /**
- * General assert method used by others for common output.
- *
- * @param boolean $expression
- * @param string|boolean $message The message to output. If the message is not a string,
- * then it will be converted to '{:message}'. Use '{:message}' in the string and it
- * will use the `$data` to format the message with `Text::insert()`.
- * @param array $data
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assert($expression, $message = false, $data = []) {
- if (!is_string($message)) {
- $message = '{:message}';
- }
- if (strpos($message, "{:message}") !== false) {
- $params = $data;
- $params['message'] = $this->_message($params);
- $message = Text::insert($message, $params);
- }
- $trace = Debugger::trace([
- 'start' => 1, 'depth' => 4, 'format' => 'array', 'closures' => !$expression
- ]);
- $methods = $this->methods();
- $i = 1;
- while ($i < count($trace)) {
- if (in_array($trace[$i]['function'], $methods) && $trace[$i - 1]['object'] == $this) {
- break;
- }
- $i++;
- }
- $class = isset($trace[$i - 1]['object']) ? get_class($trace[$i - 1]['object']) : null;
- $method = isset($trace[$i]) ? $trace[$i]['function'] : $trace[$i - 1]['function'];
- $result = compact('class', 'method', 'message', 'data') + [
- 'file' => $trace[$i - 1]['file'],
- 'line' => $trace[$i - 1]['line'],
- 'assertion' => $trace[$i - 1]['function']
- ];
- $this->_result($expression ? 'pass' : 'fail', $result);
- return $expression;
- }
- /**
- * Generates a failed test with the given message.
- *
- * @param string $message
- */
- public function fail($message = false) {
- $this->assert(false, $message);
- }
- /**
- * Assert that the actual result is equal, but not neccessarily identical, to the expected
- * result.
- *
- * @see lithium\test\Unit::assert()
- * @param mixed $expected
- * @param mixed $result
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertEqual($expected, $result, $message = '{:message}') {
- list($expected, $result) = $this->_normalizeLineEndings($expected, $result);
- $data = ($expected != $result) ? $this->_compare('equal', $expected, $result) : null;
- return $this->assert($expected == $result, $message, $data);
- }
- /**
- * Assert that the actual result and the expected result are *not* equal to each other.
- *
- * @see lithium\test\Unit::assert()
- * @param mixed $expected
- * @param mixed $result
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertNotEqual($expected, $result, $message = '{:message}') {
- list($expected, $result) = $this->_normalizeLineEndings($expected, $result);
- return $this->assert($result != $expected, $message, compact('expected', 'result'));
- }
- /**
- * Assert that the actual result and the expected result are identical using a strict
- * comparison.
- *
- * @see lithium\test\Unit::assert()
- * @param mixed $expected
- * @param mixed $result
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertIdentical($expected, $result, $message = '{:message}') {
- $data = ($expected !== $result) ? $this->_compare('identical', $expected, $result) : null;
- return $this->assert($expected === $result, $message, $data);
- }
- /**
- * Assert that the actual result and the expected result are *not* identical using a strict
- * comparison.
- *
- * @see lithium\test\Unit::assert()
- * @param mixed $expected
- * @param mixed $result
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertNotIdentical($expected, $result, $message = '{:message}') {
- return $this->assert($expected !== $result, $message, compact('expected', 'result'));
- }
- /**
- * Assert that the result is strictly `true`.
- *
- * ```
- * $this->assertTrue(true, 'Boolean true'); // succeeds
- * $this->assertTrue('false', 'String has content'); // fails
- * $this->assertTrue(10, 'Non-Zero value'); // fails
- * ```
- *
- * @see lithium\test\Unit::assert()
- * @param mixed $result
- * @param string $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertTrue($result, $message = '{:message}') {
- $expected = true;
- return $this->assert($result === $expected, $message, compact('expected', 'result'));
- }
- /**
- * Assert that the result strictly is `false`.
- *
- * ```
- * $this->assertFalse(false, 'Boolean false'); // succeeds
- * $this->assertFalse('', 'String is empty'); // fails
- * $this->assertFalse(0, 'Zero value'); // fails
- * ```
- *
- * @see lithium\test\Unit::assert()
- * @param mixed $result
- * @param string $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertFalse($result, $message = '{:message}') {
- $expected = false;
- return $this->assert($result === $expected, $message, compact('expected', 'result'));
- }
- /**
- * Assert that the result is strictly `null`.
- *
- * @see lithium\test\Unit::assert()
- * @param mixed $result
- * @param string $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertNull($result, $message = '{:message}') {
- $expected = null;
- return $this->assert($result === null, $message, compact('expected', 'result'));
- }
- /**
- * Assert that the result is *not* strictly `null`.
- *
- * ```
- * $this->assertNotNull(1); // succeeds
- * $this->assertNotNull(null); // fails
- * ```
- *
- * @see lithium\test\Unit::assert()
- * @param mixed $result
- * @param string $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertNotNull($actual, $message = '{:message}') {
- return $this->assert($actual !== null, $message, [
- 'expected' => null,
- 'actual' => gettype($actual)
- ]);
- }
- /**
- * Assert that given result is empty.
- *
- * ```
- * $this->assertEmpty(''); // succeeds
- * $this->assertEmpty(0); // succeeds
- * $this->assertEmpty(0.0); // succeeds
- * $this->assertEmpty('0'); // succeeds
- * $this->assertEmpty(null); // succeeds
- * $this->assertEmpty(false); // succeeds
- * $this->assertEmpty([]); // succeeds
- * $this->assertEmpty(1); // fails
- * ```
- *
- * @link http://php.net/empty
- * @see lithium\test\Unit::assert()
- * @param string $actual
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertEmpty($actual, $message = '{:message}') {
- return $this->assert(empty($actual), $message, [
- 'expected' => $actual,
- 'result' => empty($actual)
- ]);
- }
- /**
- * Assert that given result is *not* empty.
- *
- * ```
- * $this->assertNotEmpty(1); // succeeds
- * $this->assertNotEmpty([]); // fails
- * ```
- *
- * @link http://php.net/empty
- * @see lithium\test\Unit::assert()
- * @param string $actual
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertNotEmpty($actual, $message = '{:message}') {
- return $this->assert(!empty($actual), $message, [
- 'expected' => $actual,
- 'result' => !empty($actual)
- ]);
- }
- /**
- * Assert that the code passed in a closure throws an exception or raises a PHP error. The
- * first argument to this method specifies which class name or message the exception must
- * have in order to make the assertion successful.
- *
- * @see lithium\test\Unit::assert()
- * @param mixed $expected A string indicating what the error text is expected to be. This can
- * be an exact string, a /-delimited regular expression, or true, indicating that
- * any error text is acceptable.
- * @param \Closure $closure A closure containing the code that should throw the exception.
- * @param string $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertException($expected, $closure, $message = '{:message}') {
- $result = null;
- try {
- $closure();
- $message = sprintf('An exception "%s" was expected but not thrown.', $expected);
- return $this->assert(false, $message, compact('expected', 'result'));
- } catch (Exception $e) {
- // fallthrough
- } catch (Error $e) {
- // fallthrough
- }
- $class = get_class($e);
- $eMessage = $e->getMessage();
- if (get_class($e) === $expected) {
- $result = $class;
- return $this->assert(true, $message, compact('expected', 'result'));
- }
- if ($eMessage === $expected) {
- $result = $eMessage;
- return $this->assert(true, $message, compact('expected', 'result'));
- }
- if (Validator::isRegex($expected) && preg_match($expected, $eMessage)) {
- $result = $eMessage;
- return $this->assert(true, $message, compact('expected', 'result'));
- }
- $message = sprintf(
- 'Exception "%s" was expected. Exception "%s" with message "%s" was thrown instead.',
- $expected, get_class($e), $eMessage
- );
- return $this->assert(false, $message);
- }
- /**
- * Assert that the code passed in a closure does not throw an exception matching the passed
- * expected exception.
- *
- * The value passed to `exepected` is either an exception class name or the expected message.
- *
- * @see lithium\test\Unit::assert()
- * @param mixed $expected A string indicating what the error text is not expected to be. This
- * can be an exact string, a /-delimited regular expression, or true, indicating
- * that any error text is acceptable.
- * @param \Closure $closure A closure containing the code that should throw the exception.
- * @param string $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertNotException($expected, $closure, $message = '{:message}') {
- $result = null;
- try {
- $closure();
- } catch (Exception $e) {
- $class = get_class($e);
- $eMessage = $e->getMessage();
- if (is_a($e, $expected)) {
- $result = $class;
- return $this->assert(false, $message, compact('expected', 'result'));
- }
- if ($eMessage === $expected) {
- $result = $eMessage;
- return $this->assert(false, $message, compact('expected', 'result'));
- }
- if (Validator::isRegex($expected) && preg_match($expected, $eMessage)) {
- $result = $eMessage;
- return $this->assert(false, $message, compact('expected', 'result'));
- }
- }
- $message = sprintf('Exception "%s" was not expected.', $expected);
- return $this->assert(true, $message, compact('expected', 'result'));
- }
- /**
- * Assert that the regular expression `$expected` is matched in the result.
- *
- * @see lithium\test\Unit::assert()
- * @param mixed $expected
- * @param mixed $result
- * @param string $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertPattern($expected, $result, $message = '{:message}') {
- list($expected, $result) = $this->_normalizeLineEndings($expected, $result);
- $params = compact('expected', 'result');
- return $this->assert(!!preg_match($expected, $result), $message, $params);
- }
- /**
- * Assert that the regular expression `$expected` is *not* matched in the result.
- *
- * @see lithium\test\Unit::assert()
- * @param mixed $expected
- * @param mixed $result
- * @param string $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertNotPattern($expected, $result, $message = '{:message}') {
- list($expected, $result) = $this->_normalizeLineEndings($expected, $result);
- $params = compact('expected', 'result');
- return $this->assert(!preg_match($expected, $result), $message, $params);
- }
- /**
- * Assert that given value matches the `sprintf` format.
- *
- * ```
- * $this->assertStringMatchesFormat('%d', '10'); // succeeds
- * $this->assertStringMatchesFormat('%d', '10.555'); // fails
- * ```
- *
- * @link http://php.net/sprintf
- * @link http://php.net/sscanf
- * @see lithium\test\Unit::assert()
- * @param string $expected Expected format using sscanf's format.
- * @param string $actual
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertStringMatchesFormat($expected, $actual, $message = '{:message}') {
- $result = sscanf($actual, $expected);
- return $this->assert($result[0] == $actual, $message, compact('expected', 'result'));
- }
- /**
- * Assert that given value does *not* matche the `sprintf` format.
- *
- * ```
- * $this->assertStringNotMatchesFormat('%d', '10.555'); // succeeds
- * $this->assertStringNotMatchesFormat('%d', '10'); // fails
- * ```
- *
- * @link http://php.net/sprintf
- * @link http://php.net/sscanf
- * @see lithium\test\Unit::assert()
- * @param string $expected Expected format using sscanf's format.
- * @param string $actual
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertStringNotMatchesFormat($expected, $actual, $message = '{:message}') {
- $result = sscanf($actual, $expected);
- return $this->assert($result[0] != $actual, $message, compact('expected', 'result'));
- }
- /**
- * Assert given result string has given suffix.
- *
- * ```
- * $this->assertStringEndsWith('bar', 'foobar'); // succeeds
- * $this->assertStringEndsWith('foo', 'foobar'); // fails
- * ```
- *
- * @param string $expected The suffix to check for.
- * @param string $actual
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertStringEndsWith($expected, $actual, $message = '{:message}') {
- return $this->assert(preg_match("/$expected$/", $actual, $matches) === 1, $message, [
- 'expected' => $expected,
- 'result' => $actual
- ]);
- }
- /**
- * Assert given result string has given prefix.
- *
- * ```
- * $this->assertStringStartsWith('foo', 'foobar'); // succeeds
- * $this->assertStringStartsWith('bar', 'foobar'); // fails
- * ```
- *
- * @param string $expected The prefix to check for.
- * @param string $actual
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertStringStartsWith($expected, $actual, $message = '{:message}') {
- return $this->assert(preg_match("/^$expected/", $actual, $matches) === 1, $message, [
- 'expected' => $expected,
- 'result' => $actual
- ]);
- }
- /**
- * Takes an array $expected and generates a regex from it to match the provided $string.
- * Samples for $expected:
- *
- * Checks for an input tag with a name attribute (contains any non-empty value) and an id
- * attribute that contains 'my-input':
- * ```
- * ['input' => ['name', 'id' => 'my-input']]
- * ```
- *
- * Checks for two p elements with some text in them:
- * ```
- * [
- * ['p' => true],
- * 'textA',
- * '/p',
- * ['p' => true],
- * 'textB',
- * '/p'
- * ]
- * ```
- *
- * You can also specify a pattern expression as part of the attribute values, or the tag
- * being defined, if you prepend the value with preg: and enclose it with slashes, like so:
- * ```
- * [
- * ['input' => ['name', 'id' => 'preg:/FieldName\d+/']],
- * 'preg:/My\s+field/'
- * ]
- * ```
- *
- * Important: This function is very forgiving about whitespace and also accepts any
- * permutation of attribute order. It will also allow whitespaces between specified tags.
- *
- * @see lithium\test\Unit::assert()
- * @param string $string An HTML/XHTML/XML string
- * @param array $expected An array, see above
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertTags($string, $expected) {
- $regex = [];
- $normalized = [];
- foreach ((array) $expected as $key => $val) {
- if (!is_numeric($key)) {
- $normalized[] = [$key => $val];
- } else {
- $normalized[] = $val;
- }
- }
- $i = 0;
- foreach ($normalized as $tags) {
- $i++;
- if (is_string($tags) && $tags[0] === '<') {
- $tags = [substr($tags, 1) => []];
- } elseif (is_string($tags)) {
- $tagsTrimmed = preg_replace('/\s+/m', '', $tags);
- if (preg_match('/^\*?\//', $tags, $match) && $tagsTrimmed !== '//') {
- $prefix = [null, null];
- if ($match[0] === '*/') {
- $prefix = ['Anything, ', '.*?'];
- }
- $regex[] = [
- sprintf('%sClose %s tag', $prefix[0], substr($tags, strlen($match[0]))),
- sprintf('%s<[\s]*\/[\s]*%s[\s]*>[\n\r]*', $prefix[1], substr(
- $tags, strlen($match[0])
- )),
- $i
- ];
- continue;
- }
- if (!empty($tags) && preg_match('/^regex\:\/(.+)\/$/i', $tags, $matches)) {
- $tags = $matches[1];
- $type = 'Regex matches';
- } else {
- $tags = preg_quote($tags, '/');
- $type = 'Text equals';
- }
- $regex[] = [sprintf('%s "%s"', $type, $tags), $tags, $i];
- continue;
- }
- foreach ($tags as $tag => $attributes) {
- $regex[] = [
- sprintf('Open %s tag', $tag),
- sprintf('[\s]*<%s', preg_quote($tag, '/')),
- $i
- ];
- if ($attributes === true) {
- $attributes = [];
- }
- $attrs = [];
- $explanations = [];
- foreach ($attributes as $attr => $val) {
- if (is_numeric($attr) && preg_match('/^regex\:\/(.+)\/$/i', $val, $matches)) {
- $attrs[] = $matches[1];
- $explanations[] = sprintf('Regex "%s" matches', $matches[1]);
- continue;
- } else {
- $quotes = '"';
- if (is_numeric($attr)) {
- $attr = $val;
- $val = '.+?';
- $explanations[] = sprintf('Attribute "%s" present', $attr);
- } elseif (
- !empty($val) && preg_match('/^regex\:\/(.+)\/$/i', $val, $matches)
- ) {
- $quotes = '"?';
- $val = $matches[1];
- $explanations[] = sprintf('Attribute "%s" matches "%s"', $attr, $val);
- } else {
- $explanations[] = sprintf('Attribute "%s" == "%s"', $attr, $val);
- $val = preg_quote($val, '/');
- }
- $attrs[] = '[\s]+' . preg_quote($attr, '/') . "={$quotes}{$val}{$quotes}";
- }
- }
- if ($attrs) {
- $permutations = $this->_arrayPermute($attrs);
- $permutationTokens = [];
- foreach ($permutations as $permutation) {
- $permutationTokens[] = join('', $permutation);
- }
- $regex[] = [
- sprintf('%s', join(', ', $explanations)),
- $permutationTokens,
- $i
- ];
- }
- $regex[] = [sprintf('End %s tag', $tag), '[\s]*\/?[\s]*>[\n\r]*', $i];
- }
- }
- foreach ($regex as $i => $assertation) {
- list($description, $expressions, $itemNum) = $assertation;
- $matches = false;
- foreach ((array) $expressions as $expression) {
- if (preg_match(sprintf('/^%s/s', $expression), $string, $match)) {
- $matches = true;
- $string = substr($string, strlen($match[0]));
- break;
- }
- }
- if (!$matches) {
- $this->assert(false, sprintf(
- '- Item #%d / regex #%d failed: %s', $itemNum, $i, $description
- ));
- return false;
- }
- }
- return $this->assert(true);
- }
- /**
- * Assert Cookie data is properly set in headers.
- *
- * The value passed to `exepected` is an array of the cookie data, with at least the key and
- * value expected, but can support any of the following keys:
- * - `key`: the expected key
- * - `value`: the expected value
- * - `path`: optionally specifiy a path
- * - `name`: optionally specify the cookie name
- * - `expires`: optionally assert a specific expire time
- *
- * @see lithium\test\Unit::assert()
- * @param array $expected
- * @param array $headers When empty, value of `headers_list()` is used.
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertCookie($expected, $headers = null) {
- $result = null;
- $matched = $this->_cookieMatch($expected, $headers);
- if (!$matched['match']) {
- $message = sprintf('%s - Cookie not found in headers.', $matched['pattern']);
- return $this->assert(false, $message, compact('expected', 'result'));
- }
- return $this->assert(true, '%s');
- }
- /**
- * Assert Cookie data is *not* set in headers.
- *
- * The value passed to `expected` is an array of the cookie data, with at least the key and
- * value expected, but can support any of the following keys:
- * - `key`: the expected key
- * - `value`: the expected value
- * - `path`: optionally specify a path
- * - `name`: optionally specify the cookie name
- * - `expires`: optionally assert a specific expire time
- *
- * @see lithium\test\Unit::assert()
- * @param array $expected
- * @param array $headers When empty, value of `headers_list()` is used.
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertNoCookie($expected, $headers = null) {
- $matched = $this->_cookieMatch($expected, $headers);
- if ($matched['match']) {
- $message = sprintf('%s - Cookie found in headers.', $matched['pattern']);
- return $this->assert(false, $message, compact('expected', 'result'));
- }
- return $this->assert(true, '%s');
- }
- /**
- * Match an `$expected` cookie with the given headers. If no headers are provided, then
- * the value of `headers_list()` will be used.
- *
- * @param array $expected
- * @param array $headers When empty, value of `headers_list()` will be used.
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- protected function _cookieMatch($expected, $headers) {
- $defaults = ['path' => '/', 'name' => '[\w.-]+'];
- $expected += $defaults;
- $headers = ($headers) ?: headers_list();
- $value = preg_quote(urlencode($expected['value']), '/');
- $key = explode('.', $expected['key']);
- $key = (count($key) === 1) ? '[' . current($key) . ']' : ('[' . join('][', $key) . ']');
- $key = preg_quote($key, '/');
- if (isset($expected['expires'])) {
- $expectedExpires = strtotime($expected['expires']);
- $expires = gmdate('D, d-M-Y H:i:s \G\M\T', $expectedExpires);
- $expires = preg_quote($expires, '/');
- $maxAge = $expectedExpires - time();
- } else {
- $expires = '(?:.+?)';
- $maxAge = '([0-9]+)';
- }
- $path = preg_quote($expected['path'], '/');
- $pattern = "/^Set\-Cookie:\s{$expected['name']}$key=$value;";
- $pattern .= "\sexpires=$expires;";
- $pattern .= "\sMax-Age=$maxAge;";
- $pattern .= "\spath=$path/";
- $match = false;
- foreach ($headers as $header) {
- if (preg_match($pattern, $header)) {
- $match = true;
- continue;
- }
- }
- return compact('match', 'pattern');
- }
- /**
- * Assert that the passed result array has expected number of elements.
- *
- * ```
- * $this->assertCount(1, ['foo']); // succeeds
- * $this->assertCount(2, ['foo', 'bar', 'bar']); // fails
- * ```
- *
- * @see lithium\test\Unit::assert()
- * @param integer $expected
- * @param array $array
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertCount($expected, $array, $message = '{:message}') {
- return $this->assert($expected === ($result = count($array)), $message, [
- 'expected' => $expected,
- 'result' => $result
- ]);
- }
- /**
- * Assert that the passed result array has *not* the expected number of elements.
- *
- * ```
- * $this->assertNotCount(2, ['foo', 'bar', 'bar']); // succeeds
- * $this->assertNotCount(1, ['foo']); // fails
- * ```
- *
- * @see lithium\test\Unit::assert()
- * @param integer $expected
- * @param array $array
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertNotCount($expected, $array, $message = '{:message}') {
- return $this->assert($expected !== ($result = count($array)), $message, [
- 'expected' => $expected,
- 'result' => $result
- ]);
- }
- /**
- * Assert that the result array has given key.
- *
- * ```
- * $this->assertArrayHasKey('bar', ['bar' => 'baz']); // succeeds
- * $this->assertArrayHasKey('foo', ['bar' => 'baz']); // fails
- * ```
- *
- * @see lithium\test\Unit::assert()
- * @param mixed $expected
- * @param array $array
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertArrayHasKey($key, $array, $message = '{:message}') {
- if (is_object($array) && $array instanceof \ArrayAccess) {
- $result = isset($array[$key]);
- } else {
- $result = array_key_exists($key, $array);
- }
- return $this->assert($result, $message, [
- 'expected' => $key,
- 'result' => $array
- ]);
- }
- /**
- * Assert that the result array does *not* have given key.
- *
- * ```
- * $this->assertArrayNotHasKey('foo', ['bar' => 'baz']); // succeeds
- * $this->assertArrayNotHasKey('bar', ['bar' => 'baz']); // fails
- * ```
- *
- * @see lithium\test\Unit::assert()
- * @param mixed $expected
- * @param array $array
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertArrayNotHasKey($key, $array, $message = '{:message}') {
- if (is_object($array) && $array instanceof \ArrayAccess) {
- $result = isset($array[$key]);
- } else {
- $result = array_key_exists($key, $array);
- }
- return $this->assert(!$result, $message, [
- 'expected' => $key,
- 'result' => $array
- ]);
- }
- /**
- * Assert that `$haystack` contains `$needle` as a value.
- *
- * ```
- * $this->assertContains('foo', ['foo', 'bar', 'baz']); // succeeds
- * $this->assertContains(4, [1,2,3]); // fails
- * ```
- *
- * @see lithium\test\Unit::assert()
- * @param string $needle The needle you are looking for.
- * @param mixed $haystack An array, iterable object, or string.
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertContains($needle, $haystack, $message = '{:message}') {
- if (is_string($haystack)) {
- return $this->assert(strpos($haystack, $needle) !== false, $message, [
- 'expected' => $needle,
- 'result' => $haystack
- ]);
- }
- foreach ($haystack as $key => $value) {
- if ($value === $needle) {
- return $this->assert(true, $message, [
- 'expected' => $needle,
- 'result' => $haystack
- ]);
- }
- }
- return $this->assert(false, $message, [
- 'expected' => $needle,
- 'result' => $haystack
- ]);
- }
- /**
- * Assert that `$haystack` does *not* contain `$needle` as a value.
- *
- * ```
- * $this->assertNotContains(4, [1,2,3]); // succeeds
- * $this->assertNotContains('foo', ['foo', 'bar', 'baz']); // fails
- * ```
- *
- * @see lithium\test\Unit::assert()
- * @param string $needle The needle you are looking for.
- * @param miexed $haystack Array or iterable object or a string.
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertNotContains($needle, $haystack, $message = '{:message}') {
- if (is_string($haystack)) {
- return $this->assert(strpos($haystack, $needle) === false, $message, [
- 'expected' => $needle,
- 'result' => $haystack
- ]);
- }
- foreach ($haystack as $key => $value) {
- if ($value === $needle) {
- return $this->assert(false, $message, [
- 'expected' => $needle,
- 'result' => $haystack
- ]);
- }
- }
- return $this->assert(true, $message, [
- 'expected' => $needle,
- 'result' => $haystack
- ]);
- }
- /**
- * Assert that `$haystack` does only contain item of given type.
- *
- * ```
- * $this->assertContainsOnly('integer', [1,2,3]); // succeeds
- * $this->assertContainsOnly('integer', ['foo', 'bar', 'baz']); // fails
- * ```
- *
- * @see lithium\test\Unit::$_internalTypes
- * @see lithium\test\Unit::assert()
- * @param string $type
- * @param array|object $haystack Array or iterable object.
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertContainsOnly($type, $haystack, $message = '{:message}') {
- $method = static::$_internalTypes[$type];
- foreach ($haystack as $key => $value) {
- if (!$method($value)) {
- return $this->assert(false, $message, [
- 'expected' => $type,
- 'result' => $haystack
- ]);
- }
- }
- return $this->assert(true, $message, [
- 'expected' => $type,
- 'result' => $haystack
- ]);
- }
- /**
- * Assert that `$haystack` hasn't any items of given type.
- *
- * ```
- * $this->assertNotContainsOnly('integer', ['foo', 'bar', 'baz']); // succeeds
- * $this->assertNotContainsOnly('integer', [1,2,3]); // fails
- * ```
- *
- * @see lithium\test\Unit::$_internalTypes
- * @see lithium\test\Unit::assert()
- * @param string $type
- * @param array|object $haystack Array or iterable object.
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertNotContainsOnly($type, $haystack, $message = '{:message}') {
- $method = static::$_internalTypes[$type];
- foreach ($haystack as $key => $value) {
- if (!$method($value)) {
- return $this->assert(true, $message, [
- 'expected' => $type,
- 'result' => $haystack
- ]);
- }
- }
- return $this->assert(false, $message, [
- 'expected' => $type,
- 'result' => $haystack
- ]);
- }
- /**
- * Assert that `$haystack` contains only instances of given class.
- *
- * ```
- * $this->assertContainsOnlyInstancesOf('stdClass', [new \stdClass]); // succeeds
- * $this->assertContainsOnlyInstancesOf('stdClass', [new \lithium\test\Unit]); // fails
- * ```
- *
- * @see lithium\test\Unit::assert()
- * @param string $class
- * @param array|object $haystack Array or iterable object.
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertContainsOnlyInstancesOf($class, $haystack, $message = '{:message}') {
- $result = [];
- foreach ($haystack as $key => &$value) {
- if (!is_a($value, $class)) {
- $result[$key] =& $value;
- break;
- }
- }
- return $this->assert(empty($result), $message, [
- 'expected' => $class,
- 'result' => $result
- ]);
- }
- /**
- * Assert that `$expected` is greater than `$actual`.
- *
- * ```
- * $this->assertGreaterThan(5, 3); // succeeds
- * $this->assertGreaterThan(3, 5); // fails
- * ```
- *
- * @see lithium\test\Unit::assert()
- * @param float|integer $expected
- * @param float|integer $actual
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertGreaterThan($expected, $actual, $message = '{:message}') {
- return $this->assert($expected > $actual, $message, [
- 'expected' => $expected,
- 'result' => $actual
- ]);
- }
- /**
- * Assert that `$expected` is greater than or equal to `$actual`.
- *
- * ```
- * $this->assertGreaterThanOrEqual(5, 5); // succeeds
- * $this->assertGreaterThanOrEqual(3, 5); // fails
- * ```
- *
- * @see lithium\test\Unit::assert()
- * @param float|integer $expected
- * @param float|integer $actual
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertGreaterThanOrEqual($expected, $actual, $message = '{:message}') {
- return $this->assert($expected >= $actual, $message, [
- 'expected' => $expected,
- 'result' => $actual
- ]);
- }
- /**
- * Assert that `$expected` is less than `$actual`.
- *
- * ```
- * $this->assertLessThan(3, 5); // succeeds
- * $this->assertLessThan(5, 3); // fails
- * ```
- *
- * @see lithium\test\Unit::assert()
- * @param float|integer $expected
- * @param float|integer $actual
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertLessThan($expected, $actual, $message = '{:message}') {
- return $this->assert($expected < $actual, $message, [
- 'expected' => $expected,
- 'result' => $actual
- ]);
- }
- /**
- * Assert that `$expected` is less than or equal to `$actual`.
- *
- * ```
- * $this->assertLessThanOrEqual(5, 5); // succeeds
- * $this->assertLessThanOrEqual(5, 3); // fails
- * ```
- *
- * @see lithium\test\Unit::assert()
- * @param float|integer $expected
- * @param float|integer $actual
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertLessThanOrEqual($expected, $actual, $message = '{:message}') {
- return $this->assert($expected <= $actual, $message, [
- 'expected' => $expected,
- 'result' => $actual
- ]);
- }
- /**
- * Assert that `$actual` is an instance of `$expected`.
- *
- * ```
- * $this->assertInstanceOf('stdClass', new stdClass); // succeeds
- * $this->assertInstanceOf('ReflectionClass', new stdClass); // fails
- * ```
- *
- * @see lithium\test\Unit::assert()
- * @param string $expected Fully namespaced expected class.
- * @param object $actual Object you are testing.
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertInstanceOf($expected, $actual, $message = '{:message}') {
- return $this->assert(is_a($actual, $expected), $message, [
- 'expected' => $expected,
- 'result' => get_class($actual)
- ]);
- }
- /**
- * Assert that `$actual` is *not* an instance of `$expected`.
- *
- * ```
- * $this->assertNotInstanceOf('ReflectionClass', new stdClass); // succeeds
- * $this->assertNotInstanceOf('stdClass', new stdClass); // fails
- * ```
- *
- * @see lithium\test\Unit::assert()
- * @param string $expected Fully namespaced expected class.
- * @param object $actual Object you are testing.
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertNotInstanceOf($expected, $actual, $message = '{:message}') {
- return $this->assert(!is_a($actual, $expected), $message, [
- 'expected' => $expected,
- 'result' => is_object($actual) ? get_class($actual) : gettype($actual),
- ]);
- }
- /**
- * Assert that `$actual` is of given type.
- *
- * ```
- * $this->assertInternalType('string', 'foobar'); // succeeds
- * $this->assertInternalType('integer', 'foobar'); // fails
- * ```
- *
- * @see lithium\test\Unit::$_internalTypes
- * @see lithium\test\Unit::assert()
- * @param string $expected Internal type.
- * @param object $actual Object you are testing.
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertInternalType($expected, $actual, $message = '{:message}') {
- $method = static::$_internalTypes[$expected];
- return $this->assert($method($actual), $message, [
- 'expected' => $expected,
- 'result' => gettype($actual)
- ]);
- }
- /**
- * Assert that `$actual` is *not* of given type.
- *
- * ```
- * $this->assertNotInternalType('integer', 'foobar'); // succeeds
- * $this->assertNotInternalType('string', 'foobar'); // fails
- * ```
- *
- * @see lithium\test\Unit::$_internalTypes
- * @see lithium\test\Unit::assert()
- * @param string $expected Internal type.
- * @param object $actual Object you are testing.
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertNotInternalType($expected, $actual, $message = '{:message}') {
- $method = static::$_internalTypes[$expected];
- return $this->assert(!$method($actual), $message, [
- 'expected' => $expected,
- 'result' => gettype($actual)
- ]);
- }
- /**
- * Assert that the file contents of `$expected` are equal to the contents of `$actual`.
- *
- * ```
- * $this->assertFileEquals('/tmp/foo.txt', '/tmp/foo.txt'); // succeeds
- * $this->assertFileEquals('/tmp/foo.txt', '/tmp/bar.txt'); // fails
- * ```
- *
- * @see lithium\test\Unit::assert()
- * @param string $expected Absolute path to the expected file.
- * @param string $actual Absolute path to the actual file.
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertFileEquals($expected, $actual, $message = '{:message}') {
- $expected = md5_file($expected);
- $result = md5_file($actual);
- return $this->assert($expected === $result, $message, compact('expected', 'result'));
- }
- /**
- * Assert that the file contents of `$expected` are *not* equal to the contents of `$actual`.
- *
- * ```
- * $this->assertFileNotEquals('/tmp/foo.txt', '/tmp/bar.txt'); // succeeds
- * $this->assertFileNotEquals('/tmp/foo.txt', '/tmp/foo.txt'); // fails
- * ```
- *
- * @see lithium\test\Unit::assert()
- * @param string $expected Absolute path to the expected file.
- * @param string $actual Absolute path to the actual file.
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertFileNotEquals($expected, $actual, $message = '{:message}') {
- $expected = md5_file($expected);
- $result = md5_file($actual);
- return $this->assert($expected !== $result, $message, compact('expected', 'result'));
- }
- /**
- * Assert that a file exists.
- *
- * ```
- * $this->assertFileExists(__FILE__); // succeeds
- * $this->assertFileExists('/tmp/bar.txt'); // fails
- * ```
- *
- * @see lithium\test\Unit::assert()
- * @param string $actual Absolute path to the actual file.
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertFileExists($actual, $message = '{:message}') {
- return $this->assert(file_exists($actual), $message, [
- 'expected' => $actual,
- 'result' => file_exists($actual)
- ]);
- }
- /**
- * Assert that a file does *not* exist.
- *
- * ```
- * $this->assertFileNotExists('/tmp/bar.txt'); // succeeds
- * $this->assertFileNotExists(__FILE__); // fails
- * ```
- *
- * @see lithium\test\Unit::assert()
- * @param string $actual Absolute path to the actual file.
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertFileNotExists($actual, $message = '{:message}') {
- return $this->assert(!file_exists($actual), $message, [
- 'expected' => $actual,
- 'result' => !file_exists($actual)
- ]);
- }
- /**
- * Assert that a class has a given attribute.
- *
- * ```
- * $this->assertClassHasAttribute('__construct', 'ReflectionClass'); // succeeds
- * $this->assertClassHasAttribute('name', 'ReflectionClass'); // fails
- * ```
- *
- * @see lithium\test\Unit::assert()
- * @see lithium\test\Unit::assertObjectHasAttribute()
- * @throws InvalidArgumentException When $class does not exist.
- * @param mixed $attributeName
- * @param string $class
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertClassHasAttribute($attributeName, $class, $message = '{:message}') {
- if (!is_string($class)) {
- throw new InvalidArgumentException('Argument $class must be a string');
- }
- $object = new ReflectionClass($class);
- return $this->assert($object->hasProperty($attributeName), $message, [
- 'expected' => $attributeName,
- 'result' => $object->getProperties()
- ]);
- }
- /**
- * Assert that a class does *not* have a given attribute.
- *
- * ```
- * $this->assertClassNotHasAttribute('name', 'ReflectionClass'); // succeeds
- * $this->assertClassNotHasAttribute('__construct', 'ReflectionClass'); // fails
- * ```
- *
- * @see lithium\test\Unit::assert()
- * @see lithium\test\Unit::assertObjectHasAttribute()
- * @throws InvalidArgumentException When $class does not exist.
- * @param mixed $attributeName
- * @param string $class
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertClassNotHasAttribute($attributeName, $class, $message = '{:message}') {
- if (!is_string($class)) {
- throw new InvalidArgumentException('Argument $class must be a string.');
- }
- $object = new ReflectionClass($class);
- return $this->assert(!$object->hasProperty($attributeName), $message, [
- 'expected' => $attributeName,
- 'result' => $object->getProperties()
- ]);
- }
- /**
- * Assert that a class does have a given _static_ attribute.
- *
- * ```
- * $this->assertClassHasStaticAttribute('_methodFilters', '\lithium\core\StaticObjectDeprecated'); // succeeds
- * $this->assertClassHasStaticAttribute('foobar', '\lithium\core\StaticObjectDeprecated'); // fails
- * ```
- *
- * @see lithium\test\Unit::assert()
- * @param mixed $attributeName
- * @param string $class
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertClassHasStaticAttribute($attributeName, $class, $message = '{:message}') {
- $object = new ReflectionClass($class);
- if ($object->hasProperty($attributeName)) {
- $attribute = $object->getProperty($attributeName);
- return $this->assert($attribute->isStatic(), $message, [
- 'expected' => $attributeName,
- 'result' => $object->getProperties()
- ]);
- }
- return $this->assert(false, $message, [
- 'expected' => $attributeName,
- 'result' => $object->getProperties()
- ]);
- }
- /**
- * Assert that a class does *not* have a given _static_ attribute.
- *
- * ```
- * $this->assertClassNotHasStaticAttribute('foobar', '\lithium\core\StaticObjectDeprecated'); // succeeds
- * $this->assertClassNotHasStaticAttribute('_methodFilters', '\lithium\core\StaticObjectDeprecated'); // fails
- * ```
- *
- * @see lithium\test\Unit::assert()
- * @param mixed $attributeName
- * @param string $class
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertClassNotHasStaticAttribute($attrName, $class, $message = '{:message}') {
- $object = new ReflectionClass($class);
- if ($object->hasProperty($attrName)) {
- $attribute = $object->getProperty($attrName);
- return $this->assert(!$attribute->isStatic(), $message, [
- 'expected' => $attrName,
- 'result' => $object->getProperties()
- ]);
- }
- return $this->assert(true, $message, [
- 'expected' => $attrName,
- 'result' => $object->getProperties()
- ]);
- }
- /**
- * Assert that `$object` has given attribute.
- *
- * ```
- * $this->assertObjectHasAttribute('__construct', 'ReflectionClass'); // succeeds
- * $this->assertObjectHasAttribute('name', 'ReflectionClass'); // fails
- * ```
- *
- * @see lithium\test\Unit::assert()
- * @throws InvalidArgumentException When $object is not an object.
- * @param string $attributeName
- * @param string $object
- * @param string|boolean $message
- * @return boolean `true` if the assertion succeeded, `false` otherwise.
- */
- public function assertObjectHasAttribute($attributeName, $object, $message = '{:message}') {
- if (!is_object($object)) {
- throw new InvalidArgumentException('Second argument $object must be an object.');
- }
- $object = new ReflectionClass($object);
- return $this->assert($object->hasProperty($attributeName), $message, [
- 'expected' => $attributeName,
- 'result' => $object->getProperties()
- ]);
- }
- /**
- * Assert that `$object` does *not* have given attribute.
- *
- * ```
- * $this->assertObjectNotHasAttribute('name', 'ReflectionClass'); // succeeds
- * $this->assertObjectNotHasAttribute('__construct', 'ReflectionClass'); // fails
- * ```
- *
- * @see lithium\test\Unit::assert()
- * @throws InvalidArgumentException When $object is not an object.
- * @param string $attributeName
- * @param string $object
- * @param string|boolean $message
- * @return boolean `true` if the assertion succee…
Large files files are truncated, but you can click here to view the full file