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

move-elevator / composer-translation-validator / 16589183308

29 Jul 2025 07:08AM UTC coverage: 96.6% (-0.009%) from 96.609%
16589183308

Pull #59

github

jackd248
refactor: improve variable naming for clarity in validation summary and update test assertion for null result
Pull Request #59: refactor: domain architecture

121 of 125 new or added lines in 10 files covered. (96.8%)

8 existing lines in 4 files now uncovered.

2358 of 2441 relevant lines covered (96.6%)

8.14 hits per line

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

96.49
/src/Result/ValidationRun.php
1
<?php
2

3
declare(strict_types=1);
4

5
/*
6
 * This file is part of the Composer plugin "composer-translation-validator".
7
 *
8
 * Copyright (C) 2025 Konrad Michalik <km@move-elevator.de>
9
 *
10
 * This program is free software: you can redistribute it and/or modify
11
 * it under the terms of the GNU General Public License as published by
12
 * the Free Software Foundation, either version 3 of the License, or
13
 * (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
 * GNU General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU General Public License
21
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22
 */
23

24
namespace MoveElevator\ComposerTranslationValidator\Result;
25

26
use MoveElevator\ComposerTranslationValidator\Config\TranslationValidatorConfig;
27
use MoveElevator\ComposerTranslationValidator\FileDetector\FileSet;
28
use MoveElevator\ComposerTranslationValidator\Parser\ParserCache;
29
use MoveElevator\ComposerTranslationValidator\Validator\ResultType;
30
use MoveElevator\ComposerTranslationValidator\Validator\ValidatorInterface;
31
use Psr\Log\LoggerInterface;
32
use Throwable;
33

34
class ValidationRun
35
{
36
    public function __construct(private readonly LoggerInterface $logger) {}
11✔
37

38
    /**
39
     * @param array<FileSet>                          $fileSets
40
     * @param array<class-string<ValidatorInterface>> $validatorClasses
41
     */
42
    public function executeFor(array $fileSets, array $validatorClasses, ?TranslationValidatorConfig $config = null): ValidationResult
11✔
43
    {
44
        $startTime = microtime(true);
11✔
45
        $validatorInstances = [];
11✔
46
        $validatorFileSetPairs = [];
11✔
47
        $overallResult = ResultType::SUCCESS;
11✔
48
        $filesChecked = 0;
11✔
49

50
        foreach ($fileSets as $fileSet) {
11✔
51
            $filesChecked += count($fileSet->getFiles());
8✔
52
            foreach ($validatorClasses as $validatorClass) {
8✔
53
                // Create a new validator instance for each FileSet to ensure isolation
54
                $validatorInstance = new $validatorClass($this->logger);
7✔
55

56
                // Pass config to validator if it supports it
57
                if (null !== $config && method_exists($validatorInstance, 'setConfig')) {
7✔
UNCOV
58
                    $validatorInstance->setConfig($config);
×
59
                }
60

61
                /** @var class-string<\MoveElevator\ComposerTranslationValidator\Parser\ParserInterface> $parserClass */
62
                $parserClass = $fileSet->getParser();
7✔
63
                $result = $validatorInstance->validate($fileSet->getFiles(), $parserClass);
7✔
64
                if (!empty($result)) {
7✔
65
                    $overallResult = $overallResult->max($validatorInstance->resultTypeOnValidationFailure());
6✔
66
                    $validatorInstances[] = $validatorInstance;
6✔
67
                    $validatorFileSetPairs[] = [
6✔
68
                        'validator' => $validatorInstance,
6✔
69
                        'fileSet' => $fileSet,
6✔
70
                    ];
6✔
71
                }
72
            }
73
        }
74

75
        $keysChecked = $this->countKeysChecked($fileSets);
11✔
76

77
        $validatorsRun = count($validatorClasses);
11✔
78

79
        // Get cache statistics before clearing cache
80
        $cacheStats = ParserCache::getCacheStats();
11✔
81
        $parsersCached = $cacheStats['cached_parsers'];
11✔
82

83
        $executionTime = microtime(true) - $startTime;
11✔
84
        $statistics = new ValidationStatistics(
11✔
85
            $executionTime,
11✔
86
            $filesChecked,
11✔
87
            $keysChecked,
11✔
88
            $validatorsRun,
11✔
89
            $parsersCached,
11✔
90
        );
11✔
91

92
        $validationResult = new ValidationResult($validatorInstances, $overallResult, $validatorFileSetPairs, $statistics);
11✔
93
        ParserCache::clear();
11✔
94

95
        return $validationResult;
11✔
96
    }
97

98
    /**
99
     * @param array<string, array<string, array<string, array<string>>>> $allFiles
100
     *
101
     * @return array<FileSet>
102
     */
103
    public static function createFileSetsFromArray(array $allFiles): array
4✔
104
    {
105
        $fileSets = [];
4✔
106

107
        foreach ($allFiles as $parser => $paths) {
4✔
108
            foreach ($paths as $path => $translationSets) {
3✔
109
                foreach ($translationSets as $setKey => $files) {
3✔
110
                    $fileSets[] = new FileSet($parser, $path, $setKey, $files);
3✔
111
                }
112
            }
113
        }
114

115
        return $fileSets;
4✔
116
    }
117

118
    /**
119
     * @param array<FileSet> $fileSets
120
     */
121
    private function countKeysChecked(array $fileSets): int
11✔
122
    {
123
        $keysChecked = 0;
11✔
124

125
        foreach ($fileSets as $fileSet) {
11✔
126
            $parserClass = $fileSet->getParser();
8✔
127

128
            foreach ($fileSet->getFiles() as $file) {
8✔
129
                try {
130
                    $parser = ParserCache::get($file, $parserClass);
8✔
131
                    if (false === $parser) {
4✔
UNCOV
132
                        continue;
×
133
                    }
134
                    $keys = $parser->extractKeys();
4✔
135
                    if (is_array($keys)) {
3✔
136
                        $keysChecked += count($keys);
3✔
137
                    }
138
                } catch (Throwable) {
5✔
139
                    // Skip files that can't be parsed
140
                }
141
            }
142
        }
143

144
        return $keysChecked;
11✔
145
    }
146
}
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

© 2025 Coveralls, Inc