%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /data/www_bck/varak.net_bck/warhammer.varak.net/vendor/nette/tester/src/Framework/
Upload File :
Create Path :
Current File : //data/www_bck/varak.net_bck/warhammer.varak.net/vendor/nette/tester/src/Framework/Assert.php

<?php

/**
 * This file is part of the Nette Tester.
 * Copyright (c) 2009 David Grudl (https://davidgrudl.com)
 */

namespace Tester;


/**
 * Assertion test helpers.
 */
class Assert
{
	/** used by equal() for comparing floats */
	const EPSILON = 1e-10;

	/** used by match(); in values, each $ followed by number is backreference */
	public static $patterns = [
		'%%' => '%',            // one % character
		'%a%' => '[^\r\n]+',    // one or more of anything except the end of line characters
		'%a\?%' => '[^\r\n]*',  // zero or more of anything except the end of line characters
		'%A%' => '.+',          // one or more of anything including the end of line characters
		'%A\?%' => '.*',        // zero or more of anything including the end of line characters
		'%s%' => '[\t ]+',      // one or more white space characters except the end of line characters
		'%s\?%' => '[\t ]*',    // zero or more white space characters except the end of line characters
		'%S%' => '\S+',         // one or more of characters except the white space
		'%S\?%' => '\S*',       // zero or more of characters except the white space
		'%c%' => '[^\r\n]',     // a single character of any sort (except the end of line)
		'%d%' => '[0-9]+',      // one or more digits
		'%d\?%' => '[0-9]*',    // zero or more digits
		'%i%' => '[+-]?[0-9]+', // signed integer value
		'%f%' => '[+-]?\.?\d+\.?\d*(?:[Ee][+-]?\d+)?', // floating point number
		'%h%' => '[0-9a-fA-F]+', // one or more HEX digits
		'%w%' => '[0-9a-zA-Z_]+', //one or more alphanumeric characters
		'%ds%' => '[\\\\/]',    // directory separator
		'%(\[.+\][+*?{},\d]*)%' => '$1', // range
	];

	/** @var callable  function (AssertException $exception) */
	public static $onFailure;

	/** @var int  the count of assertions */
	public static $counter = 0;


	/**
	 * Checks assertion. Values must be exactly the same.
	 * @return void
	 */
	public static function same($expected, $actual, $description = null)
	{
		self::$counter++;
		if ($actual !== $expected) {
			self::fail(self::describe('%1 should be %2', $description), $actual, $expected);
		}
	}


	/**
	 * Checks assertion. Values must not be exactly the same.
	 * @return void
	 */
	public static function notSame($expected, $actual, $description = null)
	{
		self::$counter++;
		if ($actual === $expected) {
			self::fail(self::describe('%1 should not be %2', $description), $actual, $expected);
		}
	}


	/**
	 * Checks assertion. The identity of objects and the order of keys in the arrays are ignored.
	 * @return void
	 */
	public static function equal($expected, $actual, $description = null)
	{
		self::$counter++;
		if (!self::isEqual($expected, $actual)) {
			self::fail(self::describe('%1 should be equal to %2', $description), $actual, $expected);
		}
	}


	/**
	 * Checks assertion. The identity of objects and the order of keys in the arrays are ignored.
	 * @return void
	 */
	public static function notEqual($expected, $actual, $description = null)
	{
		self::$counter++;
		if (self::isEqual($expected, $actual)) {
			self::fail(self::describe('%1 should not be equal to %2', $description), $actual, $expected);
		}
	}


	/**
	 * Checks assertion. Values must contains expected needle.
	 * @return void
	 */
	public static function contains($needle, $actual, $description = null)
	{
		self::$counter++;
		if (is_array($actual)) {
			if (!in_array($needle, $actual, true)) {
				self::fail(self::describe('%1 should contain %2', $description), $actual, $needle);
			}
		} elseif (is_string($actual)) {
			if ($needle !== '' && strpos($actual, $needle) === false) {
				self::fail(self::describe('%1 should contain %2', $description), $actual, $needle);
			}
		} else {
			self::fail(self::describe('%1 should be string or array', $description), $actual);
		}
	}


	/**
	 * Checks assertion. Values must not contains expected needle.
	 * @return void
	 */
	public static function notContains($needle, $actual, $description = null)
	{
		self::$counter++;
		if (is_array($actual)) {
			if (in_array($needle, $actual, true)) {
				self::fail(self::describe('%1 should not contain %2', $description), $actual, $needle);
			}
		} elseif (is_string($actual)) {
			if ($needle === '' || strpos($actual, $needle) !== false) {
				self::fail(self::describe('%1 should not contain %2', $description), $actual, $needle);
			}
		} else {
			self::fail(self::describe('%1 should be string or array', $description), $actual);
		}
	}


	/**
	 * Checks TRUE assertion.
	 * @param  mixed  actual
	 * @param  string  fail message
	 * @return void
	 */
	public static function true($actual, $description = null)
	{
		self::$counter++;
		if ($actual !== true) {
			self::fail(self::describe('%1 should be TRUE', $description), $actual);
		}
	}


	/**
	 * Checks FALSE assertion.
	 * @param  mixed  actual
	 * @param  string  fail message
	 * @return void
	 */
	public static function false($actual, $description = null)
	{
		self::$counter++;
		if ($actual !== false) {
			self::fail(self::describe('%1 should be FALSE', $description), $actual);
		}
	}


	/**
	 * Checks NULL assertion.
	 * @param  mixed  actual
	 * @param  string  fail message
	 * @return void
	 */
	public static function null($actual, $description = null)
	{
		self::$counter++;
		if ($actual !== null) {
			self::fail(self::describe('%1 should be NULL', $description), $actual);
		}
	}


	/**
	 * Checks Not a Number assertion.
	 * @param  mixed  actual
	 * @param  string  fail message
	 * @return void
	 */
	public static function nan($actual, $description = null)
	{
		self::$counter++;
		if (!is_float($actual) || !is_nan($actual)) {
			self::fail(self::describe('%1 should be NAN', $description), $actual);
		}
	}


	/**
	 * Checks truthy assertion.
	 * @param  mixed  actual
	 * @param  string  fail message
	 * @return void
	 */
	public static function truthy($actual, $description = null)
	{
		self::$counter++;
		if (!$actual) {
			self::fail(self::describe('%1 should be truthy', $description), $actual);
		}
	}


	/**
	 * Checks falsey (empty) assertion.
	 * @param  mixed  actual
	 * @param  string  fail message
	 * @return void
	 */
	public static function falsey($actual, $description = null)
	{
		self::$counter++;
		if ($actual) {
			self::fail(self::describe('%1 should be falsey', $description), $actual);
		}
	}


	/**
	 * Checks if subject has expected count.
	 * @param  int    expected count
	 * @param  mixed  subject
	 * @param  string  fail message
	 * @return void
	 */
	public static function count($count, $value, $description = null)
	{
		self::$counter++;
		if (!$value instanceof \Countable && !is_array($value)) {
			self::fail(self::describe('%1 should be array or countable object', $description), $value);

		} elseif (count($value) !== $count) {
			self::fail(self::describe('Count %1 should be %2', $description), count($value), $count);
		}
	}


	/**
	 * Checks assertion.
	 * @return void
	 */
	public static function type($type, $value, $description = null)
	{
		self::$counter++;
		if (!is_object($type) && !is_string($type)) {
			throw new \Exception('Type must be a object or a string.');

		} elseif ($type === 'list') {
			if (!is_array($value) || ($value && array_keys($value) !== range(0, count($value) - 1))) {
				self::fail(self::describe("%1 should be $type", $description), $value);
			}

		} elseif (in_array($type, ['array', 'bool', 'callable', 'float',
			'int', 'integer', 'null', 'object', 'resource', 'scalar', 'string', ], true)
		) {
			if (!call_user_func("is_$type", $value)) {
				self::fail(self::describe(gettype($value) . " should be $type", $description));
			}

		} elseif (!$value instanceof $type) {
			$actual = is_object($value) ? get_class($value) : gettype($value);
			self::fail(self::describe("$actual should be instance of $type", $description));
		}
	}


	/**
	 * Checks if the function throws exception.
	 * @param  callable
	 * @param  string class
	 * @param  string message
	 * @param  int code
	 * @return \Exception|\Throwable
	 */
	public static function exception(callable $function, $class, $message = null, $code = null)
	{
		self::$counter++;
		$e = null;
		try {
			call_user_func($function);
		} catch (\Exception $e) {
		} catch (\Throwable $e) {
		}
		if ($e === null) {
			self::fail("$class was expected, but none was thrown");

		} elseif (!$e instanceof $class) {
			self::fail("$class was expected but got " . get_class($e) . ($e->getMessage() ? " ({$e->getMessage()})" : ''), null, null, $e);

		} elseif ($message && !self::isMatching($message, $e->getMessage())) {
			self::fail("$class with a message matching %2 was expected but got %1", $e->getMessage(), $message);

		} elseif ($code !== null && $e->getCode() !== $code) {
			self::fail("$class with a code %2 was expected but got %1", $e->getCode(), $code);
		}
		return $e;
	}


	/**
	 * Checks if the function throws exception, alias for exception().
	 * @return \Exception|\Throwable
	 */
	public static function throws(callable $function, $class, $message = null, $code = null)
	{
		return self::exception($function, $class, $message, $code);
	}


	/**
	 * Checks if the function generates PHP error or throws exception.
	 * @param  callable
	 * @param  int|string|array
	 * @param  string message
	 * @return null|\Exception|\Throwable
	 */
	public static function error(callable $function, $expectedType, $expectedMessage = null)
	{
		if (is_string($expectedType) && !preg_match('#^E_[A-Z_]+\z#', $expectedType)) {
			return static::exception($function, $expectedType, $expectedMessage);
		}

		self::$counter++;
		$expected = is_array($expectedType) ? $expectedType : [[$expectedType, $expectedMessage]];
		foreach ($expected as &$item) {
			$item = ((array) $item) + [null, null];
			$expectedType = $item[0];
			if (is_int($expectedType)) {
				$item[2] = Helpers::errorTypeToString($expectedType);
			} elseif (is_string($expectedType)) {
				$item[0] = constant($item[2] = $expectedType);
			} else {
				throw new \Exception('Error type must be E_* constant.');
			}
		}

		set_error_handler(function ($severity, $message, $file, $line) use (&$expected) {
			if (($severity & error_reporting()) !== $severity) {
				return;
			}

			$errorStr = Helpers::errorTypeToString($severity) . ($message ? " ($message)" : '');
			list($expectedType, $expectedMessage, $expectedTypeStr) = array_shift($expected);
			if ($expectedType === null) {
				self::fail("Generated more errors than expected: $errorStr was generated in file $file on line $line");

			} elseif ($severity !== $expectedType) {
				self::fail("$expectedTypeStr was expected, but $errorStr was generated in file $file on line $line");

			} elseif ($expectedMessage && !self::isMatching($expectedMessage, $message)) {
				self::fail("$expectedTypeStr with a message matching %2 was expected but got %1", $message, $expectedMessage);
			}
		});

		reset($expected);
		try {
			call_user_func($function);
			restore_error_handler();
		} catch (\Exception $e) {
			restore_error_handler();
			throw $e;
		}

		if ($expected) {
			self::fail('Error was expected, but was not generated');
		}
	}


	/**
	 * Checks that the function does not generate PHP error and does not throw exception.
	 * @param  callable
	 * @return void
	 */
	public static function noError($function)
	{
		self::error($function, []);
	}


