mirror of
				https://github.com/kevinveenbirkenbach/infinito.git
				synced 2025-10-31 09:19:08 +00:00 
			
		
		
		
	Optimized Attributes and tests for it
This commit is contained in:
		| @@ -5,12 +5,14 @@ namespace App\Attribut; | ||||
| use Doctrine\Common\Collections\Collection; | ||||
|  | ||||
| /** | ||||
|  * @see ChildsAttributInterface | ||||
|  * | ||||
|  * @author kevinfrantz | ||||
|  */ | ||||
| trait ChildsAttribut | ||||
| { | ||||
|     /** | ||||
|      * @var Collection|ChildsAttributeInterface[] | ||||
|      * @var Collection|ChildsAttributInterface[] | ||||
|      */ | ||||
|     protected $childs; | ||||
|  | ||||
|   | ||||
| @@ -7,7 +7,7 @@ use Doctrine\Common\Collections\Collection; | ||||
| /** | ||||
|  * @author kevinfrantz | ||||
|  */ | ||||
| interface ChildsAttributeInterface | ||||
| interface ChildsAttributInterface | ||||
| { | ||||
|     public function setChilds(Collection $childs): void; | ||||
| 
 | ||||
| @@ -7,6 +7,8 @@ namespace App\Attribut; | ||||
|  */ | ||||
| interface ClassAttributInterface | ||||
| { | ||||
|     const CLASS_ATTRIBUT_NAME = 'class'; | ||||
|  | ||||
|     /** | ||||
|      * @param string $class | ||||
|      */ | ||||
|   | ||||
| @@ -4,6 +4,8 @@ This folder containes the attributs which are used by entity, domain logic etc. | ||||
| Each attribut containes out of an interface and a trait. | ||||
| ## Interface | ||||
| The interface MUST define a __get-__ and a __set-method__. Optional an interface can define a __has-method__. | ||||
| For meta processing an interface SHOULD contain one constant which is named by the schema __<<ATTRIBUT>>_ATTRIBUT_NAME__. | ||||
| An interface MUST NOT implement other constants.  | ||||
| ### Methods | ||||
| #### Set | ||||
| The __setter__ MUST return nothing(void). It SHOULD throw an exception if the value is not valid. | ||||
|   | ||||
| @@ -6,8 +6,10 @@ use Doctrine\Common\Collections\Collection; | ||||
| 
 | ||||
| /** | ||||
|  * @author kevinfrantz | ||||
|  * | ||||
|  * @see RightsAttributInterface | ||||
|  */ | ||||
| trait RightsAttribute | ||||
| trait RightsAttribut | ||||
| { | ||||
|     /** | ||||
|      * @var Collection | ||||
| @@ -10,6 +10,8 @@ use App\Entity\Meta\RightInterface; | ||||
|  */ | ||||
| interface RightsAttributInterface | ||||
| { | ||||
|     const RIGHTS_ATTRIBUT_NAME = 'rights'; | ||||
|  | ||||
|     /** | ||||
|      * @param Collection|RightInterface[] $rights | ||||
|      */ | ||||
|   | ||||
| @@ -53,6 +53,9 @@ final class FixtureSourceFactory implements FixtureSourceFactoryInterface | ||||
|         return $objects; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public static function getAllFixtureSources(): array | ||||
|     { | ||||
|         $unfilteredClasses = self::getAllClassesInSourceFixtureNamespace(); | ||||
|   | ||||
| @@ -41,6 +41,8 @@ Checks if the crud, layer and source combination is granted by a right. | ||||
| ### Right Layer Combination Service ### | ||||
| Allows to get the possible cruds for a layer, or the possible layers for a crud. | ||||
| ## Source Management | ||||
| ### Source Class Information Service ### | ||||
| Offers to get all source classes, or source classes by a namespace.  | ||||
| ### Source Member Information ### | ||||
| Offers to get all source members over all dimensions. | ||||
| ### Source Member Manager | ||||
|   | ||||
| @@ -75,7 +75,7 @@ final class SourceClassInformationService implements SourceClassInformationServi | ||||
|         $this->allClasses[] = $this->transformPathToClass($path); | ||||
|     } | ||||
|  | ||||
|     private function loadClasses() | ||||
|     private function loadClasses(): void | ||||
|     { | ||||
|         $recursiveDirectoryIterator = new \RecursiveDirectoryIterator(self::FOLDER); | ||||
|         $files = new \RecursiveIteratorIterator($recursiveDirectoryIterator, \RecursiveIteratorIterator::SELF_FIRST); | ||||
|   | ||||
| @@ -3,7 +3,7 @@ | ||||
| namespace App\Entity\Meta; | ||||
|  | ||||
| use Doctrine\ORM\Mapping as ORM; | ||||
| use App\Attribut\RightsAttribute; | ||||
| use App\Attribut\RightsAttribut; | ||||
| use Doctrine\Common\Collections\ArrayCollection; | ||||
| use App\Attribut\RelationAttribut; | ||||
| use App\Entity\Source\SourceInterface; | ||||
| @@ -16,7 +16,7 @@ use App\Attribut\GrantAttribut; | ||||
|  */ | ||||
| class Law extends AbstractMeta implements LawInterface | ||||
| { | ||||
|     use RightsAttribute, RelationAttribut, GrantAttribut; | ||||
|     use RightsAttribut, RelationAttribut, GrantAttribut; | ||||
|  | ||||
|     /** | ||||
|      * @ORM\Column(type="boolean",name="`grant`") | ||||
|   | ||||
| @@ -3,9 +3,9 @@ | ||||
| namespace App\Entity\Meta\Relation\Parent; | ||||
|  | ||||
| use App\Attribut\ParentsAttributInterface; | ||||
| use App\Attribut\ChildsAttributeInterface; | ||||
| use App\Attribut\ChildsAttributInterface; | ||||
| use App\Entity\Meta\Relation\RelationInterface; | ||||
|  | ||||
| interface ParentRelationInterface extends RelationInterface, ParentsAttributInterface, ChildsAttributeInterface | ||||
| interface ParentRelationInterface extends RelationInterface, ParentsAttributInterface, ChildsAttributInterface | ||||
| { | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,219 @@ | ||||
| <?php | ||||
|  | ||||
| namespace tests\Integration\Attribut; | ||||
|  | ||||
| use PHPUnit\Framework\TestCase; | ||||
|  | ||||
| /** | ||||
|  * This class is not a "real" integration test. | ||||
|  * It just checks if the traits are build up on a valid way | ||||
|  * It implements the schema described in. | ||||
|  * | ||||
|  * @see https://github.com/KevinFrantz/infinito/blob/master/application/symfony/src/Attribut/README.md | ||||
|  * | ||||
|  * @author kevinfrantz | ||||
|  */ | ||||
| class AttributIntegrationTest extends TestCase | ||||
| { | ||||
|     /** | ||||
|      * @var string The folder of the attributes | ||||
|      */ | ||||
|     const FOLDER = __DIR__.'/../../../src/Attribut'; | ||||
|  | ||||
|     /** | ||||
|      * @var string The namespace of the attributs | ||||
|      */ | ||||
|     const NAMESPACE = 'App\\Attribut'; | ||||
|  | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     const INTERFACE_SUFFIX = 'Interface'; | ||||
|  | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     const ATTRIBUT_SUFFIX = 'Attribut'; | ||||
|  | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     const CONCAT_INTERFACE_SUFFIX = self::ATTRIBUT_SUFFIX.self::INTERFACE_SUFFIX; | ||||
|  | ||||
|     /** | ||||
|      * @var array | ||||
|      */ | ||||
|     const POSSIBLE_METHODS = ['has', 'get', 'set']; | ||||
|  | ||||
|     /** | ||||
|      * @var array | ||||
|      */ | ||||
|     const NECCESSARY_METHODS = ['get', 'set']; | ||||
|  | ||||
|     /** | ||||
|      * @param string $file | ||||
|      * | ||||
|      * @return bool True if it is an interface | ||||
|      */ | ||||
|     private function isInterface(\ReflectionClass $interface): bool | ||||
|     { | ||||
|         return $interface->isInterface(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param \ReflectionClass $interface | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     private function getTraitName(\ReflectionClass $interface): string | ||||
|     { | ||||
|         return substr($interface->getName(), 0, -strlen(self::INTERFACE_SUFFIX)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param \ReflectionClass $interface | ||||
|      */ | ||||
|     private function validateHasTrait(\ReflectionClass $interface): void | ||||
|     { | ||||
|         $interfaceName = $interface->getName(); | ||||
|         $trait = $this->getTraitName($interface); | ||||
|         $this->assertTrue(trait_exists($trait), "Trait <<$trait>> for interface <<$interfaceName>> MUST exist!"); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param \ReflectionClass $trait | ||||
|      */ | ||||
|     private function validateHasInterface(\ReflectionClass $trait): void | ||||
|     { | ||||
|         $traitName = $trait->getName(); | ||||
|         $interface = $traitName.self::INTERFACE_SUFFIX; | ||||
|         $this->assertTrue(interface_exists($interface), "Interface <<$interface>> for trait <<$traitName>> does not exist!"); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param \ReflectionClass $interface | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     private function getAttributName(\ReflectionClass $interface): string | ||||
|     { | ||||
|         return substr($interface->getShortName(), 0, -strlen(self::CONCAT_INTERFACE_SUFFIX)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param \ReflectionClass $interface | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     private function getConstantName(\ReflectionClass $interface): string | ||||
|     { | ||||
|         $name = strtoupper($this->getAttributName($interface)); | ||||
|  | ||||
|         return $name.'_ATTRIBUT_NAME'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param \ReflectionClass $interface | ||||
|      */ | ||||
|     private function validateConstants(\ReflectionClass $interface): void | ||||
|     { | ||||
|         $constants = $interface->getConstants(); | ||||
|         $constantAmount = count($constants); | ||||
|         $this->assertTrue($constantAmount <= 1, 'Just one constant is allowed!'); | ||||
|         if (1 === $constantAmount) { | ||||
|             $this->assertEquals($this->getConstantName($interface), array_keys($constants)[0]); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param \ReflectionClass $interface | ||||
|      */ | ||||
|     private function validateMethods(\ReflectionClass $interface): void | ||||
|     { | ||||
|         $methods = get_class_methods($interface->getName()); | ||||
|         $possibleMethods = $this->getPossibleMethods($interface); | ||||
|         foreach ($methods as $method) { | ||||
|             $this->assertContains($method, $possibleMethods); | ||||
|         } | ||||
|         $neccessaryMethods = $this->getNeccessaryMethods($interface); | ||||
|         foreach ($neccessaryMethods as $neccessaryMethod) { | ||||
|             $this->assertContains($neccessaryMethod, $methods); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param \ReflectionClass $interface | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     private function getNeccessaryMethods(\ReflectionClass $interface): array | ||||
|     { | ||||
|         $possibleMethods = []; | ||||
|         $name = $this->getAttributName($interface); | ||||
|         foreach (self::NECCESSARY_METHODS as $method) { | ||||
|             $possibleMethods[] = $method.$name; | ||||
|         } | ||||
|  | ||||
|         return $possibleMethods; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param \ReflectionClass $interface | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     private function getPossibleMethods(\ReflectionClass $interface): array | ||||
|     { | ||||
|         $possibleMethods = []; | ||||
|         $name = $this->getAttributName($interface); | ||||
|         foreach (self::POSSIBLE_METHODS as $method) { | ||||
|             $possibleMethods[] = $method.$name; | ||||
|         } | ||||
|  | ||||
|         return $possibleMethods; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param string $file | ||||
|      * | ||||
|      * @return \ReflectionClass | ||||
|      */ | ||||
|     private function getReflectionClass(string $file): \ReflectionClass | ||||
|     { | ||||
|         $shortName = substr($file, 0, -strlen('.php')); | ||||
|         $name = self::NAMESPACE.'\\'.$shortName; | ||||
|  | ||||
|         return new \ReflectionClass($name); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param \ReflectionClass $interface | ||||
|      */ | ||||
|     private function validateTraitSchema(\ReflectionClass $interface): void | ||||
|     { | ||||
|         $trait = $this->getTraitName($interface); | ||||
|         $traitMethods = get_class_methods($trait); | ||||
|         $interfaceMethods = get_class_methods($interface->getName()); | ||||
|         foreach ($interfaceMethods as $interfaceMethod) { | ||||
|             $this->assertContains($interfaceMethod, $traitMethods); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public function testFiles(): void | ||||
|     { | ||||
|         $files = scandir(self::FOLDER); | ||||
|         foreach ($files as $file) { | ||||
|             if (!in_array($file, ['README.md', '.', '..'])) { | ||||
|                 $reflection = $this->getReflectionClass($file); | ||||
|                 if ($this->isInterface($reflection)) { | ||||
|                     $this->validateHasTrait($reflection); | ||||
|                     $this->validateConstants($reflection); | ||||
|                     $this->validateMethods($reflection); | ||||
|                     $this->validateTraitSchema($reflection); | ||||
|                 } else { | ||||
|                     $this->validateHasInterface($reflection); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -3,20 +3,20 @@ | ||||
| namespace Attribut; | ||||
|  | ||||
| use PHPUnit\Framework\TestCase; | ||||
| use App\Attribut\ChildsAttributeInterface; | ||||
| use App\Attribut\ChildsAttributInterface; | ||||
| use App\Attribut\ChildsAttribut; | ||||
| use Doctrine\Common\Collections\ArrayCollection; | ||||
|  | ||||
| class ChildsAttributTest extends TestCase | ||||
| { | ||||
|     /** | ||||
|      * @var ChildsAttributeInterface | ||||
|      * @var ChildsAttributInterface | ||||
|      */ | ||||
|     protected $childs; | ||||
|  | ||||
|     public function setUp(): void | ||||
|     { | ||||
|         $this->childs = new class() implements ChildsAttributeInterface { | ||||
|         $this->childs = new class() implements ChildsAttributInterface { | ||||
|             use ChildsAttribut; | ||||
|         }; | ||||
|     } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user