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

move-elevator / composer-translation-validator / 16589228037

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

Pull #59

github

jackd248
refactor: update validation test assertions and enhance property visibility in validation summary
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

93.1
/src/Validation/ValidationEngine.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\Validation;
25

26
use InvalidArgumentException;
27
use MoveElevator\ComposerTranslationValidator\Config\TranslationValidatorConfig;
28
use MoveElevator\ComposerTranslationValidator\Result\ValidationResult;
29
use MoveElevator\ComposerTranslationValidator\Service\ValidationOrchestrationService;
30
use MoveElevator\ComposerTranslationValidator\Validator\ValidatorRegistry;
31
use Psr\Log\LoggerInterface;
32
use RuntimeException;
33
use Throwable;
34

35
/**
36
 * Main API implementation for programmatic translation validation.
37
 *
38
 * This class provides the primary entry point for external packages
39
 * to validate translation files programmatically.
40
 */
41
final class ValidationEngine implements ValidationEngineInterface
42
{
43
    public function __construct(private readonly ValidationOrchestrationService $orchestrationService, private readonly LoggerInterface $logger) {}
17✔
44

45
    public function validatePaths(array $paths, array $options = []): ?ValidationResult
11✔
46
    {
47
        if (empty($paths)) {
11✔
48
            throw new InvalidArgumentException('Paths array cannot be empty');
1✔
49
        }
50

51
        $validationOptions = ValidationOptions::fromArray($options);
10✔
52
        $config = $this->createConfigFromOptions($validationOptions);
10✔
53

54
        // Resolve absolute paths
55
        $absolutePaths = $this->orchestrationService->resolvePaths($paths, $config);
10✔
56

57
        // Resolve file detector
58
        $fileDetector = $this->orchestrationService->resolveFileDetector($config);
10✔
59

60
        // Resolve validators
61
        $validators = $this->orchestrationService->resolveValidators(
10✔
62
            $validationOptions->onlyValidators,
10✔
63
            $validationOptions->skipValidators,
10✔
64
            $config,
10✔
65
        );
10✔
66

67
        try {
68
            return $this->orchestrationService->executeValidation(
10✔
69
                $absolutePaths,
10✔
70
                $validationOptions->excludePatterns,
10✔
71
                $validationOptions->recursive,
10✔
72
                $fileDetector,
10✔
73
                $validators,
10✔
74
                $config,
10✔
75
            );
10✔
76
        } catch (Throwable $e) {
1✔
77
            $this->logger->error('Validation execution failed', [
1✔
78
                'error' => $e->getMessage(),
1✔
79
                'paths' => $paths,
1✔
80
                'options' => $options,
1✔
81
            ]);
1✔
82
            throw new RuntimeException(sprintf('Validation failed: %s', $e->getMessage()), 0, $e);
1✔
83
        }
84
    }
85

86
    public function validateProject(string $projectPath, array $configuration = []): ?ValidationResult
5✔
87
    {
88
        if (empty($projectPath)) {
5✔
89
            throw new InvalidArgumentException('Project path cannot be empty');
1✔
90
        }
91

92
        if (!is_dir($projectPath)) {
4✔
93
            throw new InvalidArgumentException(sprintf('Project path "%s" is not a valid directory', $projectPath));
1✔
94
        }
95

96
        // Use project path as single path to validate
97
        $paths = [rtrim($projectPath, '/')];
3✔
98

99
        // Enable recursive by default for project validation
100
        $options = array_merge(['recursive' => true], $configuration);
3✔
101

102
        return $this->validatePaths($paths, $options);
3✔
103
    }
104

105
    public function getAvailableValidators(): array
3✔
106
    {
107
        return ValidatorRegistry::getAvailableValidators();
3✔
108
    }
109

110
    public function isReady(): bool
2✔
111
    {
112
        try {
113
            // Check if we have validators available
114
            $validators = $this->getAvailableValidators();
2✔
115
            if (empty($validators)) {
2✔
NEW
116
                return false;
×
117
            }
118

119
            // Basic readiness checks passed
120

121
            return true;
2✔
NEW
122
        } catch (Throwable) {
×
NEW
123
            return false;
×
124
        }
125
    }
126

127
    /**
128
     * Create configuration from validation options.
129
     */
130
    private function createConfigFromOptions(ValidationOptions $options): TranslationValidatorConfig
10✔
131
    {
132
        $config = new TranslationValidatorConfig();
10✔
133

134
        if (!empty($options->onlyValidators)) {
10✔
135
            $config->setOnly($options->onlyValidators);
1✔
136
        }
137

138
        if (!empty($options->skipValidators)) {
10✔
139
            $config->setSkip($options->skipValidators);
1✔
140
        }
141

142
        if (!empty($options->excludePatterns)) {
10✔
143
            $config->setExclude($options->excludePatterns);
1✔
144
        }
145

146
        if (null !== $options->fileDetector) {
10✔
NEW
147
            $config->setFileDetectors([$options->fileDetector]);
×
148
        }
149

150
        $config->setDryRun($options->dryRun);
10✔
151
        $config->setStrict($options->strict);
10✔
152

153
        return $config;
10✔
154
    }
155
}
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