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

move-elevator / composer-translation-validator / 18559956393

16 Oct 2025 11:36AM UTC coverage: 95.519%. Remained the same
18559956393

Pull #73

github

jackd248
Merge remote-tracking branch 'origin/main' into php-cs-fixer-preset
Pull Request #73: build: add php-cs-fixer-preset

206 of 210 new or added lines in 16 files covered. (98.1%)

91 existing lines in 20 files now uncovered.

2345 of 2455 relevant lines covered (95.52%)

7.73 hits per line

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

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

3
declare(strict_types=1);
4

5
/*
6
 * This file is part of the "composer-translation-validator" Composer plugin.
7
 *
8
 * (c) 2025 Konrad Michalik <km@move-elevator.de>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13

14
namespace MoveElevator\ComposerTranslationValidator\Result;
15

16
use MoveElevator\ComposerTranslationValidator\Config\TranslationValidatorConfig;
17
use MoveElevator\ComposerTranslationValidator\FileDetector\FileSet;
18
use MoveElevator\ComposerTranslationValidator\Parser\ParserCache;
19
use MoveElevator\ComposerTranslationValidator\Validator\{ResultType, ValidatorInterface};
20
use Psr\Log\LoggerInterface;
21
use Throwable;
22

23
use function count;
24
use function is_array;
25

26
/**
27
 * ValidationRun.
28
 *
29
 * @author Konrad Michalik <km@move-elevator.de>
30
 * @license GPL-3.0-or-later
31
 */
32
class ValidationRun
33
{
34
    public function __construct(
8✔
35
        private readonly LoggerInterface $logger,
36
    ) {}
8✔
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
8✔
43
    {
44
        $startTime = microtime(true);
8✔
45
        $validatorInstances = [];
8✔
46
        $validatorFileSetPairs = [];
8✔
47
        $overallResult = ResultType::SUCCESS;
8✔
48
        $filesChecked = 0;
8✔
49

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

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

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

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

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

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

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

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

95
        return $validationResult;
8✔
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
3✔
104
    {
105
        $fileSets = [];
3✔
106

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

115
        return $fileSets;
3✔
116
    }
117

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

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

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

144
        return $keysChecked;
8✔
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