JunitOutputFormatter::outputResults()   C
last analyzed

Complexity

Conditions 10
Paths 17

Size

Total Lines 87
Code Lines 62

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 1 Features 1
Metric Value
cc 10
eloc 62
c 4
b 1
f 1
nc 17
nop 1
dl 0
loc 87
rs 6.9624

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace DaveLiddament\StaticAnalysisResultsBaseliner\Plugins\OutputFormatters;
6
7
use DaveLiddament\StaticAnalysisResultsBaseliner\Domain\Common\SarbException;
8
use DaveLiddament\StaticAnalysisResultsBaseliner\Domain\OutputFormatter\OutputFormatter;
9
use DaveLiddament\StaticAnalysisResultsBaseliner\Domain\ResultsParser\AnalysisResults;
10
use Webmozart\Assert\Assert;
11
12
final class JunitOutputFormatter implements OutputFormatter
13
{
14
    /**
15
     * @throws SarbException
16
     */
17
    public function outputResults(AnalysisResults $analysisResults): string
18
    {
19
        if (!extension_loaded('simplexml')) {
20
            throw new SarbException('Simple XML required for JUnit output format'); // @codeCoverageIgnore
21
        }
22
23
        if (0 === $analysisResults->getCount()) {
24
            return <<<XML
25
<?xml version="1.0" encoding="UTF-8"?>
26
<testsuites
27
        name="SARB" tests="1" failures="0">
28
    <testsuite errors="0" tests="1" failures="0" name="Success">
29
        <testcase name="Success"/>
30
    </testsuite>
31
</testsuites>
32
33
XML;
34
        }
35
36
        $xml = $this->getXmlString($analysisResults->getCount());
37
        $test = new \SimpleXMLElement($xml);
38
39
        $caseCount = 0;
40
        $previousRelativeFileName = null;
41
        $testsuite = null;
42
        foreach ($analysisResults->getAnalysisResults() as $analysisResult) {
43
            $details = $analysisResult->getFullDetails();
44
45
            /** @psalm-suppress MixedAssignment */
46
            $column = $details['column'] ?? null;
47
            if (is_numeric($column)) {
48
                $column = (string) ((int) $column);
49
            } else {
50
                $column = '0';
51
            }
52
53
            $relativeFileName = $analysisResult->getLocation()->getRelativeFileName()->getFileName();
54
55
            if ((null === $testsuite) || ($previousRelativeFileName !== $relativeFileName)) {
56
                // Add final counts to previous testsuite (if one exists)
57
                $this->addCounts($testsuite, $caseCount);
58
59
                $testsuite = $test->addChild('testsuite');
60
                Assert::notNull($testsuite, 'Can not add testsuite to XML');
61
                $testsuite->addAttribute('name', $relativeFileName);
62
63
                $previousRelativeFileName = $relativeFileName;
64
                $caseCount = 0;
65
            }
66
67
            $lineSprint = sprintf(
68
                '%s at %s (%d:%s)',
69
                $analysisResult->getType()->getType(),
70
                $analysisResult->getLocation()->getAbsoluteFileName()->getFileName(),
71
                $analysisResult->getLocation()->getLineNumber()->getLineNumber(),
72
                $column,
73
            );
74
            $testcase = $testsuite->addChild('testcase');
75
            Assert::notNull($testcase, 'Can not add testcase element to XML');
76
            $testcase->addAttribute('name', $lineSprint);
77
            $failure = $testcase->addChild('failure');
78
            Assert::notNull($failure, 'Can not add failure element to XML');
79
            $failure->addAttribute('type', $analysisResult->getSeverity()->getSeverity());
80
            $failure->addAttribute(
81
                'message',
82
                $analysisResult->getMessage(),
83
            );
84
            ++$caseCount;
85
        }
86
87
        $this->addCounts($testsuite, $caseCount);
88
89
        $dom = new \DOMDocument('1.0');
90
        $dom->preserveWhiteSpace = false;
91
        $dom->formatOutput = true;
92
        $asXml = $test->asXML();
93
94
        if (is_string($asXml) && ('' !== $asXml)) {
95
            $dom->loadXML($asXml);
96
        } else {
97
            throw new SarbException('xml could not be loaded'); // @codeCoverageIgnore
98
        }
99
        $saveXml = $dom->saveXML();
100
        if (false !== $saveXml) {
101
            return $saveXml;
102
        }
103
        throw new SarbException('dom could not be saved'); // @codeCoverageIgnore
104
    }
105
106
    private function getXmlString(int $issues): string
107
    {
108
        $xmlstr = <<<XML
109
<?xml version="1.0" encoding="UTF-8"?>
110
<testsuites
111
        name="SARB" tests="{$issues}" failures="{$issues}">
112
</testsuites>
113
114
XML;
115
116
        return $xmlstr;
117
    }
118
119
    public function getIdentifier(): string
120
    {
121
        return 'junit';
122
    }
123
124
    private function addCounts(?\SimpleXMLElement $testsuite, int $caseCount): void
125
    {
126
        if (null !== $testsuite) {
127
            $testsuite->addAttribute('errors', '0');
128
            $testsuite->addAttribute('tests', (string) $caseCount);
129
            $testsuite->addAttribute('failures', (string) $caseCount);
130
        }
131
    }
132
}
133