Skip to content
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

Merged
merged 6 commits into from
Jun 22, 2018
Merged

Conversation

jschaedl
Copy link
Contributor

@jschaedl jschaedl commented Jun 7, 2018

fixes #89

phpunit.xml Outdated
<directory>./src</directory>
</whitelist>
</filter>
</phpunit>
Copy link
Contributor Author

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>
Copy link
Member

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
Copy link
Member

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?

Copy link
Contributor Author

@jschaedl jschaedl Jun 7, 2018

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.

Copy link
Contributor

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.

Copy link
Contributor Author

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?

Copy link
Contributor

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;
Copy link
Member

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

Copy link
Contributor Author

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
Copy link
Member

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

Copy link
Member

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

Copy link
Contributor Author

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 ;-)

Copy link
Contributor Author

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());
Copy link
Member

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
Copy link
Member

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

Copy link
Contributor Author

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);
Copy link
Contributor

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

Copy link
Contributor Author

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>');
Copy link
Contributor

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.

Copy link
Contributor Author

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(
Copy link
Contributor

@smoench smoench Jun 7, 2018

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

Copy link
Contributor Author

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.

@jschaedl jschaedl removed the request for review from DavidBadura June 8, 2018 08:04
@jschaedl
Copy link
Contributor Author

jschaedl commented Jun 8, 2018

All fixes done! Please merge or comment :-)


private function createXml(DependencyContext $dependencyContext)
{
if (!class_exists("DomDocument")) {
Copy link
Collaborator

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>');
Copy link
Collaborator

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>');
Copy link
Collaborator

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>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useless "code"

Copy link
Contributor Author

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?

Copy link
Collaborator

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';
Copy link
Collaborator

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) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

empty

Copy link
Contributor

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

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all right :)

@timglabisch
Copy link
Collaborator

feel free to merge the code if it's ready.

*/
private function createXml(DependencyContext $dependencyContext)
{
if (!class_exists("\DomDocument")) {
Copy link
Contributor

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. ;-)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

compile time? ^^

Copy link
Contributor

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:

https://3v4l.org/f0hVj/vld#output


public function getLayers(): array
{
return $this->classNameLayerResolver->getLayers();
Copy link
Contributor

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

@smoench smoench merged commit f5c32b6 into master Jun 22, 2018
@smoench smoench deleted the junit-formatter branch June 22, 2018 11:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add JUnit formatter
5 participants