public function testIgnoreAnnotationsSurroundedByFenceWhenRawAnnotateIsUsed() { $model = new ModelWithFences(); $file = (new ReflectionObject($model))->getFileName(); $annotations = AnnotationUtility::rawAnnotate($file); $this->assertTrue(!empty($annotations['class']), 'That has class annotations are present'); codecept_debug($annotations['class']); $this->assertTrue(!empty($annotations['class']['Label']), 'That has @Label annotation is present'); $this->assertTrue(!empty($annotations['class']['Label'][0]['value']), 'That has @Label has value'); $this->assertSame('LABEL', $annotations['class']['Label'][0]['value'], 'That @Label has proper value'); $this->assertFalse(array_key_exists('Description', $annotations['class']), 'That @Description was ignored'); }
public function testIfFileWalkerFilterOutFiles() { $annotations = ['Label']; $shouldMatch = ['ModelWithLabels.php' => true, 'ModelWithConstantValue.php' => true, 'ModelWithoutLabels.php' => false]; $matched = ['ModelWithLabels.php' => false, 'ModelWithConstantValue.php' => false, 'ModelWithoutLabels.php' => false]; $callback = function ($path) use(&$matched) { $bn = basename($path); $matched[$bn] = true; }; $callback->bindTo($this); $searchPaths = [MODELS_PATH]; AnnotationUtility::fileWalker($annotations, $callback, $searchPaths); foreach ($shouldMatch as $file => $match) { $this->assertSame($match, $matched[$file]); } }
/** * @param string $file */ public function processFile($file, $contents) { $file = realpath($file); $this->paths[] = $file; // Remove initial `\` from namespace try { $annotated = AnnotationUtility::rawAnnotate($file); } catch (ParseException $e) { $this->log($e, $file); return; } catch (UnexpectedValueException $e) { $this->log($e, $file); return; } $namespace = preg_replace('~^\\\\+~', '', $annotated['namespace']); $className = $annotated['className']; // Use fully qualified name, class must autoload $fqn = $namespace . '\\' . $className; NameNormalizer::normalize($fqn); try { $info = new ReflectionClass($fqn); } catch (ReflectionException $e) { $this->log($e, $file); return; } $isAnnotated = $info->implementsInterface(AnnotatedInterface::class); $hasSignals = $this->hasSignals($contents); $isAbstract = $info->isAbstract() || $info->isInterface(); // Old classes must now implement interface // Brake BC! if ($hasSignals && !$isAnnotated && !$isAbstract) { throw new UnexpectedValueException(sprintf('Class %s must implement %s to use signals', $fqn, AnnotatedInterface::class)); } // Skip not annotated class if (!$isAnnotated) { return; } // Skip abstract classes if ($isAbstract) { return; } $meta = @SignalsMeta::create($fqn); /* @var $typeMeta DocumentTypeMeta */ $typeMeta = $meta->type(); // Signals foreach ($typeMeta->signalFor as $slot) { $this->data[Signal::Slots][$slot][$fqn] = true; } // Slots // For constructor injection foreach ($typeMeta->slotFor as $slot) { $key = implode('@', [$fqn, '__construct', '()']); $this->data[Signal::Signals][$slot][$fqn][$key] = true; } // For method injection foreach ($meta->methods() as $methodName => $method) { /* @var $method DocumentMethodMeta */ foreach ($method->slotFor as $slot) { $key = implode('@', [$fqn, $methodName, '()']); $this->data[Signal::Signals][$slot][$fqn][$key] = sprintf('%s()', $methodName); } } // For property injection foreach ($meta->fields() as $fieldName => $field) { /* @var $field DocumentPropertyMeta */ foreach ($field->slotFor as $slot) { $key = implode('@', [$fqn, $fieldName]); $this->data[Signal::Signals][$slot][$fqn][$key] = sprintf('%s', $fieldName); } } }