	/**
	 * Compares result using regular expression or mask:
	 *   %a%    one or more of anything except the end of line characters
	 *   %a?%   zero or more of anything except the end of line characters
	 *   %A%    one or more of anything including the end of line characters
	 *   %A?%   zero or more of anything including the end of line characters
	 *   %s%    one or more white space characters except the end of line characters
	 *   %s?%   zero or more white space characters except the end of line characters
	 *   %S%    one or more of characters except the white space
	 *   %S?%   zero or more of characters except the white space
	 *   %c%    a single character of any sort (except the end of line)
	 *   %d%    one or more digits
	 *   %d?%   zero or more digits
	 *   %i%    signed integer value
	 *   %f%    floating point number
	 *   %h%    one or more HEX digits
	 * @param  string  mask|regexp; only delimiters ~ and # are supported for regexp
	 * @param  string actual
	 * @param  string  fail message
	 * @return void
	 */
	public static function match($pattern, $actual, $description = null)
	{
		self::$counter++;
		if (!is_string($pattern)) {
			throw new \Exception('Pattern must be a string.');

		} elseif (!is_scalar($actual)) {
			self::fail(self::describe('%1 should match %2', $description), $actual, $pattern);

		} elseif (!self::isMatching($pattern, $actual)) {
			list($pattern, $actual) = self::expandMatchingPatterns($pattern, $actual);
			self::fail(self::describe('%1 should match %2', $description), $actual, $pattern);
		}
	}


	/**
	 * Compares results using mask sorted in file.
	 * @return void
	 */
	public static function matchFile($file, $actual, $description = null)
	{
		self::$counter++;
		$pattern = @file_get_contents($file); // @ is escalated to exception
		if ($pattern === false) {
			throw new \Exception("Unable to read file '$file'.");

		} elseif (!is_scalar($actual)) {
			self::fail(self::describe('%1 should match %2', $description), $actual, $pattern);

		} elseif (!self::isMatching($pattern, $actual)) {
			list($pattern, $actual) = self::expandMatchingPatterns($pattern, $actual);
			self::fail(self::describe('%1 should match %2', $description), $actual, $pattern);
		}
	}


	/**
	 * Failed assertion
	 * @return void
	 */
	public static function fail($message, $actual = null, $expected = null, $previous = null)
	{
		$e = new AssertException($message, $expected, $actual, $previous);
		if (self::$onFailure) {
			call_user_func(self::$onFailure, $e);
		} else {
			throw $e;
		}
	}


	private static function describe($reason, $description)
	{
		return ($description ? $description . ': ' : '') . $reason;
	}


	public static function with($obj, \Closure $closure)
	{
		return $closure->bindTo($obj, $obj)->__invoke();
	}


	/********************* helpers ****************d*g**/


	/**
	 * Compares using mask.
	 * @return bool
	 * @internal
	 */
	public static function isMatching($pattern, $actual, $strict = false)
	{
		if (!is_string($pattern) || !is_scalar($actual)) {
			throw new \Exception('Value and pattern must be strings.');
		}

		$old = ini_set('pcre.backtrack_limit', '10000000');

		if (!self::isPcre($pattern)) {
			$utf8 = preg_match('#\x80-\x{10FFFF}]#u', $pattern) ? 'u' : '';
			$suffix = ($strict ? '\z#sU' : '\s*$#sU') . $utf8;
			$patterns = static::$patterns + [
				'[.\\\\+*?[^$(){|\#]' => '\$0', // preg quoting
				'\x00' => '\x00',
				'[\t ]*\r?\n' => '[\t ]*\r?\n', // right trim
			];
			$pattern = '#^' . preg_replace_callback('#' . implode('|', array_keys($patterns)) . '#U' . $utf8, function ($m) use ($patterns) {
				foreach ($patterns as $re => $replacement) {
					$s = preg_replace("#^$re\\z#", str_replace('\\', '\\\\', $replacement), $m[0], 1, $count);
					if ($count) {
						return $s;
					}
				}
			}, rtrim($pattern, " \t\n\r")) . $suffix;
		}

		$res = preg_match($pattern, (string) $actual);
		ini_set('pcre.backtrack_limit', $old);
		if ($res === false || preg_last_error()) {
			throw new \Exception('Error while executing regular expression. (PREG Error Code ' . preg_last_error() . ')');
		}
		return (bool) $res;
	}


