[Beeframework-svn] SF.net SVN: beeframework:[176] trunk
Brought to you by:
b_hartmann,
m_plomer
From: <m_p...@us...> - 2014-07-10 17:09:16
|
Revision: 176 http://sourceforge.net/p/beeframework/code/176 Author: m_plomer Date: 2014-07-10 17:09:13 +0000 (Thu, 10 Jul 2014) Log Message: ----------- - MVC: RegexMappingInvocationResolver - proper pattern ordering and test case Modified Paths: -------------- trunk/examples/classes/Test/Mvc/ParamTestDelegate.php trunk/examples/conf/context-mvc.xml trunk/framework/Bee/MVC/Controller/Multiaction/AbstractAnnotationBasedResolver.php trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/AnnotationBasedInvocator.php trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/MethodInvocation.php trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/RegexMappingInvocationResolver.php trunk/framework/Bee/Utils/AntPathToRegexTransformer.php trunk/tests/Bee/Context/AbstractTest.php trunk/tests/Bee/Utils/AntPathDataProvider.php Added Paths: ----------- trunk/tests/Bee/MVC/ trunk/tests/Bee/MVC/Controller/ trunk/tests/Bee/MVC/Controller/Multiaction/ trunk/tests/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/ trunk/tests/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/RegexMappingInvocationResolverTest.php trunk/tests/Bee/MVC/HttpRequestMock.php Modified: trunk/examples/classes/Test/Mvc/ParamTestDelegate.php =================================================================== --- trunk/examples/classes/Test/Mvc/ParamTestDelegate.php 2014-07-08 16:51:43 UTC (rev 175) +++ trunk/examples/classes/Test/Mvc/ParamTestDelegate.php 2014-07-10 17:09:13 UTC (rev 176) @@ -21,34 +21,65 @@ * @param MC $testParam * @param boolean $getParam * @return bool - * @Bee_MVC_Controller_Multiaction_RequestHandler(httpMethod = "GET", pathPattern = "/**\/testParam/{0}/{2}/{boolParam}") + * @Bee_MVC_Controller_Multiaction_RequestHandler(pathPattern = "/**\/ghi/*\/{0}/{2}/const/{boolParam}", httpMethod="GET") + * @Bee_MVC_Controller_Multiaction_RequestHandler(pathPattern = "/**\/{0}/{2}/{boolParam}", httpMethod="POST") */ public function handleTestParams($paramA, Bee_MVC_IHttpRequest $request, MC $paramB, $boolParam = false, $testParam = null, $getParam = false) { - var_dump($paramA); - var_dump($paramB); - var_dump($request); - var_dump($boolParam); - var_dump($testParam); - var_dump($getParam); + echo '<hr/>'. get_class($this) .'::'. __FUNCTION__ .'<hr/>'; +// var_dump($paramA); +// var_dump($paramB); +// var_dump($request); +// var_dump($boolParam); +// var_dump($testParam); +// var_dump($getParam); +// echo '<hr/>'; +// var_dump($this); return new Bee_MVC_ModelAndView(array('paramA' => $paramA, 'paramB' => $paramB, 'boolParam' => $boolParam), 'testview'); } /** * - * @Bee_MVC_Controller_Multiaction_RequestHandler(httpMethod = "GET", pathPattern = "/**\/testParam/{paramA}/") + * @param int $paramA + * @param Bee_MVC_IHttpRequest $request + * @param MC $paramB + * @param boolean $boolParam + * @param MC $testParam + * @param boolean $getParam + * @return bool + * @Bee_MVC_Controller_Multiaction_RequestHandler(pathPattern = "/**\/ttt/{0}/{2}/{boolParam}") */ + public function handleTestParams25($paramA, Bee_MVC_IHttpRequest $request, MC $paramB, $boolParam = false, $testParam = null, $getParam = false) { + echo '<hr/>'. get_class($this) .'::'. __FUNCTION__ .'<hr/>'; +// var_dump($paramA); +// var_dump($paramB); +// var_dump($request); +// var_dump($boolParam); +// var_dump($testParam); +// var_dump($getParam); +// echo '<hr/>'; +// var_dump($this); + return new Bee_MVC_ModelAndView(array('paramA' => $paramA, 'paramB' => $paramB, 'boolParam' => $boolParam), 'testview'); + } + + /** + * + * @Bee_MVC_Controller_Multiaction_RequestHandler(pathPattern = "/**\/testParam/{paramA}/") + */ public function handleTestParams2(MC $paramB, Bee_MVC_IHttpRequest $request) { - var_dump($paramB); - var_dump($request); + echo '<hr/>'. get_class($this) .'::'. __FUNCTION__ .'<hr/>'; +// var_dump($paramB); +// var_dump($request); return true; } /** * @param int $getParam * @return Bee_MVC_ModelAndView + * @Bee_MVC_Controller_Multiaction_RequestHandler(pathPattern = "/**") */ public function handleDefault($getParam = 1000) { - var_dump($getParam); + echo '<hr/>'. get_class($this) .'::'. __FUNCTION__ .'<hr/>'; +// var_dump($getParam); return new Bee_MVC_ModelAndView(array(), 'defaultview'); } } \ No newline at end of file Modified: trunk/examples/conf/context-mvc.xml =================================================================== --- trunk/examples/conf/context-mvc.xml 2014-07-08 16:51:43 UTC (rev 175) +++ trunk/examples/conf/context-mvc.xml 2014-07-10 17:09:13 UTC (rev 176) @@ -17,6 +17,7 @@ <array> <assoc-item key="/**/testClassic/**" value="classicController" /> <assoc-item key="/**/testParam/**" value="paramController" /> + <assoc-item key="/**/testParamSub/**" value="paramSubController" /> </array> </property> </bean> @@ -47,5 +48,14 @@ </property> </bean> + <bean id="paramSubController" parent="multiactionControllerTemplate"> + <property name="methodInvocator"> + <bean class="Bee\MVC\Controller\Multiaction\HandlerMethodInvocator\AnnotationBasedInvocator" scope="prototype"/> + </property> + <property name="delegate"> + <bean class="Test\Mvc\SubTestDelegate" /> + </property> + </bean> + <bean id="propertyEditor_Test_MiscClass" class="Test\MiscClassPropertyEditor" /> </beans> Modified: trunk/framework/Bee/MVC/Controller/Multiaction/AbstractAnnotationBasedResolver.php =================================================================== --- trunk/framework/Bee/MVC/Controller/Multiaction/AbstractAnnotationBasedResolver.php 2014-07-08 16:51:43 UTC (rev 175) +++ trunk/framework/Bee/MVC/Controller/Multiaction/AbstractAnnotationBasedResolver.php 2014-07-10 17:09:13 UTC (rev 176) @@ -113,12 +113,11 @@ if (!$this->delegates) { $classReflector = new ReflectionAnnotatedClass($delegateClassName); - /** @var ReflectionAnnotatedMethod[] $methods */ $methods = $classReflector->getMethods(ReflectionMethod::IS_PUBLIC); $mappings = array(); - foreach ($methods as $method) { - + foreach (array_reverse($methods) as $method) { + /** @var ReflectionAnnotatedMethod $method */ if (Bee_Utils_Reflection::isCallableRegularMethod($method)) { // is possible handler method, check for annotations Modified: trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/AnnotationBasedInvocator.php =================================================================== --- trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/AnnotationBasedInvocator.php 2014-07-08 16:51:43 UTC (rev 175) +++ trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/AnnotationBasedInvocator.php 2014-07-10 17:09:13 UTC (rev 176) @@ -102,8 +102,6 @@ (array_key_exists($parameter->getName(), $_REQUEST) ? $_REQUEST[$parameter->getName()] : null); if (!is_null($value) || !$parameter->isOptional()) { $args[$pos] = $propEditor->fromString($value); -// } else { -// $args[$pos] = null; } } } Modified: trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/MethodInvocation.php =================================================================== --- trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/MethodInvocation.php 2014-07-08 16:51:43 UTC (rev 175) +++ trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/MethodInvocation.php 2014-07-10 17:09:13 UTC (rev 176) @@ -28,6 +28,11 @@ private $methodMeta; /** + * @var string + */ + private $antPathPattern; + + /** * @var array */ private $paramValues; @@ -37,8 +42,9 @@ */ private $urlParameterPositions; - function __construct(HandlerMethodMetadata $methodMetadata, array $urlParameterPositions = array()) { + function __construct(HandlerMethodMetadata $methodMetadata, $antPathPattern = false, array $urlParameterPositions = array()) { $this->methodMeta = $methodMetadata; + $this->antPathPattern = $antPathPattern; $this->urlParameterPositions = $urlParameterPositions; } @@ -77,4 +83,11 @@ public function getParamValue($pos) { return $this->paramValues[$pos]; } + + /** + * @return string + */ + public function getAntPathPattern() { + return $this->antPathPattern; + } } \ No newline at end of file Modified: trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/RegexMappingInvocationResolver.php =================================================================== --- trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/RegexMappingInvocationResolver.php 2014-07-08 16:51:43 UTC (rev 175) +++ trunk/framework/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/RegexMappingInvocationResolver.php 2014-07-10 17:09:13 UTC (rev 176) @@ -1,5 +1,6 @@ <?php namespace Bee\MVC\Controller\Multiaction\HandlerMethodInvocator; + /* * Copyright 2008-2014 the original author or authors. * @@ -15,9 +16,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -use Addendum\ReflectionAnnotatedMethod; use Bee\Utils\AntPathToRegexTransformer; use Bee_MVC_IHttpRequest; +use Logger; use ReflectionMethod; /** @@ -26,10 +27,27 @@ */ class RegexMappingInvocationResolver implements IInvocationResolver { + const IGNORE_WILDCARD_TRAILING_PATTERN = '\\.[^/]*'; + /** + * @var Logger + */ + protected static $log; + + /** + * @return Logger + */ + protected static function getLog() { + if (!self::$log) { + self::$log = Logger::getLogger(get_called_class()); + } + return self::$log; + } + + /** * @var HandlerMethodMetadata[] */ - private static $methodMetadataMap = array(); + private static $methodMetadataMap; /** * @var MethodInvocation[] @@ -37,11 +55,11 @@ private $mappedMethods = array(); /** - * @param array|ReflectionAnnotatedMethod[] $mapping + * @param array|ReflectionMethod[] $mapping */ public function __construct(array $mapping) { foreach ($mapping as $antPathPattern => $method) { - $methodMeta = new HandlerMethodMetadata($method); + $methodMeta = self::getCachedMethodMetadata($method); $urlParameterPositions = array(); $regex = AntPathToRegexTransformer::getRegexForParametrizedPattern($antPathPattern, $methodMeta->getTypeMap(), $urlParameterPositions); @@ -53,9 +71,7 @@ $urlParameterPositions = array_flip($urlParameterPositions); // now from parameter pos to match pos - if (!array_key_exists($regex, $this->mappedMethods)) { - $this->mappedMethods[$regex] = new MethodInvocation($methodMeta, $urlParameterPositions); - } + $this->mappedMethods[$regex] = new MethodInvocation($methodMeta, $antPathPattern, $urlParameterPositions); } } @@ -65,21 +81,105 @@ */ public function getInvocationDefinition(Bee_MVC_IHttpRequest $request) { $pathInfo = $request->getPathInfo(); + $matchingPatterns = array(); foreach ($this->mappedMethods as $regex => $invocInfo) { $matches = array(); if (preg_match($regex, $pathInfo, $matches) === 1) { $invocInfo->setParamValues($matches); - return $invocInfo; +// return $invocInfo; + $matchingPatterns[$regex] = $invocInfo; } } + // sort matching patterns + if (self::getLog()->isDebugEnabled()) { + self::getLog()->debug('Found ' . count($matchingPatterns) . ' matching patterns for pathInfo "' . $pathInfo . '", trying to determine most specific match'); + } + + uksort($matchingPatterns, function ($patternA, $patternB) use ($matchingPatterns, $pathInfo) { + /** @var MethodInvocation[] $matchingPatterns */ + $matchA = $matchingPatterns[$patternA]; + $matchB = $matchingPatterns[$patternB]; + + $emptyMatches = 0; + $litLength = function ($carry, $item) use (&$emptyMatches) { + if ($carry === false) { + return $item; + } + if($item) { + if(substr($item, -1) == '/') { + $item = substr($item, 0, -1); + } + return preg_replace('#/'.preg_quote($item).'#', '', $carry, 1); + } + $emptyMatches++; + return $carry; + }; + $litA = array_reduce($matchA->getParamValues(), $litLength, false); + $litA = preg_replace('#//#', '/', $litA); + + $emptyMatches *= -1; + + $litB = array_reduce($matchB->getParamValues(), $litLength, false); + $litB = preg_replace('#//#', '/', $litB); + $litCountA = substr_count($litA, '/'); + $litCountB = substr_count($litB, '/'); + + if ($litCountA != $litCountB) { + return $litCountB - $litCountA; + } + + $resA = array_diff_key($matchA->getParamValues(), array_flip($matchA->getUrlParameterPositions()), array(0 => true)); + $resB = array_diff_key($matchB->getParamValues(), array_flip($matchB->getUrlParameterPositions()), array(0 => true)); + + $counter = function ($carry, $item) { + if (strlen($item) == 0) { + return $carry; + } + $count = substr_count($item, '/'); + return $carry + $count + (substr($item, -1) == '/' ? 0 : 1); + }; + $countA = array_reduce($resA, $counter, 0); + $countB = array_reduce($resB, $counter, 0); + + if ($countA != $countB) { + return $countA - $countB; + } + return -$emptyMatches; + }); + + if (self::getLog()->isDebugEnabled()) { + $matchingAntPaths = array_map(function (MethodInvocation $item) { + return $item->getAntPathPattern(); + }, $matchingPatterns); +// self::getLog()->debug('Sorted patterns for pathInfo "' . $pathInfo . '" are ' . implode("\n", array_keys($matchingPatterns))); + self::getLog()->debug('Sorted patterns for pathInfo "' . $pathInfo . '" are ' . "\n" . implode("\n", $matchingAntPaths)); + } + + if (count($matchingPatterns) > 0) { + return array_shift($matchingPatterns); + } + return null; } public static function getCachedMethodMetadata(ReflectionMethod $method) { - $methodFullName = $method->getDeclaringClass()->getName() .'::' . $method->getName(); - if(!array_key_exists($methodFullName, self::$methodMetadataMap)) { + $methodFullName = $method->getDeclaringClass()->getName() . '::' . $method->getName(); + if (!array_key_exists($methodFullName, self::$methodMetadataMap)) { self::$methodMetadataMap[$methodFullName] = new HandlerMethodMetadata($method); } return self::$methodMetadataMap[$methodFullName]; } + + public static function getWildcardCount($pattern) { + $len = strlen(self::IGNORE_WILDCARD_TRAILING_PATTERN); + if (substr($pattern, $len) == self::IGNORE_WILDCARD_TRAILING_PATTERN) { + $pattern = substr(self::IGNORE_WILDCARD_TRAILING_PATTERN, 0, -$len); + } + return substr_count($pattern, '[^/]*') + 2 * substr_count($pattern, '(?:[^/]+/)*') + 2 * substr_count($pattern, '.*'); + } + + public static function getPatternLength($pattern) { + $pattern = preg_replace('#\([^?].*?\)#', '#', $pattern); + return strlen($pattern); + } } \ No newline at end of file Modified: trunk/framework/Bee/Utils/AntPathToRegexTransformer.php =================================================================== --- trunk/framework/Bee/Utils/AntPathToRegexTransformer.php 2014-07-08 16:51:43 UTC (rev 175) +++ trunk/framework/Bee/Utils/AntPathToRegexTransformer.php 2014-07-10 17:09:13 UTC (rev 176) @@ -23,11 +23,11 @@ class AntPathToRegexTransformer { private static $SIMPLE_REPLACEMENTS = array( - '#\.#' => '\\.', - '#\*#' => '[^/]*', - '#\[\^/\]\*\[\^/\]\*/#' => '(?:[^/]+/)*', - '#\[\^/\]\*\[\^/\]\*#' => '.*', - '#(^|(?<=[^(]))\?#' => '[^/]' + '#\.#' => '\\.', // keep "." as literals + '#\*#' => '([^/]*)', // "*" matches any string that does not contain slashes + '#\(\[\^/\]\*\)\(\[\^/\]\*\)/#' => '((?:[^/]+/)*?)', // "**/" - replaced by "([^/]+)" above - matches 0:n path elements + '#\(\[\^/\]\*\)\(\[\^/\]\*\)#' => '(.*?)', + '#(^|(?<=[^(*]))\?#' => '[^/]' ); public static $TYPE_EXPRESSION_MAP = array( @@ -39,7 +39,7 @@ ITypeDefinitions::STRING => '[^/]+' ); - const PARAMETER_MATCH = '#{((?:\d+)|(?:[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*))}#'; + const PARAMETER_MATCH = '#(?:{((?:\d+)|(?:[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*))})|\(\(\[\^/\]\+/\)\*\?\)|\(.*?\)#'; /** * @param string $antPathPattern @@ -59,6 +59,10 @@ $result = self::getRegexForSimplePattern($antPathPattern); $matchPos = 1; return preg_replace_callback(self::PARAMETER_MATCH, function($matches) use ($parameterTypes, &$positionMap, &$matchPos) { + if(count($matches) == 1) { + $matchPos++; + return $matches[0]; + } $positionMap[$matchPos++] = $matches[1]; $typeName = $parameterTypes[$matches[1]]; if(!array_key_exists($typeName, AntPathToRegexTransformer::$TYPE_EXPRESSION_MAP)) { Modified: trunk/tests/Bee/Context/AbstractTest.php =================================================================== --- trunk/tests/Bee/Context/AbstractTest.php 2014-07-08 16:51:43 UTC (rev 175) +++ trunk/tests/Bee/Context/AbstractTest.php 2014-07-10 17:09:13 UTC (rev 176) @@ -1,6 +1,6 @@ <?php /* - * Copyright 2008-2010 the original author or authors. + * Copyright 2008-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. Added: trunk/tests/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/RegexMappingInvocationResolverTest.php =================================================================== --- trunk/tests/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/RegexMappingInvocationResolverTest.php (rev 0) +++ trunk/tests/Bee/MVC/Controller/Multiaction/HandlerMethodInvocator/RegexMappingInvocationResolverTest.php 2014-07-10 17:09:13 UTC (rev 176) @@ -0,0 +1,205 @@ +<?php +namespace Bee\MVC\Controller\Multiaction\HandlerMethodInvocator; +/* + * Copyright 2008-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +use Bee\MVC\HttpRequestMock; +use PHPUnit_Framework_TestCase; + +/** + * Class RegexMappingInvocationResolver + * @package Bee\MVC\Controller\Multiaction\HandlerMethodInvocator + */ +class RegexMappingInvocationResolverTest extends PHPUnit_Framework_TestCase { + + /** + * @test + * @dataProvider matchDataProvider + */ + public function testMapping(RegexMappingInvocationResolver $resolver, $pathInfo, $expectedAntPath, $expectedParams = array()) { + $request = new HttpRequestMock($pathInfo); + $invocation = $resolver->getInvocationDefinition($request); + $this->assertEquals($expectedAntPath, $invocation->getAntPathPattern()); + + $res = array_intersect_key($invocation->getParamValues(), array_flip($invocation->getUrlParameterPositions())); + $this->assertEquals($expectedParams, array_merge($res)); // param neu durchnummerieren + } + + + public function matchDataProvider() { + $testMapping = $this->provideTestRegexMappingInvocationResolver1(); + return array( + array($testMapping, '/complicated', '/complicated'), // # 00 + array($testMapping, '/complicated/', '/complicated/**'), + array($testMapping, '/complicated/hund', '/complicated/{string1}', array('hund')), + + array($testMapping, '/complicated/more/hund/complicator/hermelin/hase', '/complicated/more/{string1}/complicator/{string2}/**', array('hund', 'hermelin')), + array($testMapping, '/complicated/more/hund/complicator/hermelin/hase/dachs', '/complicated/more/{string1}/complicator/{string2}/**', array('hund', 'hermelin')), + + array($testMapping, + '/complicated/more/hund/complicator/hase', + '/complicated/more/{string1}/complicator/{string2}', + array('hund', 'hase')), // # 05 + array($testMapping, + '/complicated/more/complicator/hund', + '/complicated/more/**/complicator/{string2}', + array('hund')), + array($testMapping, + '/complicated/more/hund/hermelin/complicator/hase', + '/complicated/more/**/complicator/{string2}', + array('hase')), + array($testMapping, + '/hund/complicated/more/hund/complicator/hermelin/hase', + '/**/complicated/more/{string1}/complicator/{string2}/**', + array('hund', 'hermelin')), + array($testMapping, + '/x/complicated/more/complicator/hermelin/hase', + '/**/complicated/more/**/complicator/{string2}/**', + array('hermelin')), + array($testMapping, + '/hase/complicated/more/complicator/hermelin/x', + '/**/complicated/more/**/complicator/{string2}/**', + array('hermelin')), // # 10 + array($testMapping, + '/x/y/z/complicated/more/hund/complicator/hermelin/hase', + '/**/complicated/more/{string1}/complicator/{string2}/**', + array('hund', + 'hermelin')), + array($testMapping, + '/x/complicated/more/y/complicator/hermelin/hase', + '/**/complicated/more/{string1}/complicator/{string2}/**', + array('y', 'hermelin')), + array($testMapping, + '/complicated/more/x/y/z/complicator/hermelin/hase', + '/complicated/more/**/complicator/{string2}/**', + array('hermelin')), + array($testMapping, + '/complicated/more/x/y/z/compliment/hermelin/hase', + '/complicated/more/**/compl*/{string2}/**', + array('hermelin')), + + ); + } + + public function provideTestRegexMappingInvocationResolver1() { + $method = new \ReflectionMethod('Bee\MVC\Controller\Multiaction\HandlerMethodInvocator\HandlerMock', 'methodA'); + + $testPatterns1 = array(); + $testPatterns1['/complicated'] = $method; + $testPatterns1['/complicated/**'] = $method; + $testPatterns1['/complicated/more'] = $method; + $testPatterns1['/complicated/{string1}'] = $method; + $testPatterns1['/complicated/more/music'] = $method; + $testPatterns1['/complicated/more/{string1}/music'] = $method; + $testPatterns1['/complicated/more/{string1}/{string2}'] = $method; + $testPatterns1['/complicated/more/{string1}/{string2}/{string3}'] = $method; + $testPatterns1['/complicated/more/{string1}/complicator/{string2}'] = $method; + $testPatterns1['/complicated/{string1}/complicator/{string2}'] = $method; + $testPatterns1['/complicated/**/complicator/{string2}'] = $method; + $testPatterns1['/complicated/more/**/complicator/{string2}'] = $method; + $testPatterns1['/complicated/more/**'] = $method; + $testPatterns1['/complicated/{string1}/**'] = $method; + $testPatterns1['/complicated/more/music/**'] = $method; + $testPatterns1['/complicated/more/{string1}/music/**'] = $method; + $testPatterns1['/complicated/more/{string1}/{string2}/**'] = $method; + $testPatterns1['/complicated/more/{string1}/{string2}/{string3}/**'] = $method; + $testPatterns1['/complicated/more/{string1}/complicator/{string2}/**'] = $method; + $testPatterns1['/complicated/{string1}/complicator/{string2}/**'] = $method; + $testPatterns1['/complicated/**/complicator/{string2}/**'] = $method; + $testPatterns1['/complicated/more/**/complicator/{string2}/**'] = $method; + + $testPatterns1['/**/complicated'] = $method; + $testPatterns1['/**/complicated/**'] = $method; + $testPatterns1['/**/complicated/more'] = $method; + $testPatterns1['/**/complicated/{string1}'] = $method; + $testPatterns1['/**/complicated/more/music'] = $method; + $testPatterns1['/**/complicated/more/{string1}/music'] = $method; + $testPatterns1['/**/complicated/more/{string1}/{string2}'] = $method; + $testPatterns1['/**/complicated/more/{string1}/{string2}/{string3}'] = $method; + $testPatterns1['/**/complicated/more/{string1}/complicator/{string2}'] = $method; + $testPatterns1['/**/complicated/{string1}/complicator/{string2}'] = $method; + $testPatterns1['/**/complicated/**/complicator/{string2}'] = $method; + $testPatterns1['/**/complicated/more/**/complicator/{string2}'] = $method; + $testPatterns1['/**/complicated/more/**'] = $method; + $testPatterns1['/**/complicated/{string1}/**'] = $method; + $testPatterns1['/**/complicated/more/music/**'] = $method; + $testPatterns1['/**/complicated/more/{string1}/music/**'] = $method; + $testPatterns1['/**/complicated/more/{string1}/{string2}/**'] = $method; + $testPatterns1['/**/complicated/more/{string1}/{string2}/{string3}/**'] = $method; + $testPatterns1['/**/complicated/more/{string1}/complicator/{string2}/**'] = $method; + $testPatterns1['/**/complicated/{string1}/complicator/{string2}/**'] = $method; + $testPatterns1['/**/complicated/**/complicator/{string2}/**'] = $method; + $testPatterns1['/**/complicated/more/**/complicator/{string2}/**'] = $method; + + $testPatterns1['/**/more'] = $method; + $testPatterns1['/**/{string1}'] = $method; + $testPatterns1['/**/more/music'] = $method; + $testPatterns1['/**/more/{string1}/music'] = $method; + $testPatterns1['/**/more/{string1}/{string2}'] = $method; + $testPatterns1['/**/more/{string1}/{string2}/{string3}'] = $method; + $testPatterns1['/**/more/{string1}/complicator/{string2}'] = $method; + $testPatterns1['/**/{string1}/complicator/{string2}'] = $method; + $testPatterns1['/**/**/complicator/{string2}'] = $method; + $testPatterns1['/**/more/**/complicator/{string2}'] = $method; + $testPatterns1['/**/more/**'] = $method; + $testPatterns1['/**/{string1}/**'] = $method; + $testPatterns1['/**/more/music/**'] = $method; + $testPatterns1['/**/more/{string1}/music/**'] = $method; + $testPatterns1['/**/more/{string1}/{string2}/**'] = $method; + $testPatterns1['/**/more/{string1}/{string2}/{string3}/**'] = $method; + $testPatterns1['/**/more/{string1}/complicator/{string2}/**'] = $method; + $testPatterns1['/**/{string1}/complicator/{string2}/**'] = $method; + $testPatterns1['/**/complicator/{string2}/**'] = $method; + $testPatterns1['/**/more/**/complicator/{string2}/**'] = $method; + + $testPatterns1['/**'] = $method; + $testPatterns1['/*/more'] = $method; + $testPatterns1['/*/{string1}'] = $method; + $testPatterns1['/*/more/music'] = $method; + $testPatterns1['/*/more/{string1}/music'] = $method; + $testPatterns1['/*/more/{string1}/{string2}'] = $method; + $testPatterns1['/*/more/{string1}/{string2}/{string3}'] = $method; + $testPatterns1['/*/more/{string1}/complicator/{string2}'] = $method; + $testPatterns1['/*/{string1}/complicator/{string2}'] = $method; + $testPatterns1['/*/**/complicator/{string2}'] = $method; + $testPatterns1['/*/more/**/complicator/{string2}'] = $method; + $testPatterns1['/*/more/**'] = $method; + $testPatterns1['/*/{string1}/**'] = $method; + $testPatterns1['/*/more/music/**'] = $method; + $testPatterns1['/*/more/{string1}/music/**'] = $method; + $testPatterns1['/*/more/{string1}/{string2}/**'] = $method; + $testPatterns1['/*/more/{string1}/{string2}/{string3}/**'] = $method; + $testPatterns1['/*/more/{string1}/complicator/{string2}/**'] = $method; + $testPatterns1['/*/{string1}/complicator/{string2}/**'] = $method; + $testPatterns1['/*/complicator/{string2}/**'] = $method; + $testPatterns1['/*/more/**/complicator/{string2}/**'] = $method; + + $testPatterns1['/complicated/more/**/compl*/{string2}/**'] = $method; + + return new RegexMappingInvocationResolver($testPatterns1); + } +} + +class HandlerMock { + + /** + * @param string $string1 + * @param string $string2 + * @param string $string3 + */ + public function methodA($string1, $string2, $string3) { + + } +} \ No newline at end of file Added: trunk/tests/Bee/MVC/HttpRequestMock.php =================================================================== --- trunk/tests/Bee/MVC/HttpRequestMock.php (rev 0) +++ trunk/tests/Bee/MVC/HttpRequestMock.php 2014-07-10 17:09:13 UTC (rev 176) @@ -0,0 +1,118 @@ +<?php +namespace Bee\MVC; +use Bee_MVC_IHttpRequest; + +/** + * Class HttpRequestMock + * @package Bee\MVC + */ +class HttpRequestMock implements Bee_MVC_IHttpRequest { + + /** + * @var string + */ + private $pathInfo; + + /** + * @var string + */ + private $method; + + /** + * @var array + */ + private $parameters = array(); + + /** + * @var array + */ + private $headers = array(); + + /** + * @var bool + */ + private $ajax = false; + + /** + * @param $pathInfo + * @param $parameters + * @param $method + * @param $headers + * @param $ajax + */ + function __construct($pathInfo = '', array $parameters = array(), $method = 'GET', array $headers = array(), $ajax = false) { + $this->pathInfo = $pathInfo; + $this->parameters = $parameters; + $this->method = $method; + $this->headers = array_change_key_case($headers, CASE_UPPER); + $this->ajax = $ajax; + } + + + /** + * @return string + */ + public function getPathInfo() { + return $this->pathInfo; + } + + /** + * @return string + */ + public function getMethod() { + return $this->method; + } + + /** + * @param string $name + * @return bool + */ + public function hasParameter($name) { + return array_key_exists($name, $this->parameters); + } + + /** + * @param String $name + * @return String + */ + public function getParameter($name) { + return $this->hasParameter($name) ? $this->parameters[$name] : null; + } + + /** + * @return array + */ + public function getParameterNames() { + return array_keys($this->parameters); + } + + /** + * @param String $name + * @return String + */ + public function getHeader($name) { + $name = strtoupper($name); + return array_key_exists($name, $this->headers) ? $this->headers[$name] : false; + } + + /** + * @return array + */ + public function getHeaderNames() { + return array_keys($this->headers); + } + + /** + * @param array $params + */ + public function addParameters(array $params) { + $this->parameters = array_merge($this->parameters, $params); + } + + /** + * @return bool + */ + public function getAjax() { + return $this->ajax; + } +} \ No newline at end of file Modified: trunk/tests/Bee/Utils/AntPathDataProvider.php =================================================================== --- trunk/tests/Bee/Utils/AntPathDataProvider.php 2014-07-08 16:51:43 UTC (rev 175) +++ trunk/tests/Bee/Utils/AntPathDataProvider.php 2014-07-10 17:09:13 UTC (rev 176) @@ -104,6 +104,8 @@ array("/x/x/**/bla", "/x/x/x/", False), + array("/test/**", "/test", False), + array("", "", True)//, // array("/{bla}.*", "/testing.html", True) // #65 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |