Skip to content

Commit dda4f69

Browse files
test: add unit tests for configuration file reading and validation
1 parent 283be23 commit dda4f69

4 files changed

Lines changed: 156 additions & 0 deletions

File tree

phpunit.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
44
displayDetailsOnTestsThatTriggerWarnings="true"
55
displayDetailsOnTestsThatTriggerNotices="true"
6+
displayDetailsOnSkippedTests="true"
67
bootstrap="vendor/autoload.php"
78
colors="true"
89
>

tests/src/Config/ConfigFileReaderTest.php

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,4 +189,61 @@ public function testReadPhpFileWithInvalidReturn(): void
189189

190190
$this->reader->readAsConfig($configPath);
191191
}
192+
193+
public function testReadPhpConfigWithInvalidPath(): void
194+
{
195+
// We need to test readAsConfig() directly for PHP files to reach the realpath() check
196+
$configPath = $this->tempDir.'/config.php';
197+
$brokenLink = $this->tempDir.'/broken_link.php';
198+
199+
file_put_contents($configPath, '<?php return "test";');
200+
symlink($configPath, $brokenLink);
201+
unlink($configPath); // Break the symlink
202+
203+
$this->expectException(\RuntimeException::class);
204+
$this->expectExceptionMessage('Invalid configuration file path');
205+
206+
$this->reader->readAsConfig($brokenLink);
207+
}
208+
209+
public function testReadJsonConfigWithNonArrayContent(): void
210+
{
211+
$configPath = $this->tempDir.'/config.json';
212+
file_put_contents($configPath, '"string-content"');
213+
214+
$this->expectException(\RuntimeException::class);
215+
$this->expectExceptionMessage('Invalid JSON configuration file');
216+
217+
$this->reader->readFile($configPath);
218+
}
219+
220+
public function testReadYamlConfigWithNonArrayContent(): void
221+
{
222+
$configPath = $this->tempDir.'/config.yaml';
223+
file_put_contents($configPath, '"string-content"');
224+
225+
$this->expectException(\RuntimeException::class);
226+
$this->expectExceptionMessage('Invalid YAML configuration file');
227+
228+
$this->reader->readFile($configPath);
229+
}
230+
231+
public function testReadAsConfigUsesDirectPhpConfigPath(): void
232+
{
233+
// Test that readAsConfig() uses the direct PHP config path
234+
$configPath = $this->tempDir.'/config.php';
235+
$phpContent = '<?php
236+
use MoveElevator\ComposerTranslationValidator\Config\TranslationValidatorConfig;
237+
238+
$config = new TranslationValidatorConfig();
239+
$config->setPaths([\'direct-php-test\']);
240+
return $config;
241+
';
242+
243+
file_put_contents($configPath, $phpContent);
244+
245+
$config = $this->reader->readAsConfig($configPath);
246+
247+
$this->assertSame(['direct-php-test'], $config->getPaths());
248+
}
192249
}

tests/src/FileDetector/CollectorTest.php

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,4 +356,64 @@ public function testRecursiveCollectionUsesRealFixtures(): void
356356
// Should find files at multiple levels
357357
$this->assertNotEmpty($result);
358358
}
359+
360+
public function testCollectFilesWithoutDetector(): void
361+
{
362+
// Test fallback to FileDetectorRegistry when no detector is provided
363+
file_put_contents($this->tempDir.'/test.xlf', 'xliff content');
364+
365+
$logger = $this->createMock(LoggerInterface::class);
366+
$collector = new Collector($logger);
367+
368+
// Test without providing a detector (should use registry)
369+
$result = $collector->collectFiles([$this->tempDir], null, null, false);
370+
371+
// Should use FileDetectorRegistry and find files
372+
$this->assertNotEmpty($result);
373+
}
374+
375+
public function testCollectFilesWithFileDetectorReturningEmptyResults(): void
376+
{
377+
// Create a file that exists but won't be detected by any file detector
378+
file_put_contents($this->tempDir.'/test.xlf', 'xliff content');
379+
380+
$logger = $this->createMock(LoggerInterface::class);
381+
382+
// Mock a detector that returns empty results
383+
$detector = $this->createMock(DetectorInterface::class);
384+
$detector->method('mapTranslationSet')->willReturn([]);
385+
386+
$collector = new Collector($logger);
387+
388+
$result = $collector->collectFiles([$this->tempDir], $detector, null, false);
389+
390+
// When detector returns empty results, the result structure will include
391+
// the parser class with the empty translation set
392+
$this->assertNotEmpty($result);
393+
394+
// Check that the translation set is empty
395+
$xliffParserClass = XliffParser::class;
396+
$this->assertArrayHasKey($xliffParserClass, $result);
397+
$this->assertArrayHasKey($this->tempDir, $result[$xliffParserClass]);
398+
$this->assertEmpty($result[$xliffParserClass][$this->tempDir]);
399+
}
400+
401+
public function testCollectFilesLogsDebugWhenNoFilesFoundForParser(): void
402+
{
403+
// Create directory with files that don't match any parser extensions
404+
file_put_contents($this->tempDir.'/readme.txt', 'content');
405+
file_put_contents($this->tempDir.'/data.csv', 'content');
406+
407+
$logger = $this->createMock(LoggerInterface::class);
408+
$logger->expects($this->exactly(4)) // One for each parser class
409+
->method('debug')
410+
->with($this->stringContains('No files found for parser class'));
411+
412+
$detector = $this->createMock(DetectorInterface::class);
413+
$collector = new Collector($logger);
414+
415+
$result = $collector->collectFiles([$this->tempDir], $detector, null);
416+
417+
$this->assertEmpty($result);
418+
}
359419
}

tests/src/Validator/AbstractValidatorTest.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,4 +317,42 @@ public function testValidateCallsResetStateBeforeProcessing(): void
317317
$this->assertSame('some_file.xlf', $issues[0]->getFile());
318318
$this->assertSame(['validationIssue'], $issues[0]->getDetails());
319319
}
320+
321+
public function testValidateLogsDebugForUnsupportedParser(): void
322+
{
323+
$loggerMock = $this->createMock(LoggerInterface::class);
324+
$loggerMock->expects($this->atLeastOnce())
325+
->method('debug')
326+
->with($this->logicalOr(
327+
$this->stringContains('is not supported by the validator'),
328+
$this->stringContains('UnsupportedValidator')
329+
));
330+
331+
// Create a custom validator that doesn't support TestParser
332+
$validator = new class($loggerMock) extends AbstractValidator implements ValidatorInterface {
333+
public function processFile(ParserInterface $file): array
334+
{
335+
return [];
336+
}
337+
338+
public function supportsParser(): array
339+
{
340+
return []; // Empty - doesn't support any parser
341+
}
342+
343+
public function postProcess(): void
344+
{
345+
}
346+
347+
public function getShortName(): string
348+
{
349+
return 'UnsupportedValidator';
350+
}
351+
};
352+
353+
$files = ['/path/to/test.xlf'];
354+
$result = $validator->validate($files, TestParser::class);
355+
356+
$this->assertEmpty($result);
357+
}
320358
}

0 commit comments

Comments
 (0)