diff --git a/src/PHPUnitGenerator/Generator/TestGenerator.php b/src/PHPUnitGenerator/Generator/TestGenerator.php index e46f69a..f7243a6 100644 --- a/src/PHPUnitGenerator/Generator/TestGenerator.php +++ b/src/PHPUnitGenerator/Generator/TestGenerator.php @@ -120,7 +120,7 @@ public function writeFile(string $inFile, string $outFile): int $this->fileSystem->write($outFile, $testCode); - Application::getPrinter()->info('"%s" tests generated', $inFile, $outFile); + Application::getPrinter()->info('"%s" tests generated', $inFile); return 1; } @@ -152,7 +152,7 @@ public function writeDir(string $inDir, string $outDir): int $count = 0; foreach ($files as $inFile) { $outFile = str_replace($inDir, $outDir, $inFile); - $outFile = preg_replace('/.php$/', 'Test.php', $outFile); + $outFile = preg_replace('/(.php|.phtml)$/', '', $outFile) . 'Test.php'; try { $this->writeFile($inFile, $outFile); diff --git a/test/PHPUnitGenerator/Generator/TestGeneratorTest.php b/test/PHPUnitGenerator/Generator/TestGeneratorTest.php index a4afefa..66eda82 100644 --- a/test/PHPUnitGenerator/Generator/TestGeneratorTest.php +++ b/test/PHPUnitGenerator/Generator/TestGeneratorTest.php @@ -3,9 +3,15 @@ namespace Test\PHPUnitGenerator\Generator; use PHPUnit\Framework\TestCase; +use PHPUnitGenerator\CLI\Application; +use PHPUnitGenerator\CLI\CLIInterface\PrinterInterface; use PHPUnitGenerator\Config\ConfigInterface\ConfigInterface; +use PHPUnitGenerator\Exception\FileExistsException; +use PHPUnitGenerator\Exception\InvalidCodeException; +use PHPUnitGenerator\Exception\InvalidRegexException; use PHPUnitGenerator\Exception\IsInterfaceException; use PHPUnitGenerator\FileSystem\FileSystemInterface\FileSystemInterface; +use PHPUnitGenerator\FileSystem\LocalFileSystem; use PHPUnitGenerator\Generator\TestGenerator; use PHPUnitGenerator\Model\ModelInterface\AnnotationModelInterface; use PHPUnitGenerator\Model\ModelInterface\ClassModelInterface; @@ -87,10 +93,13 @@ public function testConstruct() $documentationParser->setAccessible(true); $testRenderer = $reflection->getProperty('testRenderer'); $testRenderer->setAccessible(true); + $fileSystem = $reflection->getProperty('fileSystem'); + $fileSystem->setAccessible(true); $this->assertInstanceOf(CodeParser::class, $codeParser->getValue($instance)); $this->assertInstanceOf(DocumentationParser::class, $documentationParser->getValue($instance)); $this->assertInstanceOf(TwigTestRenderer::class, $testRenderer->getValue($instance)); + $this->assertInstanceOf(LocalFileSystem::class, $fileSystem->getValue($instance)); } /** @@ -137,8 +146,41 @@ public function testGenerate() */ public function testWriteFile() { - // @todo: Complete this test - $this->markTestIncomplete(); + $this->fileSystem->expects($this->exactly(2))->method('fileExists') + ->with(__FILE__)->willReturn(true); + $this->fileSystem->expects($this->once())->method('read') + ->with('in file')->willReturn('code'); + $this->fileSystem->expects($this->once())->method('mkDir') + ->with(__DIR__); + $this->fileSystem->expects($this->once())->method('write') + ->with(__FILE__, 'test code'); + $this->config->expects($this->exactly(2))->method('getOption') + ->with(ConfigInterface::OPTION_OVERWRITE)->willReturnOnConsecutiveCalls(true, false); + + $printer = $this->createMock(PrinterInterface::class); + $printer->expects($this->once())->method('info') + ->with('"%s" tests generated', 'in file'); + + $printerProperty = (new \ReflectionClass(Application::class))->getProperty('printer'); + $printerProperty->setAccessible(true); + $printerProperty->setValue($printer); + + $mock = $this->getMockBuilder(TestGenerator::class) + ->setConstructorArgs([$this->config]) + ->setMethods(['generate']) + ->getMock(); + $mock->expects($this->once())->method('generate') + ->with('code')->willReturn('test code'); + + $mock->setCodeParser($this->codeParser); + $mock->setDocumentationParser($this->documentationParser); + $mock->setTestRenderer($this->testRenderer); + $mock->setFileSystem($this->fileSystem); + + $this->assertEquals(1, $mock->writeFile('in file', __FILE__)); + + $this->expectException(FileExistsException::class); + $mock->writeFile('in file', __FILE__); } /** @@ -146,8 +188,71 @@ public function testWriteFile() */ public function testWriteDir() { - // @todo: Complete this test - $this->markTestIncomplete(); + $mock = $this->getMockBuilder(TestGenerator::class) + ->setConstructorArgs([$this->config]) + ->setMethods(['checkRegexValidity', 'writeFile']) + ->getMock(); + + $mock->setCodeParser($this->codeParser); + $mock->setDocumentationParser($this->documentationParser); + $mock->setTestRenderer($this->testRenderer); + $mock->setFileSystem($this->fileSystem); + + $mock->expects($this->exactly(4))->method('writeFile') + ->withConsecutive( + ['/in dir/file1.php', '/out dir/file1Test.php'], + ['/in dir/dir/file2.phtml', '/out dir/dir/file2Test.php'] + )->willReturnOnConsecutiveCalls( + 1, + 1, + $this->throwException(new IsInterfaceException('error')), + $this->throwException(new InvalidCodeException()) + ); + $mock->expects($this->exactly(4))->method('checkRegexValidity') + ->withConsecutive([ConfigInterface::OPTION_INCLUDE], [ConfigInterface::OPTION_EXCLUDE]); + + $this->fileSystem->expects($this->exactly(2))->method('mkDir') + ->with('/out dir/'); + $this->fileSystem->expects($this->exactly(2))->method('filterFiles') + ->with( + ['/in dir/file1.php', '/in dir/dir/file2.phtml'], + 'include regex', + 'exclude regex' + )->willReturn(['/in dir/file1.php', '/in dir/dir/file2.phtml']); + $this->fileSystem->expects($this->exactly(2))->method('getFiles') + ->withConsecutive(['/in dir/'], ['/in dir']) + ->willReturn(['/in dir/file1.php', '/in dir/dir/file2.phtml']); + + $this->config->expects($this->exactly(6))->method('getOption') + ->withConsecutive( + [ConfigInterface::OPTION_INCLUDE], + [ConfigInterface::OPTION_EXCLUDE], + [ConfigInterface::OPTION_INCLUDE], + [ConfigInterface::OPTION_EXCLUDE], + [ConfigInterface::OPTION_IGNORE], + [ConfigInterface::OPTION_IGNORE] + ) + ->willReturnOnConsecutiveCalls( + 'include regex', + 'exclude regex', + 'include regex', + 'exclude regex', + true, + false + ); + + $this->assertEquals(2, $mock->writeDir('/in dir/', '/out dir')); + + $printer = $this->createMock(PrinterInterface::class); + $printer->expects($this->once())->method('warning') + ->with("An error occurred during tests creation (for \"%s\"):\n\n\t%s", '/in dir/file1.php', 'error'); + + $printerProperty = (new \ReflectionClass(Application::class))->getProperty('printer'); + $printerProperty->setAccessible(true); + $printerProperty->setValue($printer); + + $this->expectException(InvalidCodeException::class); + $mock->writeDir('/in dir', '/out dir/'); } /** @@ -194,4 +299,38 @@ public function testSetTestRenderer() $this->assertEquals($expected, $property->getValue($this->instance)); } + + /** + * @covers \PHPUnitGenerator\Generator\TestGenerator::setFileSystem() + */ + public function testSetFileSystem() + { + $expected = $this->createMock(\PHPUnitGenerator\FileSystem\FileSystemInterface\FileSystemInterface::class); + + $property = (new \ReflectionClass(TestGenerator::class))->getProperty('fileSystem'); + $property->setAccessible(true); + + $this->instance->setFileSystem($expected); + + $this->assertEquals($expected, $property->getValue($this->instance)); + } + + /** + * @covers \PHPUnitGenerator\Generator\TestGenerator::checkRegexValidity() + */ + public function testCheckRegexValidity() + { + $method = (new \ReflectionClass(TestGenerator::class))->getMethod('checkRegexValidity'); + $method->setAccessible(true); + + $this->config->expects($this->exactly(5))->method('getOption') + ->with(ConfigInterface::OPTION_INCLUDE) + ->willReturnOnConsecutiveCalls(null, '/.*.php/', '/.*.php/', 'invalid', 'invalid'); + + $method->invoke($this->instance, ConfigInterface::OPTION_INCLUDE); + $method->invoke($this->instance, ConfigInterface::OPTION_INCLUDE); + + $this->expectException(InvalidRegexException::class); + $method->invoke($this->instance, ConfigInterface::OPTION_INCLUDE); + } }