• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

systemsdk / phpcpd / #4

30 Dec 2024 04:42PM UTC coverage: 75.789%. Remained the same
#4

push

DKravtsov
phpcpd 8.0.0 release. Made codebase refactoring. Updated requirements php 8.3, updated composer dependencies, updated tests to the PHPUnit 11. Updated dev environment to the php 8.4, Phing 3.0, added code quality tools: ecs, phpstan.

271 of 379 new or added lines in 20 files covered. (71.5%)

65 existing lines in 13 files now uncovered.

648 of 855 relevant lines covered (75.79%)

2.18 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

74.42
/src/Log/PMD.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Systemsdk\PhpCPD\Log;
6

7
use DOMElement;
8
use DOMException;
9
use DOMNode;
10
use Systemsdk\PhpCPD\CodeCloneMap;
11
use Systemsdk\PhpCPD\Exceptions\LoggerException;
12

13
use function is_object;
14
use function sprintf;
15

16
final class PMD extends AbstractXmlLogger
17
{
18
    private const string CPD_ELEMENT_NAME = 'pmd-cpd';
19
    private const string DUPLICATION_ELEMENT_NAME = 'duplication';
20
    private const string FILE_ELEMENT_NAME = 'file';
21
    private const string CODE_FRAGMENT_ELEMENT_NAME = 'codefragment';
22
    private const string ATTRIBUTE_LINES_NAME = 'lines';
23
    private const string ATTRIBUTE_TOKENS_NAME = 'tokens';
24
    private const string ATTRIBUTE_PATH_NAME = 'path';
25
    private const string ATTRIBUTE_LINE_NAME = 'line';
26
    private const string ACTION_CREATE_ELEMENT = 'create-element';
27
    private const string ACTION_APPEND_CHILD = 'append-child';
28
    private const string ACTION_SET_ATTRIBUTE = 'set-attribute';
29

30
    /**
31
     * @throws LoggerException
32
     */
33
    public function processClones(CodeCloneMap $clones): void
34
    {
35
        try {
36
            $cpd = $this->document->createElement(self::CPD_ELEMENT_NAME);
1✔
37
            $this->checkResult($cpd, self::CPD_ELEMENT_NAME, self::ACTION_CREATE_ELEMENT);
1✔
38

39
            $result = $this->document->appendChild($cpd);
1✔
40
            $this->checkResult($result, self::CPD_ELEMENT_NAME, self::ACTION_APPEND_CHILD);
1✔
41

42
            foreach ($clones as $clone) {
1✔
43
                $duplicationEl = $this->document->createElement(self::DUPLICATION_ELEMENT_NAME);
1✔
44
                $this->checkResult($duplicationEl, self::DUPLICATION_ELEMENT_NAME, self::ACTION_CREATE_ELEMENT);
1✔
45

46
                $duplication = $cpd->appendChild($duplicationEl);
1✔
47
                $this->checkResult($duplication, self::DUPLICATION_ELEMENT_NAME, self::ACTION_APPEND_CHILD);
1✔
48

49
                /** @var DOMElement $duplication */
50
                $result1 = $duplication->setAttribute(self::ATTRIBUTE_LINES_NAME, (string)$clone->numberOfLines());
1✔
51
                $this->checkResult($result1, self::ATTRIBUTE_LINES_NAME, self::ACTION_SET_ATTRIBUTE);
1✔
52

53
                $result2 = $duplication->setAttribute(self::ATTRIBUTE_TOKENS_NAME, (string)$clone->numberOfTokens());
1✔
54
                $this->checkResult($result2, self::ATTRIBUTE_TOKENS_NAME, self::ACTION_SET_ATTRIBUTE);
1✔
55

56
                foreach ($clone->files() as $codeCloneFile) {
1✔
57
                    $fileEl = $this->document->createElement(self::FILE_ELEMENT_NAME);
1✔
58
                    $this->checkResult($fileEl, self::FILE_ELEMENT_NAME, self::ACTION_CREATE_ELEMENT);
1✔
59

60
                    $file = $duplication->appendChild($fileEl);
1✔
61
                    $this->checkResult($file, self::FILE_ELEMENT_NAME, self::ACTION_APPEND_CHILD);
1✔
62

63
                    /** @var DOMElement $file */
64
                    $result1 = $file->setAttribute(self::ATTRIBUTE_PATH_NAME, $codeCloneFile->name());
1✔
65
                    $this->checkResult($result1, self::ATTRIBUTE_PATH_NAME, self::ACTION_SET_ATTRIBUTE);
1✔
66

67
                    $result2 = $file->setAttribute(self::ATTRIBUTE_LINE_NAME, (string)$codeCloneFile->startLine());
1✔
68
                    $this->checkResult($result2, self::ATTRIBUTE_LINE_NAME, self::ACTION_SET_ATTRIBUTE);
1✔
69
                }
70

71
                $codeFragmentEl = $this->document->createElement(
1✔
72
                    self::CODE_FRAGMENT_ELEMENT_NAME,
1✔
73
                    $this->escapeForXml($clone->lines())
1✔
74
                );
1✔
75
                $this->checkResult($codeFragmentEl, self::CODE_FRAGMENT_ELEMENT_NAME, self::ACTION_CREATE_ELEMENT);
1✔
76

77
                $codeFragment = $duplication->appendChild($codeFragmentEl);
1✔
78
                $this->checkResult($codeFragment, self::CODE_FRAGMENT_ELEMENT_NAME, self::ACTION_APPEND_CHILD);
1✔
79
            }
80

81
            $this->flush();
1✔
NEW
82
        } catch (DOMException $exception) {
×
NEW
83
            throw new LoggerException($exception->getMessage());
×
84
        }
85
    }
86

87
    /**
88
     * @throws LoggerException
89
     */
90
    private function checkResult(DOMNode|false $result, string $name, string $type): void
91
    {
92
        if (is_object($result)) {
1✔
93
            return;
1✔
94
        }
95

NEW
96
        $error = 'Unknown action: %s';
×
97

NEW
98
        if ($type === self::ACTION_CREATE_ELEMENT) {
×
NEW
99
            $error = 'Can not create element: %s';
×
NEW
100
        } elseif ($type === self::ACTION_APPEND_CHILD) {
×
NEW
101
            $error = 'Can not add new child at the end: %s';
×
NEW
102
        } elseif ($type === self::ACTION_SET_ATTRIBUTE) {
×
NEW
103
            $error = 'Can not set attribute: %s';
×
104
        }
105

NEW
106
        $this->generateException($error, $name);
×
107
    }
108

109
    /**
110
     * @throws LoggerException
111
     */
112
    private function generateException(string $error, string $name): void
113
    {
NEW
114
        throw new LoggerException(sprintf($error, $name));
×
115
    }
116
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc