/** * @dataProvider getPreNormalizationTests */ public function testPreNormalize($denormalized, $normalized) { $node = new ArrayNode('foo'); $r = new \ReflectionMethod($node, 'preNormalize'); $r->setAccessible(true); $this->assertSame($normalized, $r->invoke($node, $denormalized)); }
/** * Execute requested action */ public function execute() { $method = $_SERVER['REQUEST_METHOD']; $verbs = $this->verbs(); if (isset($verbs[$this->requestMethod])) { $action = 'action' . ucfirst(mb_strtolower($verbs[$method])); $reflectionMethod = new \ReflectionMethod($this, $action); $parsePath = array_slice($this->path, count($this->route)); $args = []; $errors = []; if ($params = $reflectionMethod->getParameters()) { foreach ($params as $key => $param) { if (isset($parsePath[$key])) { $args[$param->name] = $parsePath[$key]; } else { $errors[] = ['code' => 'required', 'message' => ucfirst(mb_strtolower(explode('_', $param->name)[0])) . ' cannot be blank.', 'name' => $param->name]; } } if ($errors) { throw new \phantomd\ShopCart\modules\base\HttpException(400, 'Invalid data parameters', 0, null, $errors); } } if (count($parsePath) === count($params)) { return call_user_func_array([$this, $action], $args); } } throw new HttpException(404, 'Unable to resolve the request "' . $this->requestPath . '".', 0, null, $errors); }
/** * {@inheritdoc} */ public function validate($object, Constraint $constraint) { if (null === $object) { return; } if (null !== $constraint->callback && null !== $constraint->methods) { throw new ConstraintDefinitionException('The Callback constraint supports either the option "callback" ' . 'or "methods", but not both at the same time.'); } // has to be an array so that we can differentiate between callables // and method names if (null !== $constraint->methods && !is_array($constraint->methods)) { throw new UnexpectedTypeException($constraint->methods, 'array'); } $methods = $constraint->methods ?: array($constraint->callback); foreach ($methods as $method) { if (is_array($method) || $method instanceof \Closure) { if (!is_callable($method)) { throw new ConstraintDefinitionException(sprintf('"%s::%s" targeted by Callback constraint is not a valid callable', $method[0], $method[1])); } call_user_func($method, $object, $this->context); } else { if (!method_exists($object, $method)) { throw new ConstraintDefinitionException(sprintf('Method "%s" targeted by Callback constraint does not exist', $method)); } $reflMethod = new \ReflectionMethod($object, $method); if ($reflMethod->isStatic()) { $reflMethod->invoke(null, $object, $this->context); } else { $reflMethod->invoke($object, $this->context); } } } }
/** * @internal * * @param Oxygen_Http_Request $request * @param Oxygen_Util_RequestData $requestData * @param string $className * @param string $method * @param array $actionParameters * * @return Oxygen_Http_Response * @throws Oxygen_Exception */ public function handleRaw($request, $requestData, $className, $method, array $actionParameters) { $reflectionMethod = new ReflectionMethod($className, $method); $parameters = $reflectionMethod->getParameters(); $arguments = array(); foreach ($parameters as $parameter) { if (isset($actionParameters[$parameter->getName()])) { $arguments[] = $actionParameters[$parameter->getName()]; } else { if (!$parameter->isOptional()) { throw new Oxygen_Exception(Oxygen_Exception::ACTION_ARGUMENT_NOT_PROVIDED); } $arguments[] = $parameter->getDefaultValue(); } } if (is_subclass_of($className, 'Oxygen_Container_ServiceLocatorAware')) { $instance = call_user_func(array($className, 'createFromContainer'), $this->container); } else { $instance = new $className(); } $result = call_user_func_array(array($instance, $method), $arguments); if (is_array($result)) { $result = $this->convertResultToResponse($request, $requestData, $result); } elseif (!$result instanceof Oxygen_Http_Response) { throw new LogicException(sprintf('An action should return array or an instance of Oxygen_Http_Response; %s gotten.', gettype($result))); } return $result; }
public function testGetPageFactory() { $element = $this->createElement(); $method = new \ReflectionMethod(get_class($element), 'getPageFactory'); $method->setAccessible(true); $this->assertSame($this->pageFactory, $method->invoke($element)); }
public function getHtmlData() { $htmlDataString = ""; foreach (get_class_methods(get_called_class()) as $method) { if (substr($method, 0, 3) == "get" && $method != "getHtmlData" && $method != "getPK") { $ref = new ReflectionMethod($this, $method); if (sizeOf($ref->getParameters()) == 0) { $field = strtolower(substr($method, 3)); $value = $this->{$method}(); if (is_object($value)) { if (get_class($value) != "Doctrine\\ORM\\PersistentCollection") { $field = "id{$field}"; $pkGetter = "get" . $field; $value = $value->{$pkGetter}(); $data = "data-{$field}=\"" . $value . "\" "; $htmlDataString .= $data; } } else { $data = "data-{$field}=\"" . $value . "\" "; $htmlDataString .= $data; } } } } return $htmlDataString . " data-crud=" . get_called_class() . " data-string=" . $this; }
/** * Actual routing + sanitizing data * * @param $class * @param array $params */ public static function connect($namespace, $class, $params = array()) { $defaults = array('indexPage' => 'index', 'loginPage' => false, 'loginRedirect' => false); static::$class = strtolower($class); $class = $namespace . '\\' . $class; $params += $defaults; extract($params); // Authenticated controllers if ($loginPage) { Auth::checkLogin($loginRedirect, $loginPage); } $method = $indexPage; $parameters = array(); if (isset($_SERVER[URI_INFO])) { $url = explode('/', substr($_SERVER[URI_INFO], 1)); array_shift($url); if ($url) { foreach ($url as $key => $element) { if (!$key && !is_numeric($element)) { $method = $element; } else { $parameters[] = $element; } } } } // Check availability try { $methodInfo = new \ReflectionMethod($class, $method); // Methods that start with _ are not accesible from browser $name = $methodInfo->getName(); if ($name[0] == '_') { $method = $indexPage; } $methodParams = $methodInfo->getParameters(); // Force cast parameters by arguments default value if ($methodParams) { foreach ($methodParams as $parameterKey => $parameterValue) { try { $defaultValue = $parameterValue->getDefaultValue(); $type = gettype($defaultValue); if ($defaultValue) { unset($methodParams[$parameterKey]); } // settype($parameters[$parameterKey], $type); } catch (\Exception $e) { continue; } } } // if(count($methodParams) != count($parameters)) { // $parameters = array(); // } } catch (\Exception $e) { $method = $indexPage; } static::$method = $method; call_user_func_array($class . '::' . $method, $parameters); return; }
/** * Magic function to read a data value * * @param $name string Name of the property to be returned * @throws Exception * @return mixed */ public function __get($name) { if (isset($this->_valueMap[$name])) { $key = $this->_valueMap[$name]; } else { $key = $name; } if (!is_array($this->_primaryKey) && $key == $this->_primaryKey) { return $this->getId(); } if (!array_key_exists($key, $this->_data)) { // Is there a public getter function for this value? $functionName = $this->composeGetterName($key); if (method_exists($this, $functionName)) { $reflection = new \ReflectionMethod($this, $functionName); if ($reflection->isPublic()) { return $this->{$functionName}(); } } throw new Exception('Column not found in data: ' . $name); } $result = $this->_data[$key]; if (isset($this->_formatMap[$key])) { $result = Format::fromSql($this->_formatMap[$key], $result); } return $result; }
/** * @covers System::set_template */ public function test_set_template() { $method = new ReflectionMethod(System::class, 'set_template'); $method->setAccessible(true); $method->invoke($this->system_obj); self::assertTrue($this->system_obj->template instanceof \common\interfaces\Template); }
public function __construct(\ReflectionMethod $method) { $this->_method = $method; $comment = $method->getDocComment(); $comment = new DocBloc($comment); $this->_annotations = $comment->getAnnotations(); }
public function __construct($callable, array $annotations = array()) { if (is_array($callable)) { list($this->class, $method) = $callable; $reflMethod = new \ReflectionMethod($this->class, $method); if (!$reflMethod->isPublic()) { throw new \InvalidArgumentException('Class method must be public'); } elseif ($reflMethod->isStatic()) { $this->staticMethod = $method; } else { $this->method = $method; $class = $this->class; $this->instance = new $class(); } } elseif ($callable instanceof \Closure) { $this->closure = $callable; } elseif (is_string($callable)) { if (!function_exists($callable)) { throw new \InvalidArgumentException('Function does not exist'); } $this->function = $callable; } else { throw new \InvalidArgumentException('Invalid callable type'); } $this->annotations = $annotations; }
/** * @covers gzip_file::open_archive * @todo Implement testopen_archive(). */ public function testopen_archive() { $methods = get_class_methods($this->object); $this->assertTrue(in_array('open_archive', $methods), 'exists method open_archive'); $r = new ReflectionMethod('gzip_file', 'open_archive'); $params = $r->getParameters(); }
/** * Creates alias to all native methods of the resource. * * @param string $method method name * @param mixed $args arguments * @return mixed */ public function __call($method, $args) { $class = get_called_class(); $obj = $class::instance(); $method = new ReflectionMethod($obj, $method); return $method->invokeArgs($obj, $args); }
public function testGetUrl() { $this->router->expects($this->once())->method('generate')->with($this->equalTo('sonata_cache_opcode'), $this->equalTo(array('token' => 'token')))->will($this->returnValue('/sonata/cache/opcode/token')); $method = new \ReflectionMethod($this->cache, 'getUrl'); $method->setAccessible(true); $this->assertEquals('/sonata/cache/opcode/token', $method->invoke($this->cache)); }
/** * Check to see if said module has method and is publically callable * @param {string} $module The raw module name * @param {string} $method The method name */ public function moduleHasMethod($module, $method) { $this->getActiveModules(); $module = ucfirst(strtolower($module)); if (!empty($this->moduleMethods[$module]) && in_array($method, $this->moduleMethods[$module])) { return true; } $amods = array(); foreach (array_keys($this->active_modules) as $mod) { $amods[] = $this->cleanModuleName($mod); } if (in_array($module, $amods)) { try { $rc = new \ReflectionClass($this->FreePBX->{$module}); if ($rc->hasMethod($method)) { $reflection = new \ReflectionMethod($this->FreePBX->{$module}, $method); if ($reflection->isPublic()) { $this->moduleMethods[$module][] = $method; return true; } } } catch (\Exception $e) { } } return false; }
private function format_controller_methods($path, $file) { $this->load->helper("url"); $controller = array(); // only show php files if (($extension = substr($file, strrpos($file, ".") + 1)) == "php") { // include the class include_once $path . "/" . $file; $parts = explode(".", $file); $class_lower = $parts["0"]; $class = ucfirst($class_lower); // check if a class actually exists if (class_exists($class) and get_parent_class($class) == "MY_Controller") { // get a list of all methods $controller["name"] = $class; $controller["path"] = base_url() . $class_lower; $controller["methods"] = array(); // get a list of all public methods foreach (get_class_methods($class) as $method) { $reflect = new ReflectionMethod($class, $method); if ($reflect->isPublic()) { // ignore some methods $object = new $class(); if (!in_array($method, $object->internal_methods)) { $method_array = array(); $method_array["name"] = $method; $method_array["path"] = base_url() . $class_lower . "/" . $method; $controller["methods"][] = $method_array; } } } } } return $controller; }
/** * {@inheritdoc} */ public function validate($object, Constraint $constraint) { if (!$constraint instanceof Callback) { throw new UnexpectedTypeException($constraint, __NAMESPACE__ . '\\Callback'); } $method = $constraint->callback; if ($method instanceof \Closure) { $method($object, $this->context, $constraint->payload); } elseif (is_array($method)) { if (!is_callable($method)) { if (isset($method[0]) && is_object($method[0])) { $method[0] = get_class($method[0]); } throw new ConstraintDefinitionException(sprintf('%s targeted by Callback constraint is not a valid callable', json_encode($method))); } call_user_func($method, $object, $this->context, $constraint->payload); } elseif (null !== $object) { if (!method_exists($object, $method)) { throw new ConstraintDefinitionException(sprintf('Method "%s" targeted by Callback constraint does not exist in class %s', $method, get_class($object))); } $reflMethod = new \ReflectionMethod($object, $method); if ($reflMethod->isStatic()) { $reflMethod->invoke(null, $object, $this->context, $constraint->payload); } else { $reflMethod->invoke($object, $this->context, $constraint->payload); } } }
/** * @covers ::buildSelector */ public function testBuildSelector() { $this->stringTranslation->expects($this->any())->method('translate')->willReturnArgument(0); $method = new \ReflectionMethod($this->sut, 'buildSelector'); $method->setAccessible(TRUE); $plugin_id = $this->randomMachineName(); $plugin_label = $this->randomMachineName(); $plugin_definition = $this->getMock(PluginLabelDefinitionInterface::class); $plugin_definition->expects($this->atLeastOnce())->method('getLabel')->willReturn($plugin_label); $plugin = $this->getMock(PluginInspectionInterface::class); $plugin->expects($this->atLeastOnce())->method('getPluginDefinition')->willReturn($plugin_definition); $plugin->expects($this->atLeastOnce())->method('getPluginId')->willReturn($plugin_id); $this->selectablePluginType->expects($this->atLeastOnce())->method('ensureTypedPluginDefinition')->willReturnArgument(0); $this->sut->setSelectedPlugin($plugin); $selector_title = $this->randomMachineName(); $this->sut->setLabel($selector_title); $selector_description = $this->randomMachineName(); $this->sut->setDescription($selector_description); $element = array('#parents' => array('foo', 'bar'), '#title' => $selector_title); $form_state = $this->getMock(FormStateInterface::class); $available_plugins = array($plugin); $expected_build_plugin_id = array('#ajax' => array('callback' => array(Radios::class, 'ajaxRebuildForm'), 'effect' => 'fade', 'event' => 'change', 'progress' => 'none', 'trigger_as' => array('name' => 'foo[bar][select][container][change]')), '#attached' => ['library' => ['plugin/plugin_selector.plugin_radios']], '#default_value' => $plugin_id, '#empty_value' => 'select', '#options' => array($plugin_id => $plugin_label), '#required' => FALSE, '#title' => $selector_title, '#description' => $selector_description, '#type' => 'radios'); $expected_build_change = array('#ajax' => array('callback' => array(AdvancedPluginSelectorBase::class, 'ajaxRebuildForm')), '#attributes' => array('class' => array('js-hide')), '#limit_validation_errors' => array(array('foo', 'bar', 'select', 'plugin_id')), '#name' => 'foo[bar][select][container][change]', '#submit' => [[AdvancedPluginSelectorBase::class, 'rebuildForm']], '#type' => 'submit', '#value' => 'Choose'); $build = $method->invokeArgs($this->sut, array($element, $form_state, $available_plugins)); $this->assertEquals($expected_build_plugin_id, $build['container']['plugin_id']); $this->assertEquals($expected_build_change, $build['container']['change']); $this->assertSame('container', $build['container']['#type']); }
/** * Binds the parameters to the action. * This method is invoked by [[\yii\base\Action]] when it begins to run with the given parameters. * This method will check the parameter names that the action requires and return * the provided parameters according to the requirement. If there is any missing parameter, * an exception will be thrown. * @param \yii\base\Action $action the action to be bound with parameters * @param array $params the parameters to be bound to the action * @return array the valid parameters that the action can run with. * @throws HttpException if there are missing or invalid parameters. */ public function bindActionParams($action, $params) { if ($action instanceof InlineAction) { $method = new \ReflectionMethod($this, $action->actionMethod); } else { $method = new \ReflectionMethod($action, 'run'); } $args = []; $missing = []; $actionParams = []; foreach ($method->getParameters() as $param) { $name = $param->getName(); if (array_key_exists($name, $params)) { if ($param->isArray()) { $args[] = $actionParams[$name] = is_array($params[$name]) ? $params[$name] : [$params[$name]]; } elseif (!is_array($params[$name])) { $args[] = $actionParams[$name] = $params[$name]; } else { throw new BadRequestHttpException(Yii::t('yii', 'Invalid data received for parameter "{param}".', ['param' => $name])); } unset($params[$name]); } elseif ($param->isDefaultValueAvailable()) { $args[] = $actionParams[$name] = $param->getDefaultValue(); } else { $missing[] = $name; } } if (!empty($missing)) { throw new BadRequestHttpException(Yii::t('yii', 'Missing required parameters: {params}', ['params' => implode(', ', $missing)])); } $this->actionParams = $actionParams; return $args; }
public function __construct($argv) { $this->verbose = $this->verbose == true ? true : false; $argv[] = '-clean'; $argv[] = ''; $this->args = $argv; // get the systems username and set the home dir. $this->user = get_current_user(); $this->home = '/home/' . $this->user . '/'; foreach ($this->args as $location => $args) { $chars = str_split($args); if ($chars[0] === '-') { $tmp = explode('-', $args); $function = end($tmp); unset($tmp); // this does a check to make sure we can only // run public functions via this constructor. $check = new ReflectionMethod($this, $function); if (!$check->isPublic()) { continue; } $this->{$function}($argv[++$location]); } } }
/** * Resolves the target of the route and returns a callable. * * @param mixed $target * @param array $construct_args * * @throws RuntimeException If the target is not callable * * @return callable */ private static function getCallable($target, array $construct_args) { if (is_string($target)) { //is a class "classname::method" if (strpos($target, '::') === false) { $class = $target; $method = '__invoke'; } else { list($class, $method) = explode('::', $target, 2); } if (!class_exists($class)) { throw new RuntimeException("The class {$class} does not exists"); } $fn = new \ReflectionMethod($class, $method); if (!$fn->isStatic()) { $class = new \ReflectionClass($class); $instance = $class->hasMethod('__construct') ? $class->newInstanceArgs($construct_args) : $class->newInstance(); $target = [$instance, $method]; } } //if it's callable as is if (is_callable($target)) { return $target; } throw new RuntimeException('The route target is not callable'); }
/** * @param object $object an object or classname * @param string $method the method which we want to inspect */ public function reflect($object, $method) { $reflection = new \ReflectionMethod($object, $method); $docs = $reflection->getDocComment(); // extract everything prefixed by @ and first letter uppercase preg_match_all('/@([A-Z]\\w+)/', $docs, $matches); $this->annotations = $matches[1]; // extract type parameter information preg_match_all('/@param\\h+(?P<type>\\w+)\\h+\\$(?P<var>\\w+)/', $docs, $matches); // this is just a fix for PHP 5.3 (array_combine raises warning if called with // two empty arrays if ($matches['var'] === array() && $matches['type'] === array()) { $this->types = array(); } else { $this->types = array_combine($matches['var'], $matches['type']); } // get method parameters foreach ($reflection->getParameters() as $param) { if ($param->isOptional()) { $default = $param->getDefaultValue(); } else { $default = null; } $this->parameters[$param->name] = $default; } }
/** * @dataProvider parseUrlExceptionProvider */ public function testParseUrlException($url) { $this->setExpectedException('rex_socket_exception'); $method = new ReflectionMethod('rex_socket', 'parseUrl'); $method->setAccessible(true); $method->invoke(null, $url); }
public function getMethod($filePath, $ext = '') { $fileName = dirname($filePath); $className = basename(dirname(dirname($filePath))); if (!class_exists($className)) { helper::import($fileName); } $methodName = basename($filePath); $method = new ReflectionMethod($className . $ext, $methodName); $data = new stdClass(); $data->startLine = $method->getStartLine(); $data->endLine = $method->getEndLine(); $data->comment = $method->getDocComment(); $data->parameters = $method->getParameters(); $data->className = $className; $data->methodName = $methodName; $data->fileName = $fileName; $data->post = false; $file = file($fileName); for ($i = $data->startLine - 1; $i <= $data->endLine; $i++) { if (strpos($file[$i], '$this->post') or strpos($file[$i], 'fixer::input') or strpos($file[$i], '$_POST')) { $data->post = true; } } return $data; }
public function __try($method) { if (!$this->app->is_admin() && $method !== 'auth') { throw new \exception('denied'); } try { if (!method_exists($this, $method)) { throw new \exception('method not found'); } else { $reflection = new \ReflectionMethod($this, $method); if (!$reflection->isPublic()) { throw new \exception('method not found'); } } $msg = call_user_func([$this, $method]); } catch (\exception $e) { if ($this->app->debug === true) { $err = $e->getMessage() . '<br/><hr>' . $e->getFile() . ' @ Line ' . $e->getLine() . '<br/><hr>STACK TRACE:<br/>' . $e->getTraceAsString(); } else { $err = $e->getMessage(); } $msg = ['error' => 1, 'message' => $err]; } echo json_encode($msg, JSON_HEX_QUOT | JSON_HEX_TAG); }
public final function generateCode(ReflectionClass $class, $test_double_class_name, array $interfaces = array(), array $traits = array(), $method_checker = null) { FBMock_Utils::assertString($test_double_class_name); if ($class->isFinal() && !$this->canOverrideFinals()) { throw new FBMock_TestDoubleException("Cannot mock final class %s", $class->getName()); } $code = $this->getMockClassHeader($class, $test_double_class_name, $interfaces, $traits) . "\n"; $method_sources = array(); foreach ($class->getMethods() as $method) { $method_checker && $method_checker($class, $method); if ($method->isFinal() && !$this->canOverrideFinals()) { continue; } // #1137433 if (!$class->isInterface()) { $method = new ReflectionMethod($class->getName(), $method->getName()); } $test_double_method_generator = FBMock_Config::get()->getMethodGenerator(); $method_source = $test_double_method_generator->generateCode($method); if ($method_source) { $method_sources[] = $method_source; } } $code .= implode("\n\n", $method_sources); $code .= "\n}"; // close class return $code; }
function executePrivateMethod($object, $method, $arguments) { $reflectedMethod = new \ReflectionMethod($object, $method); $reflectedMethod->setAccessible(true); $result = $reflectedMethod->invoke($object, ...$arguments); return $result; }
/** * @expectedException JMS\SerializerBundle\Exception\XmlErrorException * @expectedExceptionMessage [FATAL] Start tag expected, '<' not found */ public function testInvalidXml() { $driver = $this->getDriver(); $ref = new \ReflectionMethod($driver, 'loadMetadataFromFile'); $ref->setAccessible(true); $ref->invoke($driver, new \ReflectionClass('stdClass'), __DIR__ . '/xml/invalid.xml'); }
public function testLifetime() { $cache = $this->_getCacheDriver(); // Test save $cache->save('test_key', 'testing this out', 10); // Test contains to test that save() worked $this->assertTrue($cache->contains('test_key')); // Test fetch $this->assertEquals('testing this out', $cache->fetch('test_key')); // access private methods $getFilename = new \ReflectionMethod($cache, 'getFilename'); $getNamespacedId = new \ReflectionMethod($cache, 'getNamespacedId'); $getFilename->setAccessible(true); $getNamespacedId->setAccessible(true); $id = $getNamespacedId->invoke($cache, 'test_key'); $filename = $getFilename->invoke($cache, $id); $data = ''; $lifetime = 0; $resource = fopen($filename, "r"); if (false !== ($line = fgets($resource))) { $lifetime = (int) $line; } while (false !== ($line = fgets($resource))) { $data .= $line; } $this->assertNotEquals(0, $lifetime, 'previous lifetime could not be loaded'); // update lifetime $lifetime = $lifetime - 20; file_put_contents($filename, $lifetime . PHP_EOL . $data); // test expired data $this->assertFalse($cache->contains('test_key')); $this->assertFalse($cache->fetch('test_key')); }
public function testRetrievesAndCachesTargetData() { $ctime = strtotime('January 1, 2013'); $a = $this->getMockBuilder('SplFileinfo')->setMethods(array('getSize', 'getMTime', '__toString'))->disableOriginalConstructor()->getMock(); $a->expects($this->any())->method('getSize')->will($this->returnValue(10)); $a->expects($this->any())->method('getMTime')->will($this->returnValue($ctime)); $a->expects($this->any())->method('__toString')->will($this->returnValue('')); $b = $this->getMockBuilder('SplFileinfo')->setMethods(array('getSize', 'getMTime', '__toString'))->disableOriginalConstructor()->getMock(); $b->expects($this->any())->method('getSize')->will($this->returnValue(11)); $b->expects($this->any())->method('getMTime')->will($this->returnValue($ctime)); $a->expects($this->any())->method('__toString')->will($this->returnValue('')); $c = 0; $converter = $this->getMockBuilder('Aws\\S3\\Sync\\KeyConverter')->setMethods(array('convert'))->getMock(); $converter->expects($this->any())->method('convert')->will($this->returnCallback(function () use(&$c) { if (++$c == 1) { return 'foo'; } else { return 'bar'; } })); $targetIterator = new \ArrayIterator(array($b, $a)); $targetIterator->rewind(); $changed = new ChangedFilesIterator($targetIterator, $targetIterator, $converter, $converter); $ref = new \ReflectionMethod($changed, 'getTargetData'); $ref->setAccessible(true); $this->assertEquals(array(10, $ctime), $ref->invoke($changed, 'bar')); $this->assertEquals(array(11, $ctime), $ref->invoke($changed, 'foo')); $this->assertFalse($ref->invoke($changed, 'baz')); }