	/**
	 * @return array
	 * @internal
	 */
	public static function expandMatchingPatterns($pattern, $actual)
	{
		if (self::isPcre($pattern)) {
			return [$pattern, $actual];
		}

		$parts = preg_split('#(%)#', $pattern, -1, PREG_SPLIT_DELIM_CAPTURE);
		for ($i = count($parts); $i >= 0; $i--) {
			$patternX = implode(array_slice($parts, 0, $i));
			$patternY = "$patternX%A?%";
			if (self::isMatching($patternY, $actual)) {
				$patternZ = implode(array_slice($parts, $i));
				break;
			}
		}

		foreach (['%A%', '%A?%'] as $greedyPattern) {
			if (substr($patternX, -strlen($greedyPattern)) === $greedyPattern) {
				$patternX = substr($patternX, 0, -strlen($greedyPattern));
				$patternY = "$patternX%A?%";
				$patternZ = $greedyPattern . $patternZ;
				break;
			}
		}

		$low = 0;
		$high = strlen($actual);
		while ($low <= $high) {
			$mid = ($low + $high) >> 1;
			if (self::isMatching($patternY, substr($actual, 0, $mid))) {
				$high = $mid - 1;
			} else {
				$low = $mid + 1;
			}
		}

		$low = $high + 2;
		$high = strlen($actual);
		while ($low <= $high) {
			$mid = ($low + $high) >> 1;
			if (!self::isMatching($patternX, substr($actual, 0, $mid), true)) {
				$high = $mid - 1;
			} else {
				$low = $mid + 1;
			}
		}

		$actualX = substr($actual, 0, $high);
		$actualZ = substr($actual, $high);

		return [
			$actualX . rtrim(preg_replace('#[\t ]*\r?\n#', "\n", $patternZ)),
			$actualX . rtrim(preg_replace('#[\t ]*\r?\n#', "\n", $actualZ)),
		];
	}


	/**
	 * Compares two structures. Ignores the identity of objects and the order of keys in the arrays.
	 * @return bool
	 */
	private static function isEqual($expected, $actual, $level = 0, $objects = null)
	{
		if ($level > 10) {
			throw new \Exception('Nesting level too deep or recursive dependency.');
		}

		if (is_float($expected) && is_float($actual) && is_finite($expected) && is_finite($actual)) {
			$diff = abs($expected - $actual);
			return ($diff < self::EPSILON) || ($diff / max(abs($expected), abs($actual)) < self::EPSILON);
		}

		if (is_object($expected) && is_object($actual) && get_class($expected) === get_class($actual)) {
			$objects = $objects ? clone $objects : new \SplObjectStorage;
			if (isset($objects[$expected])) {
				return $objects[$expected] === $actual;
			} elseif ($expected === $actual) {
				return true;
			}
			$objects[$expected] = $actual;
			$objects[$actual] = $expected;
			$expected = (array) $expected;
			$actual = (array) $actual;
		}

		if (is_array($expected) && is_array($actual)) {
			ksort($expected, SORT_STRING);
			ksort($actual, SORT_STRING);
			if (array_keys($expected) !== array_keys($actual)) {
				return false;
			}

			foreach ($expected as $value) {
				if (!self::isEqual($value, current($actual), $level + 1, $objects)) {
					return false;
				}
				next($actual);
			}
			return true;
		}

		return $expected === $actual;
	}


	/**
	 * @param  string
	 * @return bool
	 */
	private static function isPcre($pattern)
	{
		return (bool) preg_match('/^([~#]).+(\1)[imsxUu]*\z/s', $pattern);
	}
}

Zerion Mini Shell 1.0