diff --git a/src/PhpFile.php b/src/PhpFile.php index 0b4deac..055a696 100644 --- a/src/PhpFile.php +++ b/src/PhpFile.php @@ -16,8 +16,8 @@ class PhpFile extends DependencyAwareGenerator protected string $name; protected ?Comment $comment; - /** @var PhpClass[] */ - protected array $classes = []; + /** @var OOPStructure[] */ + protected array $oopStructures = []; /** @var string[] */ protected array $declares = []; @@ -25,7 +25,7 @@ class PhpFile extends DependencyAwareGenerator public function __construct(string $name = '') { $this->name = $name; - $this->dependencyAwareChildren = [&$this->classes]; + $this->dependencyAwareChildren = [&$this->oopStructures]; } public static function new(string $name = ''): self @@ -36,12 +36,12 @@ public static function new(string $name = ''): self public function generate(): string { $namespace = $this->namespace ? "\nnamespace $this->namespace;\n" : ''; - $classes = implode("\n\n", $this->classes); + $oopStructures = implode("\n\n", $this->oopStructures); return <<buildUseStatements()} - $classes + $oopStructures CODE; } @@ -50,38 +50,92 @@ public function __toString(): string return $this->generate(); } + public function removeOOPStructure(string $name, ?string $type = null): self + { + foreach ($this->oopStructures as $key => $oopStructure) { + if ($oopStructure->name === $name && ($type === null || $oopStructure instanceof $type)) { + unset($this->oopStructures[$key]); + } + } + + return $this; + } + + public function getOOPStructure(string $name, ?string $type = null): ?OOPStructure + { + foreach ($this->oopStructures as $key => $oopStructure) { + if ($oopStructure->name === $name && ($type === null || $oopStructure instanceof $type)) { + return $this->oopStructures[$key]; + } + } + + return null; + } + public function addClass(PhpClass $class): self { - $this->classes[] = $class; + $this->oopStructures[] = $class; return $this; } public function createClass(string $name): PhpClass { - return $this->classes[] = PhpClass::new($name); + return $this->oopStructures[] = PhpClass::new($name); } public function removeClass(string $name): self { - foreach ($this->classes as $key => $class) { - if ($class->name === $name) { - unset($this->classes[$key]); - } - } + return $this->removeOOPStructure($name, PhpClass::class); + } + + public function getClass(string $name): ?PhpClass + { + return $this->getOOPStructure($name, PhpClass::class); + } + + public function addTrait(PhpTrait $trait): self + { + $this->oopStructures[] = $trait; return $this; } - public function getClass(string $name): ?PhpClass + public function createTrait(string $name): PhpTrait { - foreach ($this->classes as $key => $class) { - if ($class->name === $name) { - return $this->classes[$key]; - } - } + return $this->oopStructures[] = PhpTrait::new($name); + } - return null; + public function removeTrait(string $name): self + { + return $this->removeOOPStructure($name, PhpTrait::class); + } + + public function getTrait(string $name): ?PhpTrait + { + return $this->getOOPStructure($name, PhpTrait::class); + } + + public function addInterface(PhpInterface $trait): self + { + $this->oopStructures[] = $trait; + + return $this; + } + + public function createInterface(string $name): PhpInterface + { + return $this->oopStructures[] = PhpInterface::new($name); + } + + public function removeInterface(string $name): self + { + return $this->removeOOPStructure($name, PhpInterface::class); + } + + public function getInterface(string $name): ?PhpInterface + { + return $this->getOOPStructure($name, PhpInterface::class); } public function getNamespace(): string diff --git a/tests/PhpFileTest.php b/tests/PhpFileTest.php index b61ff58..ae90cfd 100644 --- a/tests/PhpFileTest.php +++ b/tests/PhpFileTest.php @@ -11,6 +11,9 @@ use Murtukov\PHPCodeGenerator\Modifier; use Murtukov\PHPCodeGenerator\PhpClass; use Murtukov\PHPCodeGenerator\PhpFile; +use Murtukov\PHPCodeGenerator\PhpInterface; +use Murtukov\PHPCodeGenerator\PhpTrait; +use Murtukov\PHPCodeGenerator\Property; use Murtukov\PHPCodeGenerator\Qualifier; use PHPUnit\Framework\TestCase; @@ -167,7 +170,7 @@ public function modifyComments(PhpFile $file): PhpFile * @test * @depends modifyComments */ - public function saveFile(PhpFile $file): void + public function saveFile(PhpFile $file): PhpFile { $path = sys_get_temp_dir().'/PHPCodeGenerator/GeneratedFile.php'; @@ -189,5 +192,165 @@ public function saveFile(PhpFile $file): void // @phpstan-ignore-next-line $this->assertEquals(['status' => 200], $yetAnotherClass->getArray()); + + @unlink($path); + + return $file; + } + + /** + * @test + * @depends saveFile + */ + public function modifyFileClassToTrait(PhpFile $file): PhpFile + { + $file->removeClass('YetAnotherClass'); + $file->addTrait(new PhpTrait('TAnotherTrait')); + + $this->assertNull($file->getClass('NonExistentClass')); + $this->assertEquals('App\Converter', $file->getNamespace()); + + $this->assertNotNull($file->getTrait('TAnotherTrait')); + $this->assertNotNull($file->getOOPStructure('TAnotherTrait')); + $this->assertInstanceOf(PhpTrait::class, $file->getOOPStructure('TAnotherTrait')); + $this->assertNull($file->getClass('TAnotherTrait')); + $this->assertNull($file->getInterface('TAnotherTrait')); + + $this->expectOutputString(<<<'CODE' + createTrait('TYetAnotherTrait') + ->append(Method::new('getName')); + + $this->expectOutputString(<<<'CODE' + removeTrait('TAnotherTrait'); + $file->removeTrait('TYetAnotherTrait'); + $file->addInterface(new PhpInterface('IAnotherTrait')); + + $this->assertNull($file->getClass('NonExistentClass')); + $this->assertEquals('App\Converter', $file->getNamespace()); + + $this->assertNotNull($file->getInterface('IAnotherTrait')); + $this->assertNotNull($file->getOOPStructure('IAnotherTrait')); + $this->assertInstanceOf(PhpInterface::class, $file->getOOPStructure('IAnotherTrait')); + $this->assertNull($file->getClass('IAnotherTrait')); + $this->assertNull($file->getTrait('IAnotherTrait')); + + $this->expectOutputString(<<<'CODE' + createInterface('IYetAnotherTrait') + ->createSignature('getName'); + + $this->expectOutputString(<<<'CODE' + removeInterface('IAnotherTrait'); + + $this->expectOutputString(<<<'CODE' +