Пример #1
0
 public function testIfWillRecognizeAnnotationAfterDynamicallyAddingNamespace()
 {
     $model = new ModelWithTwoNsAnnotations();
     $options = new MetaOptions();
     $options->namespaces[] = NamespacedAnnotation::Ns;
     $meta = Meta::create($model, $options)->title;
     $this->assertTrue($meta->namespaced);
     // Not added second namespace
     $this->assertNull($meta->second);
     $this->assertNull($meta->third);
     // Second ns
     $options->namespaces[] = SecondNsAnnotation::Ns;
     $metaContainer2 = Meta::create($model, $options);
     $this->assertNotNull($metaContainer2);
     $meta2 = $metaContainer2->title;
     $this->assertTrue($meta2->namespaced);
     // Added second namespace
     $this->assertTrue($meta2->second, 'That namespace added via options id detected');
     // Third ns
     Addendum::fly()->addNamespace(ThirdNsAnnotation::Ns);
     $meta3 = Meta::create($model, $options)->title;
     $this->assertTrue($meta3->namespaced);
     $this->assertTrue($meta3->second);
     // Added second namespace
     $this->assertTrue($meta3->third, 'That namespace added via Addendum::addNamespace is detected');
 }
Пример #2
0
 public function testIfWillProperlyCacheNamespacesForDifferentMetaContainers()
 {
     $path = (new ConfigDetector())->getRuntimePath();
     if (!is_dir($path)) {
         mkdir($path);
     }
     // Simulate different meta container classes by creating different paths
     $path1 = sprintf('%s/path1', $path);
     $path2 = sprintf('%s/path2', $path);
     $path3 = sprintf('%s/path3', $path);
     if (!is_dir($path1)) {
         mkdir($path1);
     }
     if (!is_dir($path2)) {
         mkdir($path2);
     }
     if (!is_dir($path3)) {
         mkdir($path3);
     }
     $ns1 = new NsCache($path1, Addendum::fly(), new CacheOptionsOne());
     $ns1->set();
     codecept_debug($ns1->get());
     $this->assertTrue($ns1->valid());
     $ns2 = new NsCache($path2, Addendum::fly(), new CacheOptionsTwo());
     $ns2->set();
     codecept_debug($ns2->get());
     $this->assertTrue($ns1->valid());
     $this->assertTrue($ns2->valid());
     $ns3 = new NsCache($path3, Addendum::fly(), new CacheOptionsOne());
     $ns3->set();
     codecept_debug($ns3->get());
     $this->assertTrue($ns1->valid());
     $this->assertTrue($ns2->valid());
     $this->assertTrue($ns3->valid());
 }
Пример #3
0
 public function testBefore(TestEvent $e)
 {
     // Clear cache if env var is not set or is set to true
     if (false === getenv('ADDENDUM_CACHE_CLEAR') || getenv('ADDENDUM_CACHE_CLEAR')) {
         Addendum::cacheClear();
         exec('rm -rf vendor/addendum/*');
     }
 }
Пример #4
0
 public function testRawMatcher()
 {
     $model = new ModelWithConstantValue();
     $reflection = new ReflectionAnnotatedClass($model);
     $matcher = new AnnotationsMatcher();
     $matcher->setPlugins(new MatcherConfig(['addendum' => new Addendum(), 'reflection' => new ReflectionClass($this)]));
     $matches = [];
     $matcher->matches(Addendum::getDocComment($reflection), $matches);
 }
Пример #5
0
 /**
  * Get all annotations with optional restriction to $restriction annotation name
  * @param string $restriction
  * @return AnnotationInterface[]
  */
 public function getAllAnnotations($restriction = false)
 {
     $restriction = Addendum::resolveClassName($restriction);
     $result = [];
     foreach ($this->annotations as $class => $instances) {
         if (!$restriction || $restriction == $class) {
             $result = array_merge($result, $instances);
         }
     }
     return $result;
 }
Пример #6
0
 /**
  *
  * @param string $metaClass
  * @param AnnotatedInterface|object|string $component
  * @param MetaOptions|Addendum $options
  */
 public function __construct($metaClass = null, $component = null, $options = null)
 {
     if (null === self::$runtimePath) {
         self::$runtimePath = (new ConfigDetector())->getRuntimePath();
     }
     $this->path = self::$runtimePath . '/addendum';
     $this->metaClass = $metaClass;
     $this->component = $component;
     if (empty($options)) {
         $this->instanceId = Addendum::DefaultInstanceId;
     } elseif ($options instanceof Addendum) {
         $this->instanceId = $options->getInstanceId();
     } elseif ($options instanceof MetaOptions) {
         $this->instanceId = $options->instanceId;
     } else {
         throw new UnexpectedValueException('Unknown options');
     }
     $this->prepare();
     $this->addendum = Addendum::fly($this->instanceId);
     $this->nsCache = new NsCache(dirname($this->getFilename()), $this->addendum);
 }
Пример #7
0
 public function testIfWillExtractTopValues()
 {
     $model = new ModelWithTopValues();
     // Raw matcher for debug
     $reflection = new ReflectionAnnotatedProperty($model, 'straight');
     $matcher = new AnnotationsMatcher();
     $matcher->setPlugins(new MatcherConfig(['addendum' => new Addendum(), 'reflection' => $reflection]));
     $data = [];
     $comment = Addendum::getDocComment($reflection);
     $matcher->matches($comment, $data);
     $meta = Meta::create($model);
     // All fields have same annotation
     foreach ($meta->fields() as $fieldMeta) {
         $title = sprintf('Annotation is defined on %s', $fieldMeta->name);
         $this->assertSame(ModelWithTopValues::ClassValue, $fieldMeta->class);
         $this->assertSame(ModelWithTopValues::UpdatableValue, $fieldMeta->updatable);
     }
 }
