diff --git a/src/Graphviz/ObjectHashIdentifier.php b/src/Graphviz/ObjectHashIdentifier.php index 662fdfe..773246a 100644 --- a/src/Graphviz/ObjectHashIdentifier.php +++ b/src/Graphviz/ObjectHashIdentifier.php @@ -10,8 +10,7 @@ use PhUml\Code\WithName; /** - * Both `ClassDefinition` and `InterfaceDefinition` objects identifiers are generated using the - * function `spl_object_hash` + * Both `ClassDefinition` and `InterfaceDefinition` objects identifiers are generated using their Fully Qualified Name */ trait ObjectHashIdentifier { @@ -19,6 +18,6 @@ trait ObjectHashIdentifier public function identifier(): string { - return (string) $this->name(); + return $this->name->fullName(); } } diff --git a/src/Parser/Code/Builders/TagTypeFactory.php b/src/Parser/Code/Builders/TagTypeFactory.php index 5352341..9303006 100644 --- a/src/Parser/Code/Builders/TagTypeFactory.php +++ b/src/Parser/Code/Builders/TagTypeFactory.php @@ -89,7 +89,18 @@ private function resolveType(?Type $type): ?TagType $type === null => null, $type instanceof Nullable => TagType::nullable((string) $type->getActualType()), $type instanceof Compound => TagType::compound(array_map('strval', $type->getIterator()->getArrayCopy())), - default => TagType::named((string) ($type instanceof Object_ ? $type->getFqsen() : $type)) + default => $this->fromType($type) }; } + + private function fromType(Type $type): TagType + { + if (! $type instanceof Object_) { + return TagType::named((string) $type); + } + if ($type->getFqsen() === null) { + return TagType::named((string) $type); + } + return TagType::named((string) $type->getFqsen()); + } } diff --git a/tests/src/Fakes/WithDotLanguageAssertions.php b/tests/src/Fakes/WithDotLanguageAssertions.php index 2178b31..e728da6 100644 --- a/tests/src/Fakes/WithDotLanguageAssertions.php +++ b/tests/src/Fakes/WithDotLanguageAssertions.php @@ -16,8 +16,9 @@ trait WithDotLanguageAssertions { public function assertNode(Definition $definition, string $dotLanguage): void { + $identifier = str_replace('\\', '\\\\', $definition->identifier()); $this->assertMatchesRegularExpression( - "/\"{$definition->identifier()}\" \\[label=<(?:.)+{$definition->name()}(?:.)+> shape=plaintext color=\"#[0-9a-f]{6}\"\\]/", + "/\"{$identifier}\" \\[label=<(?:.)+{$definition->name()}(?:.)+> shape=plaintext color=\"#[0-9a-f]{6}\"\\]/", $dotLanguage, "Definition {$definition->name()} with identifier {$definition->identifier()} cannot be found" ); @@ -28,8 +29,10 @@ public function assertInheritance( Definition $parent, string $dotLanguage ): void { + $parentIdentifier = str_replace('\\', '\\\\', $parent->identifier()); + $identifier = str_replace('\\', '\\\\', $definition->identifier()); $this->assertMatchesRegularExpression( - "/\"{$parent->identifier()}\" -> \"{$definition->identifier()}\" \\[dir=back arrowtail=empty style=solid color=\"#[0-9a-f]{6}\"\\]/", + "/\"{$parentIdentifier}\" -> \"{$identifier}\" \\[dir=back arrowtail=empty style=solid color=\"#[0-9a-f]{6}\"\\]/", $dotLanguage, "{$definition->name()} identified by {$definition->identifier()} does not inherits {$parent->name()} identified by {$parent->identifier()}" ); @@ -40,8 +43,10 @@ public function assertImplementation( InterfaceDefinition $interface, string $dotLanguage ): void { + $interfaceIdentifier = str_replace('\\', '\\\\', $interface->identifier()); + $identifier = str_replace('\\', '\\\\', $class->identifier()); $this->assertMatchesRegularExpression( - "/\"{$interface->identifier()}\" -> \"{$class->identifier()}\" \\[dir=back arrowtail=empty style=dashed color=\"#[0-9a-f]{6}\"\\]/", + "/\"{$interfaceIdentifier}\" -> \"{$identifier}\" \\[dir=back arrowtail=empty style=dashed color=\"#[0-9a-f]{6}\"\\]/", $dotLanguage, "{$class->name()} does not implements {$interface->name()}" ); diff --git a/tests/unit/Generators/GenerateDotFileTest.php b/tests/unit/Generators/GenerateDotFileTest.php index 3405258..9187b35 100644 --- a/tests/unit/Generators/GenerateDotFileTest.php +++ b/tests/unit/Generators/GenerateDotFileTest.php @@ -29,8 +29,8 @@ function it_creates_the_dot_file_of_a_directory() $digraph = $this->processor->process($codebase); - $this->assertNode(A::classNamed('plBase'), $digraph->value()); - $this->assertNode(A::classNamed('plPhuml'), $digraph->value()); + $this->assertNode(A::classNamed('phuml\plBase'), $digraph->value()); + $this->assertNode(A::classNamed('phuml\plPhuml'), $digraph->value()); } /** @test */ @@ -42,14 +42,14 @@ function it_creates_the_dot_file_of_a_directory_using_a_recursive_finder() $digraph = $this->processor->process($codebase); - $base = A::classNamed('plBase'); + $base = A::classNamed('phuml\plBase'); $tokenParser = A::classNamed('plStructureTokenparserGenerator'); $attribute = A::classNamed('plPhpAttribute'); $class = A::classNamed('plPhpClass'); $function = A::classNamed('plPhpFunction'); $parameter = A::classNamed('plPhpFunctionParameter'); $interface = A::classNamed('plPhpInterface'); - $uml = A::classNamed('plPhuml'); + $uml = A::classNamed('phuml\plPhuml'); $dotProcessor = A::classNamed('plDotProcessor'); $graphvizProcessor = A::classNamed('plGraphvizProcessor'); $styleName = A::classNamed('plStyleName'); @@ -60,7 +60,7 @@ function it_creates_the_dot_file_of_a_directory_using_a_recursive_finder() $statisticsProcessor = A::classNamed('plStatisticsProcessor'); $structureGenerator = A::classNamed('plStructureGenerator'); $externalCommand = A::classNamed('plExternalCommandProcessor'); - $processor = A::classNamed('plProcessor'); + $processor = A::classNamed('phuml\interfaces\plProcessor'); $style = A::classNamed('plGraphvizProcessorStyle'); $this->assertNode($base, $digraph->value()); $this->assertNode($structureGenerator, $digraph->value()); diff --git a/tests/unit/Parser/Code/TypeResolverTest.php b/tests/unit/Parser/Code/TypeResolverTest.php index a4f7969..63cfe47 100644 --- a/tests/unit/Parser/Code/TypeResolverTest.php +++ b/tests/unit/Parser/Code/TypeResolverTest.php @@ -17,6 +17,22 @@ final class TypeResolverTest extends TestCase { + /** @test */ + function it_resolves_built_in_types() + { + $useStatements = new UseStatements([]); + + $objectType = $this->resolver->resolveForAttribute('/** @var object */', $useStatements); + $mixedType = $this->resolver->resolveForReturn('/** @return mixed */', $useStatements); + $stringType = $this->resolver->resolveForParameter('/** @param string[] $test */', '$test', $useStatements); + $boolType = $this->resolver->resolveForAttribute('/** @var bool */', $useStatements); + + $this->assertEquals('object', (string) $objectType); + $this->assertEquals('mixed', (string) $mixedType); + $this->assertEquals('string[]', (string) $stringType); + $this->assertEquals('bool', (string) $boolType); + } + /** @test */ function it_resolves_to_absent_type_if_doc_block_is_invalid() {