-
Notifications
You must be signed in to change notification settings - Fork 134
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add output formatter to create junit reports #167
Conversation
phpunit.xml
Outdated
<directory>./src</directory> | ||
</whitelist> | ||
</filter> | ||
</phpunit> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, this file shouldn't be here. Will remove it.
phpunit.xml
Outdated
<whitelist> | ||
<exclude> | ||
<directory>./src/Command</directory> | ||
<directory>./src/CompilerPass</directory> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this directory does not seem to exist
@@ -59,4 +60,11 @@ public function getLayersByClassName(string $className): array | |||
|
|||
return array_keys($layers); | |||
} | |||
|
|||
public function getLayers(): array |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getLayerNames()
? Is it actually required that we do the filtering here instead of letting the consumer decide which information of the layers they are interested in?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if I understand your question, but couldn't you define the layers you want to see in the yaml config file? So if I want to see different layers, I would create different config files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be renamed to getLayerNames
as we return names of the layers. But instead just returning names I think we should return layer-objects.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about the getLayersByClassName(...)
? It is returning names as well. I would rename it too, ok?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Layers are represented as a string. I am fine keeping these names. But we should rename this class to e.g. LayerResolver
.
|
||
class JUnitOutputFormatter implements OutputFormatterInterface | ||
{ | ||
protected $eventDispatcher; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this property does not seem to be used
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Absolutely, will be removed.
use SensioLabs\Deptrac\RulesetEngine\RulesetViolation; | ||
use Symfony\Component\Console\Output\OutputInterface; | ||
|
||
class JUnitOutputFormatter implements OutputFormatterInterface |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the class is missing an @author
tag
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and the class could be made final
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, none of the classes in this project have an @author
tag. But someone needs to start using it, right ;-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will make it final
{ | ||
public function testGetName() | ||
{ | ||
$this->assertEquals('junit', (new JUnitOutputFormatter())->getName()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assertSame()
/** | ||
* @param array $layers | ||
* @param array $violations | ||
* @param $expectedOutput |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the @param
tags are not really necessary
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will remove them.
|
||
private function normalize($str) | ||
{ | ||
return str_replace(["\t", "\n", ' '], '', $str); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seams like we could use trim
instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not really, because line breaks and tabs should be removed within the string as well. trim
removes the defined characters only at the beginning and the end of a string.
file_put_contents($dumpXmlPath, $xml); | ||
$output->writeln(PHP_EOL . '<info>JUnit Report dumped to '.realpath($dumpXmlPath).'</info>'); | ||
} else { | ||
$output->writeln(PHP_EOL . '<info>JUnit Report dump:</info>'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should not print any string/line before, because it would be more difficult to pipe the XML-Result into an other programm.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, will change this.
); | ||
|
||
$o = $output->fetch(); | ||
$this->assertEquals( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could use $this->assertXmlStringEqualsXmlString(...)
instead if the pre output has been removed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I will change this completely and will use $this->assertXmlFileEqualsXmlFile(...)
. It is easier to read and easier to add new test data later.
All fixes done! Please merge or comment :-) |
|
||
private function createXml(DependencyContext $dependencyContext) | ||
{ | ||
if (!class_exists("DomDocument")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
\DomDocument::class
|
||
if ($dumpXmlPath = $outputFormatterInput->getOption(static::$argument_dump_xml) ?: './junit-report.xml') { | ||
file_put_contents($dumpXmlPath, $xml); | ||
$output->writeln('<info>JUnit Report dumped to '.realpath($dumpXmlPath).'</info>'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
early retun instead of else
|
||
if ($dumpXmlPath = $outputFormatterInput->getOption(static::$argument_dump_xml) ?: './junit-report.xml') { | ||
file_put_contents($dumpXmlPath, $xml); | ||
$output->writeln('<info>JUnit Report dumped to '.realpath($dumpXmlPath).'</info>'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
coding style (space)
use Symfony\Component\Console\Output\BufferedOutput; | ||
|
||
/** | ||
* @author Jan Schädlich <janschaedlich@sensiolabs.de> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
useless "code"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So an author tag is generally not needed? @xabbuh wrote it should have one: https://github.com/sensiolabs-de/deptrac/pull/167/files/98ce07cd86eaa99238303828812d5b6e972c631e#diff-571a84413ead5d19e843d892a9f55ebf
What is the general guideline for this project? No comments at all?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there is no guideline, but also no technical reason why to embed a @author
annotation. feel free to discuss this with the sensio team. from my point of view, huge 👎 for any kind of "noise".
@author
statements also harm refactoring, because nobody likes to remove them.
*/ | ||
class JUnitOutputFormatterTest extends TestCase | ||
{ | ||
const ACTUAL_JUNIT_REPORT_FILE = 'actual-junit-report.xml'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be private
$layerIndex = 0; | ||
foreach ($layers as $layer) { | ||
$violationsByLayer = $dependencyContext->getViolationsByLayerName($layer); | ||
if (count($violationsByLayer) === 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
empty
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
empty
is to weak. empty could be ""
, 0
, "0"
, null
, false
or array()
.
I avoid empty, because you never know exactly what everything is checked.
👍 for count
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
all right :)
5e13eec
to
38e923e
Compare
feel free to merge the code if it's ready. |
*/ | ||
private function createXml(DependencyContext $dependencyContext) | ||
{ | ||
if (!class_exists("\DomDocument")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you have misunderstood the comment. The line should look like this:
if (!class_exists(\DomDocument::class)) {
This does not throw any errors if the class does not exist. The class name is resolved at compile time. ;-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
compile time? ^^
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PHP files are run in two stages compile time
& run time
:
PHP source code -(compile time)-> zend opcode -(run time)-> result
In the compiler step, the ::class
expression is converted to a string. See:
https://3v4l.org/fHY7h/vld#output
And here's an example with a nonexistent class:
|
||
public function getLayers(): array | ||
{ | ||
return $this->classNameLayerResolver->getLayers(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be cached, too
fixes #89