Пример #8
0
 /**
  * @param string|object|AnnotatedInterface $model
  * @param MetaOptions $options
  * @throws Exception
  */
 protected function __construct($model = null, MetaOptions $options = null)
 {
     // For internal use
     if (null === $model) {
         return;
     }
     if (null === $options) {
         $options = new MetaOptions();
     }
     // TODO Use adapter here
     // ?TODO Abstract from component meta, so other kinds of meta extractors could be used
     // For example, for development annotation based extractor could be used, which could compile
     // Metadata to arrays, and for production environment, compiled arrays could be used
     $annotations = [];
     $mes = [];
     // Get reflection data
     $ad = Addendum::fly($options->instanceId);
     $ad->addNamespaces($options->namespaces);
     $info = $ad->annotate($model);
     // Class name of working component
     $className = is_object($model) ? get_class($model) : $model;
     if (!$info instanceof ReflectionAnnotatedClass) {
         throw new Exception(sprintf('Could not annotate `%s`', $className));
     }
     $properties = $info->getProperties(ReflectionProperty::IS_PUBLIC);
     $defaults = $info->getDefaultProperties();
     $methods = $info->getMethods(ReflectionMethod::IS_PUBLIC);
     // Setup type
     /**
      * @todo Fix it: $this->_meta->{$this->name}->...
      * ^-- _meta __get and __set is only for fields AND use _fields field,
      * for class OR methods it should use different fields
      * for class should be _main
      * for methods should be _methods
      * __get and __set should distinguish it somehow... - maybe by field type EComponentMetaProperty for fieltds etc.
      * Currently disabled
      * OR add function to Annotation to setEntity, which should point to _field, _main or _method?
      */
     // Setup class annotations
     $this->_type = new $options->typeClass($info);
     foreach ($info->getAllAnnotations() as $annotation) {
         if (!$annotation instanceof MetaAnnotationInterface) {
             continue;
         }
         $annotation->setName($info->name);
         $annotation->setEntity($this->_type);
         $annotation->setMeta($this);
         $annotation->init();
         $annotations[] = $annotation;
     }
     // Setup methods
     foreach ($methods as $method) {
         if (!$method instanceof ReflectionAnnotatedMethod) {
             throw new Exception(sprintf('Could not annotate `%s::%s()`', $className, $method->name));
         }
         // Ignore magic methods
         if (preg_match('~^__~', $method->name)) {
             continue;
         }
         // Ignore @Ignored marked methods
         if (IgnoredChecker::check($method)) {
             continue;
         }
         // Create method holder class based on options
         $methodMeta = new $options->methodClass($method);
         foreach ($method->getAllAnnotations() as $annotation) {
             if (!$annotation instanceof MetaAnnotationInterface) {
                 continue;
             }
             $annotation->setName($method->name);
             $annotation->setEntity($methodMeta);
             $annotation->setMeta($this);
             $annotation->init();
             $annotations[] = $annotation;
         }
         // Put it to metadata object
         $this->_methods[$method->name] = $methodMeta;
         // Get getters and setters for properties setup
         if (preg_match('~^[gs]et~', $method->name) && !$method->isStatic()) {
             $mes[$method->name] = true;
         }
     }
     // Setup properties
     foreach ($properties as $property) {
         if (!$property instanceof ReflectionAnnotatedProperty) {
             throw new Exception(sprintf('Could not annotate `%s::%s`', $className, $property->name));
         }
         if (IgnoredChecker::check($property)) {
             continue;
         }
         $name = $property->name;
         /* @var $property ReflectionAnnotatedProperty */
         $field = new $options->propertyClass($property);
         // Access options
         $field->callGet = isset($mes[$field->methodGet]) && $mes[$field->methodGet];
         $field->callSet = isset($mes[$field->methodSet]) && $mes[$field->methodSet];
         $field->direct = !($field->callGet || $field->callSet);
         $field->isStatic = $property->isStatic();
         // Other
         if (array_key_exists($name, $defaults)) {
             $field->default = $defaults[$name];
         }
         // Put it to metadata object
         $this->_fields[$field->name] = $field;
         foreach ($property->getAllAnnotations() as $annotation) {
             if (!$annotation instanceof MetaAnnotationInterface) {
                 continue;
             }
             $annotation->setName($field->name);
             $annotation->setEntity($field);
             $annotation->setMeta($this);
             $annotation->init();
             $annotations[] = $annotation;
         }
     }
     foreach ($annotations as $annotation) {
         $annotation->afterInit();
     }
 }
Пример #9
0
<?php

use Maslosoft\Addendum\Addendum;
use Maslosoft\Signals\Signal;
use Maslosoft\Signals\Utility;
date_default_timezone_set('Europe/Paris');
define('VENDOR_DIR', __DIR__ . '/../../..');
define('YII_DIR', VENDOR_DIR . '/yiisoft/yii/framework/');
require VENDOR_DIR . '/autoload.php';
// Invoker stub for windows
if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
    require __DIR__ . '/../misc/Invoker.php';
}
$config = (require __DIR__ . '/../config.php');
define('RUNTIME_PATH', __DIR__ . '/../runtime');
define('MODELS_PATH', __DIR__ . '/../models');
define('SIGNALS_PATH', __DIR__ . '/../signals');
$addendum = new Addendum();
$addendum->namespaces[] = 'Maslosoft\\Signals';
$addendum->init();
$signal = new Signal();
$signal->runtimePath = RUNTIME_PATH;
$signal->paths = [MODELS_PATH];
$signal->init();
(new Utility($signal))->generate();
$signal->resetCache();
Пример #10
0
 /**
  * Add annotation namespace
  * @param string $namespace
  */
 public function addNamespace($namespace)
 {
     $this->addendum->addNamespace($namespace);
 }
Пример #11
0
 /**
  * Get doc comment
  * @param ReflectionAnnotatedClass|ReflectionAnnotatedMethod|ReflectionAnnotatedProperty $reflection
  * @return mixed[]
  */
 protected function getDocComment($reflection)
 {
     return Addendum::getDocComment($reflection);
 }
Пример #12
0
 public function _after()
 {
     Addendum::cacheClear();
 }