Skip to content

Commit

Permalink
refactor: Extract value objects
Browse files Browse the repository at this point in the history
- Extract OutputFilePath and OutputContent for generators
  • Loading branch information
MontealegreLuis committed Jul 8, 2021
1 parent 54faa3f commit 3773f14
Show file tree
Hide file tree
Showing 24 changed files with 164 additions and 89 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
[![CI workflow](https://github.com/montealegreluis/phuml/actions/workflows/ci.yml/badge.svg)](https://github.com/montealegreluis/phuml/actions/workflows/ci.yml)
[![Scrutinizer Code Quality][scrutinizer-badge]][scrutinizer]
[![Code Coverage][coverage-badge]][coverage]
[![Infection MSI](https://badge.stryker-mutator.io/github.com/montealegreluis/phuml/master)](https://infection.github.io)
[![Infection MSI](https://badge.stryker-mutator.io/github.com/montealegreluis/phuml/master)](https://dashboard.stryker-mutator.io/reports/github.com/montealegreluis/phuml/master)
[![Latest Stable Version][stable-badge]][packagist]
[![Minimum PHP Version][php-version-badge]][php]

Expand Down
4 changes: 2 additions & 2 deletions index.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
![CI workflow](https://github.com/montealegreluis/phuml/actions/workflows/ci.yml/badge.svg)
[![Scrutinizer Code Quality][scrutinizer-badge]][scrutinizer]
[![Code Coverage][coverage-badge]][coverage]
[![Infection MSI](https://badge.stryker-mutator.io/github.com/montealegreluis/phuml/master)](https://infection.github.io)
[![Infection MSI](https://badge.stryker-mutator.io/github.com/montealegreluis/phuml/master)](https://dashboard.stryker-mutator.io/reports/github.com/montealegreluis/phuml/master)
[![Latest Stable Version][stable-badge]][packagist]
[![Minimum PHP Version][php-badge]][php]

phUML is a fully automatic [UML][uml] class diagram generator written [PHP][php].
phUML is a fully automatic [UML][uml] class diagram generator written in [PHP][php].
It creates a class diagram from an Object-Oriented codebase based on the UML specification.

To successfully create UML diagrams with phUML you will need to install the [graphviz][graphviz] toolkit.
Expand Down
18 changes: 4 additions & 14 deletions src/Console/Commands/GeneratorInput.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
namespace PhUml\Console\Commands;

use PhUml\Parser\CodebaseDirectory;
use Webmozart\Assert\Assert;
use PhUml\Processors\OutputFilePath;

final class GeneratorInput
{
private CodebaseDirectory $directory;

private string $outputFile;
private OutputFilePath $outputFile;

/** @var mixed[] $options */
private array $options;
Expand All @@ -26,7 +26,7 @@ final class GeneratorInput
public function __construct(array $arguments, array $options)
{
$this->directory = new CodebaseDirectory($arguments['directory'] ?? '');
$this->setOutputFile($arguments);
$this->outputFile = new OutputFilePath($arguments['output'] ?? '');
$this->options = $options;
}

Expand All @@ -35,7 +35,7 @@ public function directory(): CodebaseDirectory
return $this->directory;
}

public function outputFile(): string
public function outputFile(): OutputFilePath
{
return $this->outputFile;
}
Expand All @@ -45,14 +45,4 @@ public function options(): array
{
return $this->options;
}

/** @param string[] $arguments */
private function setOutputFile(array $arguments): void
{
Assert::stringNotEmpty(
$arguments['output'] ?? '',
'The output file cannot be empty'
);
$this->outputFile = $arguments['output'];
}
}
27 changes: 9 additions & 18 deletions src/Console/Commands/StatisticsInput.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
use PhUml\Parser\CodebaseDirectory;
use PhUml\Parser\CodeFinder;
use PhUml\Parser\SourceCodeFinder;
use Webmozart\Assert\Assert;
use PhUml\Processors\OutputFilePath;

final class StatisticsInput
{
private string $directory;
private CodebaseDirectory $directory;

private string $outputFile;
private OutputFilePath $outputFile;

private bool $recursive;

Expand All @@ -26,29 +26,20 @@ final class StatisticsInput
*/
public function __construct(array $arguments, array $options)
{
$this->directory = $arguments['directory'] ?? '';
$this->directory = new CodebaseDirectory($arguments['directory'] ?? '');
$this->recursive = isset($options['recursive']) && (bool) $options['recursive'];
$this->setOutputFile($arguments);
$this->outputFile = new OutputFilePath($arguments['output'] ?? '');
}

public function outputFile(): string
public function outputFile(): OutputFilePath
{
return $this->outputFile;
}

/** @param string[] $arguments */
private function setOutputFile(array $arguments): void
{
Assert::stringNotEmpty(
$arguments['output'] ?? '',
'The output file cannot be empty'
);
$this->outputFile = $arguments['output'];
}

public function codeFinder(): CodeFinder
{
$directory = new CodebaseDirectory($this->directory);
return $this->recursive ? SourceCodeFinder::recursive($directory) : SourceCodeFinder::nonRecursive($directory);
return $this->recursive
? SourceCodeFinder::recursive($this->directory)
: SourceCodeFinder::nonRecursive($this->directory);
}
}
6 changes: 4 additions & 2 deletions src/Generators/ClassDiagramGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
use PhUml\Parser\CodeParser;
use PhUml\Processors\GraphvizProcessor;
use PhUml\Processors\ImageProcessor;
use PhUml\Processors\OutputContent;
use PhUml\Processors\OutputFilePath;

/**
* It generates a UML class diagram from a directory with PHP code
Expand Down Expand Up @@ -41,15 +43,15 @@ public function __construct(
*
* @throws LogicException If either the image processor or the command are missing
*/
public function generate(CodeFinder $finder, string $imagePath): void
public function generate(CodeFinder $finder, OutputFilePath $imagePath): void
{
$this->display()->start();
$image = $this->generateClassDiagram($this->generateDigraph($this->parseCode($finder)));
$this->save($this->imageProcessor, $image, $imagePath);
}

/** @throws LogicException If no command or image processor is provided */
private function generateClassDiagram(string $digraph): string
private function generateClassDiagram(OutputContent $digraph): OutputContent
{
$this->display()->runningProcessor($this->imageProcessor);
return $this->imageProcessor->process($digraph);
Expand Down
3 changes: 2 additions & 1 deletion src/Generators/DigraphGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use PhUml\Code\Codebase;
use PhUml\Parser\CodeParser;
use PhUml\Processors\GraphvizProcessor;
use PhUml\Processors\OutputContent;

class DigraphGenerator extends Generator
{
Expand All @@ -21,7 +22,7 @@ public function __construct(CodeParser $parser, GraphvizProcessor $digraphProces
$this->digraphProcessor = $digraphProcessor;
}

protected function generateDigraph(Codebase $codebase): string
protected function generateDigraph(Codebase $codebase): OutputContent
{
$this->display()->runningProcessor($this->digraphProcessor);
return $this->digraphProcessor->process($codebase);
Expand Down
3 changes: 2 additions & 1 deletion src/Generators/DotFileGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

use LogicException;
use PhUml\Parser\CodeFinder;
use PhUml\Processors\OutputFilePath;

/**
* It generates a file with a digraph in DOT format that can be used to create a class diagram
Expand All @@ -32,7 +33,7 @@ final class DotFileGenerator extends DigraphGenerator
*
* @throws LogicException If the command is missing
*/
public function generate(CodeFinder $finder, string $dotFilePath): void
public function generate(CodeFinder $finder, OutputFilePath $dotFilePath): void
{
$this->display()->start();

Expand Down
4 changes: 3 additions & 1 deletion src/Generators/Generator.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
use PhUml\Code\Codebase;
use PhUml\Parser\CodeFinder;
use PhUml\Parser\CodeParser;
use PhUml\Processors\OutputContent;
use PhUml\Processors\OutputFilePath;
use PhUml\Processors\Processor;

/**
Expand Down Expand Up @@ -53,7 +55,7 @@ protected function parseCode(CodeFinder $finder): Codebase
return $this->parser->parse($finder);
}

protected function save(Processor $processor, string $content, string $path): void
protected function save(Processor $processor, OutputContent $content, OutputFilePath $path): void
{
$this->display()->savingResult();
$processor->saveToFile($content, $path);
Expand Down
6 changes: 4 additions & 2 deletions src/Generators/StatisticsGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
use PhUml\Code\Codebase;
use PhUml\Parser\CodeFinder;
use PhUml\Parser\CodeParser;
use PhUml\Processors\OutputContent;
use PhUml\Processors\OutputFilePath;
use PhUml\Processors\StatisticsProcessor;
use PhUml\Templates\TemplateFailure;

Expand Down Expand Up @@ -40,14 +42,14 @@ public function __construct(CodeParser $parser, StatisticsProcessor $statisticsP
* @throws TemplateFailure If Twig fails
* @throws LogicException If the command is missing
*/
public function generate(CodeFinder $finder, string $statisticsFilePath): void
public function generate(CodeFinder $finder, OutputFilePath $statisticsFilePath): void
{
$this->display()->start();
$statistics = $this->generateStatistics($this->parseCode($finder));
$this->save($this->statisticsProcessor, $statistics, $statisticsFilePath);
}

private function generateStatistics(Codebase $codebase): string
private function generateStatistics(Codebase $codebase): OutputContent
{
$this->display()->runningProcessor($this->statisticsProcessor);
return $this->statisticsProcessor->process($codebase);
Expand Down
4 changes: 2 additions & 2 deletions src/Processors/GraphvizProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,13 @@ public function name(): string
return 'Graphviz';
}

public function process(Codebase $codebase): string
public function process(Codebase $codebase): OutputContent
{
$digraph = new Digraph();
foreach ($codebase->definitions() as $definition) {
$this->extractElements($definition, $codebase, $digraph);
}
return $this->printer->toDot($digraph);
return new OutputContent($this->printer->toDot($digraph));
}

protected function extractElements(
Expand Down
6 changes: 3 additions & 3 deletions src/Processors/ImageProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ public function __construct(Process $process = null, Filesystem $fileSystem = nu
/**
* It returns the contents of a `png` class diagram
*/
public function process(string $digraphInDotFormat): string
public function process(OutputContent $digraphInDotFormat): OutputContent
{
$dotFile = $this->fileSystem->tempnam('/tmp', 'phuml');
$imageFile = $this->fileSystem->tempnam('/tmp', 'phuml');

$this->fileSystem->dumpFile($dotFile, $digraphInDotFormat);
$this->fileSystem->dumpFile($dotFile, $digraphInDotFormat->value());
$this->fileSystem->remove($imageFile);

$this->execute($dotFile, $imageFile);
Expand All @@ -49,7 +49,7 @@ public function process(string $digraphInDotFormat): string
$this->fileSystem->remove($dotFile);
$this->fileSystem->remove($imageFile);

return $image;
return new OutputContent($image);
}

/**
Expand Down
23 changes: 23 additions & 0 deletions src/Processors/OutputContent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php declare(strict_types=1);
/**
* PHP version 7.4
*
* This source file is subject to the license that is bundled with this package in the file LICENSE.
*/

namespace PhUml\Processors;

final class OutputContent
{
private string $content;

public function __construct(string $content)
{
$this->content = $content;
}

public function value(): string
{
return $this->content;
}
}
27 changes: 27 additions & 0 deletions src/Processors/OutputFilePath.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php declare(strict_types=1);
/**
* PHP version 7.4
*
* This source file is subject to the license that is bundled with this package in the file LICENSE.
*/

namespace PhUml\Processors;

use SplFileInfo;
use Webmozart\Assert\Assert;

final class OutputFilePath
{
private SplFileInfo $filePath;

public function __construct(string $filePath)
{
Assert::stringNotEmpty(trim($filePath), 'Output file path cannot be empty');
$this->filePath = new SplFileInfo(trim($filePath));
}

public function value(): string
{
return $this->filePath->getPathname();
}
}
4 changes: 2 additions & 2 deletions src/Processors/Processor.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
*/
abstract class Processor
{
public function saveToFile(string $contents, string $filePath): void
public function saveToFile(OutputContent $contents, OutputFilePath $filePath): void
{
file_put_contents($filePath, $contents);
file_put_contents($filePath->value(), $contents->value());
}

abstract public function name(): string;
Expand Down
4 changes: 2 additions & 2 deletions src/Processors/StatisticsProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ public function name(): string
/**
* @throws TemplateFailure
*/
public function process(Codebase $codebase): string
public function process(Codebase $codebase): OutputContent
{
$summary = new Summary();
$summary->from($codebase);

return $this->engine->render('statistics.txt.twig', ['summary' => $summary]);
return new OutputContent($this->engine->render('statistics.txt.twig', ['summary' => $summary]));
}
}
11 changes: 6 additions & 5 deletions tests/integration/Generators/GenerateClassDiagramWithDotTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use PhUml\Parser\SourceCodeFinder;
use PhUml\Processors\DotProcessor;
use PhUml\Processors\GraphvizProcessor;
use PhUml\Processors\OutputFilePath;
use Prophecy\PhpUnit\ProphecyTrait;

final class GenerateClassDiagramWithDotTest extends TestCase
Expand All @@ -31,7 +32,7 @@ final class GenerateClassDiagramWithDotTest extends TestCase
function it_fails_to_generate_diagram_if_a_command_is_not_provided()
{
$this->expectException(LogicException::class);
$this->generator->generate(new StringCodeFinder(), 'wont-be-generated.png');
$this->generator->generate(new StringCodeFinder(), new OutputFilePath('wont-be-generated.png'));
}

/**
Expand All @@ -43,12 +44,12 @@ function it_generates_a_class_diagram()
$this->generator->attach($this->prophesize(ProcessorProgressDisplay::class)->reveal());
$directory = new CodebaseDirectory(__DIR__ . '/../../resources/.code/classes');
$finder = SourceCodeFinder::nonRecursive($directory);
$diagram = __DIR__ . '/../../resources/.output/graphviz-dot.png';
$diagram = new OutputFilePath(__DIR__ . '/../../resources/.output/graphviz-dot.png');
$expectedDiagram = __DIR__ . '/../../resources/images/graphviz-dot.png';

$this->generator->generate($finder, $diagram);

$this->assertImagesSame($expectedDiagram, $diagram);
$this->assertImagesSame($expectedDiagram, $diagram->value());
}

/**
Expand All @@ -59,12 +60,12 @@ function it_generates_a_class_diagram_using_a_recursive_finder()
{
$this->generator->attach($this->prophesize(ProcessorProgressDisplay::class)->reveal());
$codeFinder = SourceCodeFinder::recursive(new CodebaseDirectory(__DIR__ . '/../../resources/.code'));
$diagram = __DIR__ . '/../../resources/.output/graphviz-dot-recursive.png';
$diagram = new OutputFilePath(__DIR__ . '/../../resources/.output/graphviz-dot-recursive.png');
$expectedDiagram = __DIR__ . '/../../resources/images/graphviz-dot-recursive.png';

$this->generator->generate($codeFinder, $diagram);

$this->assertImagesSame($expectedDiagram, $diagram);
$this->assertImagesSame($expectedDiagram, $diagram->value());
}

/** @before */
Expand Down
Loading

0 comments on commit 3773f14

Please sign in to comment.