/** * Tests static method call routing to enable patterns defined in Validator::$_rules to be * called as methods. * * @return void */ public function testCustomMethodDispatching() { $this->assertTrue(Validator::isRegex('/^abc$/')); $this->assertTrue(Validator::isPhone('800-999-5555')); $this->assertTrue(Validator::isUrl('http://google.com')); $this->assertTrue(Validator::isUrl('google.com', 'loose')); }
/** * Provides a simple syntax for making assertions about the properties of a request. * By default, the `Request` object is configured with several different types of assertions, * which are individually known as _detectors_. Detectors are invoked by calling the `is()` and * passing the name of the detector flag, i.e. `$request->is('<name>')`, which returns `true` or * `false`, depending on whether or not the the properties (usually headers or data) contained * in the request match the detector. The default detectors include the following: * * - `'mobile'`: Uses a regular expression to match common mobile browser user agents. * - `'ajax'`: Checks to see if the `X-Requested-With` header is present, and matches the value * `'XMLHttpRequest'`. * - `'flash'`: Checks to see if the user agent is `'Shockwave Flash'`. * - `'ssl'`: Verifies that the request is SSL-secured. * - `'get'` / `'post'` / `'put'` / `'delete'` / `'head'` / `'options'`: Checks that the HTTP * request method matches the one specified. * * In addition to the above, this method also accepts media type names (see `Media::type()`) to * make assertions against the format of the request body (for POST or PUT requests), i.e. * `$request->is('json')`. This will return `true` if the client has made a POST request with * JSON data. * * For information about adding custom detectors or overriding the ones in the core, see the * `detect()` method. * * While these detectors are useful in controllers or other similar contexts, they're also * useful when performing _content negotiation_, which is the process of modifying the response * format to suit the client (see the `'conditions'` field of the `$options` parameter in * `Media::type()`). * * @see lithium\action\Request::detect() * @see lithium\net\http\Media::type() * @param string $flag The name of the flag to check, which should be the name of a valid * detector (that is either built-in or defined with `detect()`). * @return boolean Returns `true` if the detector check succeeds (see the details for the * built-in detectors above, or `detect()`), otherwise `false`. */ public function is($flag) { $media = $this->_classes['media']; if (!isset($this->_detectors[$flag])) { if (!in_array($flag, $media::types())) { return false; } return $this->type() == $flag; } $detector = $this->_detectors[$flag]; if (!is_array($detector) && is_callable($detector)) { return $detector($this); } if (!is_array($detector)) { return (bool) $this->env($detector); } list($key, $check) = $detector + array('', ''); if (is_array($check)) { $check = '/' . join('|', $check) . '/i'; } if (Validator::isRegex($check)) { return (bool) preg_match($check, $this->env($key)); } return $this->env($key) == $check; }
/** * Convert an exception object to an exception result array for test reporting. * * @param array $exception The exception data to report on. Statistics are gathered and * added to the reporting stack contained in `Unit::$_results`. * @param string $lineFlag * @return void * @todo Refactor so that reporters handle trace formatting. */ protected function _reportException($exception, $lineFlag = null) { $message = $exception['message']; $isExpected = ($exp = end($this->_expected)) && ($exp === true || $exp === $message || Validator::isRegex($exp) && preg_match($exp, $message)); if ($isExpected) { return array_pop($this->_expected); } $initFrame = current($exception['trace']) + array('class' => '-', 'function' => '-'); foreach ($exception['trace'] as $frame) { if (isset($scopedFrame)) { break; } if (!class_exists('lithium\\analysis\\Inspector')) { continue; } if (isset($frame['class']) && in_array($frame['class'], Inspector::parents($this))) { $scopedFrame = $frame; } } if (class_exists('lithium\\analysis\\Debugger')) { $exception['trace'] = Debugger::trace(array('trace' => $exception['trace'], 'format' => '{:functionRef}, line {:line}', 'includeScope' => false, 'scope' => array_filter(array('functionRef' => __NAMESPACE__ . '\\{closure}', 'line' => $lineFlag)))); } $this->_result('exception', $exception + array('class' => $initFrame['class'], 'method' => $initFrame['function'])); }
/** * Tests the regular expression validation for various regex delimiters * * @link http://www.php.net/manual/en/regexp.reference.delimiters.php Regex Delimiters */ public function testIsRegex() { $this->assertTrue(Validator::isRegex('/^123$/')); $this->assertTrue(Validator::isRegex('/^abc$/')); $this->assertTrue(Validator::isRegex('/^abc123$/')); $this->assertTrue(Validator::isRegex('@^abc$@')); $this->assertTrue(Validator::isRegex('#^abc$#')); $this->assertFalse(Validator::isRegex('d^abc$d')); $this->assertTrue(Validator::isRegex('(^abc$)')); $this->assertTrue(Validator::isRegex('{^abc$}')); $this->assertTrue(Validator::isRegex('[^abc$]')); $this->assertTrue(Validator::isRegex('<^abc$>')); $this->assertTrue(Validator::isRegex(')^abc$)')); $this->assertTrue(Validator::isRegex('}^abc$}')); $this->assertTrue(Validator::isRegex(']^abc$]')); $this->assertTrue(Validator::isRegex('>^abc$>')); $this->assertFalse(Validator::isRegex('\\^abc$\\')); $this->assertFalse(Validator::isRegex('(^abc$(')); $this->assertFalse(Validator::isRegex('{^abc${')); $this->assertFalse(Validator::isRegex('[^abc$[')); $this->assertFalse(Validator::isRegex('<^abc$<')); }
protected static function _normalizeResource($resource) { if (is_callable($resource)) { return $resource; } if (is_array($resource)) { if ($resource === array('*')) { return true; } return $resource; } if (!is_string($resource)) { throw new Exception('Unsupported resource definition: ' . var_export($resource, true)); } if (preg_match('/^([a-z0-9_\\*\\\\]+)::([a-z0-9_\\*]+)$/i', $resource, $matches)) { return array('controller' => $matches[1], 'action' => $matches[2]); } if (Validator::isRegex($resource)) { return function ($params) use($resource) { return (bool) preg_match($resource, $params['request']->url); }; } if ($resource === '*') { return true; } return function ($params) use($resource) { return $resource === $params['request']->url; }; }
/** * Normalizes `Exception` objects and PHP error data into a single array format, and checks * each error against the list of expected errors (set using `expectException()`). If a match * is found, the expectation is removed from the stack and the error is ignored. If no match * is found, then the error data is logged to the test results. * * @param mixed $exception An `Exception` object instance, or an array containing the following * keys: `'message'`, `'file'`, `'line'`, `'trace'` (in `debug_backtrace()` * format) and optionally `'code'` (error code number) and `'context'` (an array * of variables relevant to the scope of where the error occurred). * @param integer $lineFlag A flag used for determining the relevant scope of the call stack. * Set to the line number where test methods are called. * @return void * @see lithium\test\Unit::expectException() * @see lithium\test\Unit::_reportException() */ protected function _handleException($exception, $lineFlag = null) { if (is_object($exception)) { $data = array(); foreach (array('message', 'file', 'line', 'trace') as $key) { $method = 'get' . ucfirst($key); $data[$key] = $exception->{$method}(); } $ref = $exception->getTrace(); $ref = $ref[0] + array('class' => null); if ($ref['class'] == __CLASS__ && $ref['function'] == 'skipIf') { return $this->_result('skip', $data); } $exception = $data; } $message = $exception['message']; $isExpected = ($exp = end($this->_expected)) && ($exp === true || $exp == $message || Validator::isRegex($exp) && preg_match($exp, $message)); if ($isExpected) { return array_pop($this->_expected); } $this->_reportException($exception, $lineFlag); }
/** * Detects properties of the request and returns a boolean response. * * @see lithium\action\Request::detect() * @todo Remove $content and refer to Media class instead * @param string $flag * @return boolean */ public function is($flag) { $flag = strtolower($flag); if (!empty($this->_detectors[$flag])) { $detector = $this->_detectors[$flag]; if (is_array($detector)) { list($key, $check) = $detector + array('', ''); if (is_array($check)) { $check = '/' . join('|', $check) . '/i'; } if (Validator::isRegex($check)) { return (bool) preg_match($check, $this->env($key)); } return $this->env($key) == $check; } if (is_callable($detector)) { return $detector($this); } return (bool) $this->env($detector); } return false; }