diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 12497dc4..c25b8626 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -9,14 +9,26 @@ on: jobs: tests: - name: Tests (PHP ${{ matrix.php-version }}, Composer ${{ matrix.composer-version }} & ${{ matrix.dependencies }} dependencies) - runs-on: ubuntu-latest + name: Tests (PHP ${{ matrix.php-version }}, Composer ${{ matrix.composer-version }} & ${{ matrix.dependencies }} dependencies on ${{ matrix.os }}) + runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: php-version: ["8.1", "8.2", "8.3"] composer-version: ["2.1", "2.2", "2.3", "2.4", "2.5", "2.6", "2.7"] dependencies: ["highest", "lowest"] + os: ["ubuntu-latest"] + include: + # Windows tests + - php-version: "8.3" + composer-version: "2.7" + dependencies: "highest" + os: "windows-latest" + # macOS tests + - php-version: "8.3" + composer-version: "2.7" + dependencies: "highest" + os: "macos-latest" steps: - uses: actions/checkout@v4 with: @@ -28,6 +40,7 @@ jobs: with: php-version: ${{ matrix.php-version }} tools: composer:v${{ matrix.composer-version }} + extensions: sockets coverage: none # Install dependencies @@ -36,7 +49,7 @@ jobs: with: dependency-versions: ${{ matrix.dependencies }} # Composer < 2.7 is not compatible with symfony/console 7.x - composer-options: ${{ matrix.composer-version != '2.7' && '--with symfony/console:<7' }} + composer-options: ${{ matrix.composer-version != '2.7' && '--with symfony/console:<7' || '' }} # Run tests - name: Run tests diff --git a/src/Builder/BuildInstructions.php b/src/Builder/BuildInstructions.php index 0bb85e88..108c665a 100644 --- a/src/Builder/BuildInstructions.php +++ b/src/Builder/BuildInstructions.php @@ -26,7 +26,6 @@ use ArrayObject; use CPSIT\ProjectBuilder\Helper; use CPSIT\ProjectBuilder\Paths; -use Symfony\Component\Filesystem; use function dirname; @@ -62,12 +61,12 @@ public function getTemplateDirectory(): string public function getSourceDirectory(): string { - return Filesystem\Path::join($this->getTemplateDirectory(), Paths::TEMPLATE_SOURCES); + return Helper\FilesystemHelper::path($this->getTemplateDirectory(), Paths::TEMPLATE_SOURCES); } public function getSharedSourceDirectory(): string { - return Filesystem\Path::join($this->getTemplateDirectory(), Paths::TEMPLATE_SHARED_SOURCES); + return Helper\FilesystemHelper::path($this->getTemplateDirectory(), Paths::TEMPLATE_SHARED_SOURCES); } public function getTemporaryDirectory(): string diff --git a/src/Builder/Config/ConfigFactory.php b/src/Builder/Config/ConfigFactory.php index 93883dad..be8233c9 100644 --- a/src/Builder/Config/ConfigFactory.php +++ b/src/Builder/Config/ConfigFactory.php @@ -99,8 +99,7 @@ public function buildFromString(string $content, string $identifier, FileType $f private function validateConfig(stdClass $parsedContent): JsonSchema\ValidationResult { - $schemaFile = Filesystem\Path::join(Helper\FilesystemHelper::getProjectRootPath(), Paths::PROJECT_SCHEMA_CONFIG); - $schemaReference = 'file://'.$schemaFile; + $schemaFile = Helper\FilesystemHelper::path(Helper\FilesystemHelper::getProjectRootPath(), Paths::PROJECT_SCHEMA_CONFIG); $schemaResolver = $this->validator->resolver(); // @codeCoverageIgnoreStart @@ -110,9 +109,9 @@ private function validateConfig(stdClass $parsedContent): JsonSchema\ValidationR } // @codeCoverageIgnoreEnd - $schemaResolver->registerFile($schemaReference, $schemaFile); + $schemaResolver->registerFile(Paths::PROJECT_SCHEMA_REFERENCE, $schemaFile); - return $this->validator->validate($parsedContent, $schemaReference); + return $this->validator->validate($parsedContent, Paths::PROJECT_SCHEMA_REFERENCE); } private function generateMapperSource(string $content, string $identifier, FileType $fileType): Mapper\Source\Source diff --git a/src/Builder/Config/ConfigReader.php b/src/Builder/Config/ConfigReader.php index e2a9374a..12c439eb 100644 --- a/src/Builder/Config/ConfigReader.php +++ b/src/Builder/Config/ConfigReader.php @@ -65,7 +65,7 @@ private function __construct( public static function create(?string $templateDirectory = null): self { - $templateDirectory ??= Filesystem\Path::join(Helper\FilesystemHelper::getProjectRootPath(), Paths::PROJECT_TEMPLATES); + $templateDirectory ??= Helper\FilesystemHelper::path(Helper\FilesystemHelper::getProjectRootPath(), Paths::PROJECT_TEMPLATES); return new self(ConfigFactory::create(), $templateDirectory); } diff --git a/src/Builder/Generator/Step/InstallComposerDependenciesStep.php b/src/Builder/Generator/Step/InstallComposerDependenciesStep.php index fd9e0621..ba4cef6d 100644 --- a/src/Builder/Generator/Step/InstallComposerDependenciesStep.php +++ b/src/Builder/Generator/Step/InstallComposerDependenciesStep.php @@ -25,10 +25,10 @@ use Composer\IO as ComposerIO; use CPSIT\ProjectBuilder\Builder; +use CPSIT\ProjectBuilder\Helper; use CPSIT\ProjectBuilder\IO; use CPSIT\ProjectBuilder\Resource; use Symfony\Component\Console; -use Symfony\Component\Filesystem; /** * InstallComposerDependenciesStep. @@ -49,7 +49,7 @@ public function __construct( public function run(Builder\BuildResult $buildResult): bool { - $composerJson = Filesystem\Path::join($buildResult->getInstructions()->getTemplateDirectory(), 'composer.json'); + $composerJson = Helper\FilesystemHelper::path($buildResult->getInstructions()->getTemplateDirectory(), 'composer.json'); $exitCode = $this->runComposerInstall($composerJson); $buildResult->applyStep($this); diff --git a/src/Builder/Generator/Step/ProcessSharedSourceFilesStep.php b/src/Builder/Generator/Step/ProcessSharedSourceFilesStep.php index d229be3e..0d415c77 100644 --- a/src/Builder/Generator/Step/ProcessSharedSourceFilesStep.php +++ b/src/Builder/Generator/Step/ProcessSharedSourceFilesStep.php @@ -24,6 +24,7 @@ namespace CPSIT\ProjectBuilder\Builder\Generator\Step; use CPSIT\ProjectBuilder\Builder; +use CPSIT\ProjectBuilder\Helper; use CPSIT\ProjectBuilder\IO; use CPSIT\ProjectBuilder\Paths; use CPSIT\ProjectBuilder\Resource; @@ -95,7 +96,7 @@ public static function supports(string $type): bool private function listSharedSourceFiles(Builder\BuildInstructions $instructions): Finder\Finder { - $basePath = Filesystem\Path::join( + $basePath = Helper\FilesystemHelper::path( $instructions->getSharedSourceDirectory(), // Include all installed shared source packages '*', diff --git a/src/Console/Application.php b/src/Console/Application.php index 39d8ce1a..0a5cc703 100644 --- a/src/Console/Application.php +++ b/src/Console/Application.php @@ -27,6 +27,7 @@ use CPSIT\ProjectBuilder\DependencyInjection; use CPSIT\ProjectBuilder\Error; use CPSIT\ProjectBuilder\Exception; +use CPSIT\ProjectBuilder\Helper; use CPSIT\ProjectBuilder\IO; use CPSIT\ProjectBuilder\Paths; use CPSIT\ProjectBuilder\Resource; @@ -127,8 +128,8 @@ public function run(bool $disableTemplateSourceCache = false): int private function mirrorSourceFiles(): void { $this->filesystem->mirror( - Filesystem\Path::join($this->targetDirectory, Paths::PROJECT_SOURCES), - Filesystem\Path::join($this->targetDirectory, '.build', Paths::PROJECT_SOURCES), + Helper\FilesystemHelper::path($this->targetDirectory, Paths::PROJECT_SOURCES), + Helper\FilesystemHelper::path($this->targetDirectory, '.build', Paths::PROJECT_SOURCES), ); } diff --git a/src/Console/Simulation.php b/src/Console/Simulation.php index f1f8a220..31b9c082 100644 --- a/src/Console/Simulation.php +++ b/src/Console/Simulation.php @@ -65,7 +65,7 @@ public static function create(): self new Resource\Local\Composer($filesystem), Factory::createOutput(), $rootPath, - Filesystem\Path::join($rootPath, '.build', uniqid('simulate_')), + Helper\FilesystemHelper::path($rootPath, '.build', uniqid('simulate_')), ); } @@ -88,7 +88,7 @@ public function prepare(): string // Install project $exitCode = $this->composer->install( - Filesystem\Path::join($this->targetDirectory, 'composer.json'), + Helper\FilesystemHelper::path($this->targetDirectory, 'composer.json'), true, $this->output, ); diff --git a/src/DependencyInjection/ContainerFactory.php b/src/DependencyInjection/ContainerFactory.php index fe918e51..ffdaa583 100644 --- a/src/DependencyInjection/ContainerFactory.php +++ b/src/DependencyInjection/ContainerFactory.php @@ -71,7 +71,7 @@ public static function create(array $resourcePaths = []): self public static function createFromConfig(Builder\Config\Config $config): self { $resourcePaths = [ - Filesystem\Path::join( + Helper\FilesystemHelper::path( Helper\FilesystemHelper::getProjectRootPath(), Paths::PROJECT_TEMPLATES, basename(dirname($config->getDeclaringFile())), @@ -85,22 +85,20 @@ public static function createFromConfig(Builder\Config\Config $config): self public static function createForTesting(string $testsRootPath = 'tests'): self { if (!Filesystem\Path::isAbsolute($testsRootPath)) { - $testsRootPath = Filesystem\Path::join( + $testsRootPath = Helper\FilesystemHelper::path( Helper\FilesystemHelper::getProjectRootPath(), $testsRootPath, ); } $resources = self::locateResources([ - Filesystem\Path::join( + Helper\FilesystemHelper::path( $testsRootPath, 'config', ), ]); - $containerPath = Filesystem\Path::join( + $containerPath = Helper\FilesystemHelper::path( Helper\FilesystemHelper::getProjectRootPath(), - 'var', - 'cache', - 'test-container.php', + 'var/cache/test-container.php', ); $filesystem = new Filesystem\Filesystem(); @@ -115,7 +113,7 @@ public function get(): DependencyInjection\ContainerInterface if ($this->debug && null !== $this->containerPath) { $containerXmlFilename = Filesystem\Path::getFilenameWithoutExtension($this->containerPath); - $containerXmlPath = Filesystem\Path::join(dirname($this->containerPath), $containerXmlFilename.'.xml'); + $containerXmlPath = Helper\FilesystemHelper::path(dirname($this->containerPath), $containerXmlFilename.'.xml'); $container->addCompilerPass(new CompilerPass\ContainerBuilderDebugDumpPass($containerXmlPath)); } @@ -185,6 +183,6 @@ private static function locateResources(array $resourcePaths = []): array private static function getDefaultResourcePath(): string { - return Filesystem\Path::join(Helper\FilesystemHelper::getProjectRootPath(), Paths::PROJECT_SERVICE_CONFIG); + return Helper\FilesystemHelper::path(Helper\FilesystemHelper::getProjectRootPath(), Paths::PROJECT_SERVICE_CONFIG); } } diff --git a/src/Helper/FilesystemHelper.php b/src/Helper/FilesystemHelper.php index c3faca52..79e058d1 100644 --- a/src/Helper/FilesystemHelper.php +++ b/src/Helper/FilesystemHelper.php @@ -28,7 +28,9 @@ use Symfony\Component\Finder; use function dirname; +use function explode; use function getenv; +use function implode; /** * FilesystemHelper. @@ -41,7 +43,7 @@ final class FilesystemHelper public static function createFileObject(string $baseDir, string $relativePathname): Finder\SplFileInfo { return new Finder\SplFileInfo( - Filesystem\Path::join($baseDir, $relativePathname), + self::path($baseDir, $relativePathname), dirname($relativePathname), $relativePathname, ); @@ -50,7 +52,7 @@ public static function createFileObject(string $baseDir, string $relativePathnam public static function getNewTemporaryDirectory(): string { do { - $dir = Filesystem\Path::join(sys_get_temp_dir(), uniqid('cpsit_project_builder_')); + $dir = self::path(sys_get_temp_dir(), uniqid('cpsit_project_builder_')); } while (is_dir($dir)); return $dir; @@ -63,9 +65,16 @@ public static function getProjectRootPath(): string } if (null !== $rootPath) { - $rootPath = Filesystem\Path::canonicalize($rootPath); + $rootPath = self::path($rootPath); } return $rootPath ?? dirname(__DIR__, 2); } + + public static function path(string ...$segments): string + { + $normalizedSegments = explode('/', Filesystem\Path::join(...$segments)); + + return implode(DIRECTORY_SEPARATOR, $normalizedSegments); + } } diff --git a/src/Paths.php b/src/Paths.php index e3bc3235..658c346b 100644 --- a/src/Paths.php +++ b/src/Paths.php @@ -48,6 +48,11 @@ enum Paths */ final public const PROJECT_SCHEMA_CONFIG = 'resources/config.schema.json'; + /** + * Internal reference to the JSON schema for template config files. + */ + final public const PROJECT_SCHEMA_REFERENCE = 'https://project-builder.cps-it.de/schema.json'; + /** * Path to service configurations. */ diff --git a/src/Resource/Local/Composer.php b/src/Resource/Local/Composer.php index 79790b7c..40f508fd 100644 --- a/src/Resource/Local/Composer.php +++ b/src/Resource/Local/Composer.php @@ -136,7 +136,7 @@ public static function createComposer(string $rootPath): \Composer\Composer return $factory->createComposer( new IO\NullIO(), - Filesystem\Path::join($rootPath, 'composer.json'), + Helper\FilesystemHelper::path($rootPath, 'composer.json'), ); } } diff --git a/src/Template/Provider/BaseProvider.php b/src/Template/Provider/BaseProvider.php index 57464917..0d27b211 100644 --- a/src/Template/Provider/BaseProvider.php +++ b/src/Template/Provider/BaseProvider.php @@ -66,7 +66,7 @@ public function __construct( $this->composer = new Resource\Local\Composer($this->filesystem); $this->renderer = new Environment( new Loader\FilesystemLoader([ - Filesystem\Path::join( + Helper\FilesystemHelper::path( Helper\FilesystemHelper::getProjectRootPath(), Paths::PROJECT_INSTALLER, ), @@ -272,7 +272,7 @@ protected function createComposerJson(array $templateSources, array $repositorie ]; $targetDirectory = Helper\FilesystemHelper::getNewTemporaryDirectory(); - $targetFile = Filesystem\Path::join($targetDirectory, 'composer.json'); + $targetFile = Helper\FilesystemHelper::path($targetDirectory, 'composer.json'); $composerJson = $this->renderer->render('composer.json.twig', [ 'templateSources' => $templateSources, 'rootDir' => Helper\FilesystemHelper::getProjectRootPath(), diff --git a/tests/bootstrap.php b/tests/bootstrap.php index c1d836af..5c71cecd 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -21,6 +21,14 @@ * along with this program. If not, see . */ +// Assure cross-platform compatible line break is used in tests +if (!defined('LF')) { + define('LF', match (PHP_OS) { + 'Windows' => "\r\n", + default => "\n", + }); +} + require_once dirname(__DIR__).'/.build/vendor/autoload.php'; $factory = CPSIT\ProjectBuilder\DependencyInjection\ContainerFactory::createForTesting(); diff --git a/tests/src/Builder/BuildInstructionsTest.php b/tests/src/Builder/BuildInstructionsTest.php index 35b8dc19..075b0020 100644 --- a/tests/src/Builder/BuildInstructionsTest.php +++ b/tests/src/Builder/BuildInstructionsTest.php @@ -63,13 +63,19 @@ public function getTemplateDirectoryReturnsTemplateDirectory(): void #[Framework\Attributes\Test] public function getSourceDirectoryReturnsSourceDirectory(): void { - self::assertSame(dirname(__DIR__).'/templates/src', $this->subject->getSourceDirectory()); + self::assertSame( + Src\Helper\FilesystemHelper::path(dirname(__DIR__), 'templates/src'), + $this->subject->getSourceDirectory(), + ); } #[Framework\Attributes\Test] public function getSharedSourceDirectoryReturnsSharedSourceDirectory(): void { - self::assertSame(dirname(__DIR__).'/templates/shared', $this->subject->getSharedSourceDirectory()); + self::assertSame( + Src\Helper\FilesystemHelper::path(dirname(__DIR__), 'templates/shared'), + $this->subject->getSharedSourceDirectory(), + ); } #[Framework\Attributes\Test] diff --git a/tests/src/Builder/Config/ConfigFactoryTest.php b/tests/src/Builder/Config/ConfigFactoryTest.php index 47e18c6a..1a1b5f42 100644 --- a/tests/src/Builder/Config/ConfigFactoryTest.php +++ b/tests/src/Builder/Config/ConfigFactoryTest.php @@ -136,7 +136,7 @@ public function buildFromFileReturnsHydratedConfigObject(): void ); foreach (['json', 'yaml'] as $fileType) { - $configFile = dirname(__DIR__, 2).'/Fixtures/Templates/'.$fileType.'-template/config.'.$fileType; + $configFile = Src\Helper\FilesystemHelper::path(dirname(__DIR__, 2), 'Fixtures/Templates/'.$fileType.'-template/config.'.$fileType); $expected = $createConfig($fileType); $expected->setDeclaringFile($configFile); @@ -159,10 +159,16 @@ public function buildFromStringThrowsExceptionIfGivenContentIsInvalid(): void */ public static function buildFromFileThrowsExceptionIfFileContentsAreInvalidDataProvider(): Generator { - $fixturePath = dirname(__DIR__, 2).'/Fixtures/Files'; - - yield 'invalid file' => [$fixturePath.'/invalid-config-file.yaml']; - yield 'invalid path at file condition' => [$fixturePath.'/invalid-config-file-condition-path.yaml']; - yield 'invalid target at file condition' => [$fixturePath.'/invalid-config-file-condition-target.yaml']; + $fixturePath = Src\Helper\FilesystemHelper::path(dirname(__DIR__, 2), 'Fixtures/Files'); + + yield 'invalid file' => [ + Src\Helper\FilesystemHelper::path($fixturePath, 'invalid-config-file.yaml'), + ]; + yield 'invalid path at file condition' => [ + Src\Helper\FilesystemHelper::path($fixturePath, 'invalid-config-file-condition-path.yaml'), + ]; + yield 'invalid target at file condition' => [ + Src\Helper\FilesystemHelper::path($fixturePath, 'invalid-config-file-condition-target.yaml'), + ]; } } diff --git a/tests/src/Builder/Config/ConfigReaderTest.php b/tests/src/Builder/Config/ConfigReaderTest.php index 17694f1c..b2da6da5 100644 --- a/tests/src/Builder/Config/ConfigReaderTest.php +++ b/tests/src/Builder/Config/ConfigReaderTest.php @@ -41,7 +41,7 @@ final class ConfigReaderTest extends Framework\TestCase protected function setUp(): void { $this->subject = Src\Builder\Config\ConfigReader::create( - dirname(__DIR__, 2).'/Fixtures/Templates', + Src\Helper\FilesystemHelper::path(dirname(__DIR__, 2), 'Fixtures/Templates'), ); } @@ -60,11 +60,13 @@ public function createCreatesTemplateDirectoryIfItDoesNotExist(): void #[Framework\Attributes\Test] public function readConfigThrowsExceptionIfTemplateHasNoComposerJson(): void { - $templateDirectory = dirname(__DIR__, 2).'/Fixtures'; + $templateDirectory = Src\Helper\FilesystemHelper::path(dirname(__DIR__, 2), 'Fixtures'); $subject = Src\Builder\Config\ConfigReader::create($templateDirectory); $this->expectExceptionObject( - Src\Exception\InvalidConfigurationException::forMissingManifestFile($templateDirectory.'/Files/config.json'), + Src\Exception\InvalidConfigurationException::forMissingManifestFile( + Src\Helper\FilesystemHelper::path($templateDirectory, 'Files/config.json'), + ), ); $subject->readConfig('foo'); @@ -84,7 +86,7 @@ public function readConfigThrowsExceptionIfTemplateWithGivenIdentifierDoesNotExi public function readConfigThrowsExceptionIfTemplateContainsMultipleConfigFiles(): void { $subject = Src\Builder\Config\ConfigReader::create( - dirname(__DIR__, 2).'/Fixtures/Files', + Src\Helper\FilesystemHelper::path(dirname(__DIR__, 2), 'Fixtures/Files'), ); $this->expectException(Src\Exception\InvalidConfigurationException::class); @@ -101,7 +103,7 @@ public function readConfigReturnsHydratedConfigObject(): void self::assertSame('cpsit/project-builder-template-yaml', $actual->getIdentifier()); self::assertSame( - dirname(__DIR__, 2).'/Fixtures/Templates/yaml-template/config.yaml', + Src\Helper\FilesystemHelper::path(dirname(__DIR__, 2), 'Fixtures/Templates/yaml-template/config.yaml'), $actual->getDeclaringFile(), ); } diff --git a/tests/src/Builder/Generator/GeneratorTest.php b/tests/src/Builder/Generator/GeneratorTest.php index 0162b353..32583661 100644 --- a/tests/src/Builder/Generator/GeneratorTest.php +++ b/tests/src/Builder/Generator/GeneratorTest.php @@ -77,8 +77,11 @@ public function runRunsThroughAllConfiguredSteps(): void self::assertStringContainsString('Running step #5 "mirrorProcessedFiles"...', $output); self::assertStringContainsString('Running step #6 "runCommand"...', $output); - self::assertFileExists($this->targetDirectory.'/dummy.yaml'); - self::assertStringEqualsFile($this->targetDirectory.'/dummy.yaml', 'name: "foo"'.PHP_EOL); + self::assertFileExists(Src\Helper\FilesystemHelper::path($this->targetDirectory, 'dummy.yaml')); + self::assertStringEqualsFile( + Src\Helper\FilesystemHelper::path($this->targetDirectory, 'dummy.yaml'), + 'name: "foo"'.LF, + ); self::assertCount(9, $this->eventListener->dispatchedEvents); self::assertInstanceOf(Src\Event\ProjectBuildStartedEvent::class, $this->eventListener->dispatchedEvents[0]); @@ -109,8 +112,11 @@ public function runRestartsProjectGenerationOnStepFailure(): void $output = self::$io->getOutput(); self::assertStringContainsString('If you want, you can restart project generation now.', $output); - self::assertFileExists($this->targetDirectory.'/dummy.yaml'); - self::assertStringEqualsFile($this->targetDirectory.'/dummy.yaml', 'name: "foo"'.PHP_EOL); + self::assertFileExists(Src\Helper\FilesystemHelper::path($this->targetDirectory, 'dummy.yaml')); + self::assertStringEqualsFile( + Src\Helper\FilesystemHelper::path($this->targetDirectory, 'dummy.yaml'), + 'name: "foo"'.LF, + ); self::assertCount(12, $this->eventListener->dispatchedEvents); self::assertInstanceOf(Src\Event\ProjectBuildStartedEvent::class, $this->eventListener->dispatchedEvents[0]); @@ -202,7 +208,7 @@ public function runDisplaysExceptionTraceOnVeryVerboseOutput(): void } self::assertStringContainsString( - 'Exception: The given input must not be empty.'.PHP_EOL.'#0', + 'Exception: The given input must not be empty.'.LF.'#0', self::$io->getOutput(), ); } @@ -236,7 +242,7 @@ protected static function createConfig(): Src\Builder\Config\Config $configReader = Src\Builder\Config\ConfigFactory::create(); $config = $configReader->buildFromFile( - dirname(__DIR__, 2).'/Fixtures/Templates/yaml-template/config.yaml', + Src\Helper\FilesystemHelper::path(dirname(__DIR__, 2), 'Fixtures/Templates/yaml-template/config.yaml'), 'yaml', ); $config->setTemplateSource( diff --git a/tests/src/Builder/Generator/Step/CleanUpStepTest.php b/tests/src/Builder/Generator/Step/CleanUpStepTest.php index ce19b0e2..f81ff4fa 100644 --- a/tests/src/Builder/Generator/Step/CleanUpStepTest.php +++ b/tests/src/Builder/Generator/Step/CleanUpStepTest.php @@ -58,16 +58,16 @@ public function runCleansUpRemainingFilesInTargetDirectory(): void { $targetDirectory = $this->result->getInstructions()->getTargetDirectory(); - $this->filesystem->mkdir($targetDirectory.'/.build'); - $this->filesystem->touch($targetDirectory.'/foo'); + $this->filesystem->mkdir(Src\Helper\FilesystemHelper::path($targetDirectory, '.build')); + $this->filesystem->touch(Src\Helper\FilesystemHelper::path($targetDirectory, 'foo')); - self::assertDirectoryExists($targetDirectory.'/.build'); - self::assertFileExists($targetDirectory.'/foo'); + self::assertDirectoryExists(Src\Helper\FilesystemHelper::path($targetDirectory, '.build')); + self::assertFileExists(Src\Helper\FilesystemHelper::path($targetDirectory, 'foo')); $this->subject->run($this->result); - self::assertDirectoryDoesNotExist($targetDirectory.'/.build'); - self::assertFileExists($targetDirectory.'/foo'); + self::assertDirectoryDoesNotExist(Src\Helper\FilesystemHelper::path($targetDirectory, '.build')); + self::assertFileExists(Src\Helper\FilesystemHelper::path($targetDirectory, 'foo')); self::assertTrue($this->result->isStepApplied('cleanUp')); } diff --git a/tests/src/Builder/Generator/Step/GenerateBuildArtifactStepTest.php b/tests/src/Builder/Generator/Step/GenerateBuildArtifactStepTest.php index 8edb41b8..20cfd141 100644 --- a/tests/src/Builder/Generator/Step/GenerateBuildArtifactStepTest.php +++ b/tests/src/Builder/Generator/Step/GenerateBuildArtifactStepTest.php @@ -49,7 +49,7 @@ protected function setUp(): void $this->buildResult = new Src\Builder\BuildResult( new Src\Builder\BuildInstructions(self::$config, 'foo'), ); - $this->artifactPath = Filesystem\Path::join( + $this->artifactPath = Src\Helper\FilesystemHelper::path( $this->buildResult->getWrittenDirectory(), '.build/build-artifact.json', ); diff --git a/tests/src/Builder/Generator/Step/InstallComposerDependenciesStepTest.php b/tests/src/Builder/Generator/Step/InstallComposerDependenciesStepTest.php index ccd50f7e..d1e2b2ba 100644 --- a/tests/src/Builder/Generator/Step/InstallComposerDependenciesStepTest.php +++ b/tests/src/Builder/Generator/Step/InstallComposerDependenciesStepTest.php @@ -67,8 +67,8 @@ public function runWritesComposerInstallOutputAndFailsOnFailure(): void self::$config->setDeclaringFile($newConfig->getDeclaringFile()); self::$filesystem->copy( - dirname(__DIR__, 3).'/Fixtures/Files/invalid-composer.json', - self::$temporaryDirectory.'/composer.json', + Src\Helper\FilesystemHelper::path(dirname(__DIR__, 3), 'Fixtures/Files/invalid-composer.json'), + Src\Helper\FilesystemHelper::path(self::$temporaryDirectory, 'composer.json'), true, ); @@ -81,7 +81,7 @@ public function runWritesComposerInstallOutputAndFailsOnFailure(): void protected static function createConfig(): Src\Builder\Config\Config { - $templateDirectory = dirname(__DIR__, 3).'/Fixtures/Templates/yaml-template'; + $templateDirectory = Src\Helper\FilesystemHelper::path(dirname(__DIR__, 3), 'Fixtures/Templates/yaml-template'); $finder = Finder\Finder::create() ->in($templateDirectory) ->notPath('vendor') @@ -94,7 +94,10 @@ protected static function createConfig(): Src\Builder\Config\Config $configFactory = Src\Builder\Config\ConfigFactory::create(); - return $configFactory->buildFromFile(self::$temporaryDirectory.'/config.yaml', 'yaml'); + return $configFactory->buildFromFile( + Src\Helper\FilesystemHelper::path(self::$temporaryDirectory, 'config.yaml'), + 'yaml', + ); } protected function tearDown(): void diff --git a/tests/src/Builder/Generator/Step/ProcessSharedSourceFilesStepTest.php b/tests/src/Builder/Generator/Step/ProcessSharedSourceFilesStepTest.php index 8dcc8cff..8895d8fa 100644 --- a/tests/src/Builder/Generator/Step/ProcessSharedSourceFilesStepTest.php +++ b/tests/src/Builder/Generator/Step/ProcessSharedSourceFilesStepTest.php @@ -56,17 +56,36 @@ public function runProcessesSourceFilesAndAppliesStep(): void $actual = $this->subject->run($this->result); + $temporaryDirectory = $this->result->getInstructions()->getTemporaryDirectory(); + self::assertTrue($actual); self::assertCount(4, $this->subject->getProcessedFiles()); - self::assertSame('overrides/shared-dummy-4.yaml', $this->subject->getProcessedFiles()[0]->getTargetFile()->getRelativePathname()); + self::assertSame( + 'overrides/shared-dummy-4.yaml', + $this->subject->getProcessedFiles()[0]->getTargetFile()->getRelativePathname(), + ); self::assertSame('shared-dummy.yaml', $this->subject->getProcessedFiles()[1]->getTargetFile()->getRelativePathname()); - self::assertFileExists($this->result->getInstructions()->getTemporaryDirectory().'/shared-dummy.yaml'); - self::assertFileDoesNotExist($this->result->getInstructions()->getTemporaryDirectory().'/shared-dummy-2.yaml'); - self::assertFileDoesNotExist($this->result->getInstructions()->getTemporaryDirectory().'/shared-dummy-3.yaml'); - self::assertFileDoesNotExist($this->result->getInstructions()->getTemporaryDirectory().'/shared-dummy-4.yaml'); - self::assertFileExists($this->result->getInstructions()->getTemporaryDirectory().'/overrides/shared-dummy-4.yaml'); - self::assertFileExists($this->result->getInstructions()->getTemporaryDirectory().'/foo-baz-shared-dummy/shared-dummy-1.yaml'); - self::assertFileExists($this->result->getInstructions()->getTemporaryDirectory().'/foo-baz-shared-dummy/shared-dummy-2.yaml'); + self::assertFileExists( + Src\Helper\FilesystemHelper::path($temporaryDirectory, 'shared-dummy.yaml'), + ); + self::assertFileDoesNotExist( + Src\Helper\FilesystemHelper::path($temporaryDirectory, 'shared-dummy-2.yaml'), + ); + self::assertFileDoesNotExist( + Src\Helper\FilesystemHelper::path($temporaryDirectory, 'shared-dummy-3.yaml'), + ); + self::assertFileDoesNotExist( + Src\Helper\FilesystemHelper::path($temporaryDirectory, 'shared-dummy-4.yaml'), + ); + self::assertFileExists( + Src\Helper\FilesystemHelper::path($temporaryDirectory, 'overrides/shared-dummy-4.yaml'), + ); + self::assertFileExists( + Src\Helper\FilesystemHelper::path($temporaryDirectory, 'foo-baz-shared-dummy/shared-dummy-1.yaml'), + ); + self::assertFileExists( + Src\Helper\FilesystemHelper::path($temporaryDirectory, 'foo-baz-shared-dummy/shared-dummy-2.yaml'), + ); self::assertTrue($this->result->isStepApplied($this->subject)); } @@ -75,11 +94,15 @@ public function revertRemovesProcessedFiles(): void { $this->subject->run($this->result); - self::assertFileExists($this->result->getInstructions()->getTemporaryDirectory().'/shared-dummy.yaml'); + self::assertFileExists( + Src\Helper\FilesystemHelper::path($this->result->getInstructions()->getTemporaryDirectory(), 'shared-dummy.yaml'), + ); $this->subject->revert($this->result); - self::assertFileDoesNotExist($this->result->getInstructions()->getTemporaryDirectory().'/shared-dummy.yaml'); + self::assertFileDoesNotExist( + Src\Helper\FilesystemHelper::path($this->result->getInstructions()->getTemporaryDirectory(), 'shared-dummy.yaml'), + ); } protected static function createConfig(): Src\Builder\Config\Config @@ -87,7 +110,7 @@ protected static function createConfig(): Src\Builder\Config\Config $configFactory = Src\Builder\Config\ConfigFactory::create(); return $configFactory->buildFromFile( - dirname(__DIR__, 3).'/Fixtures/Templates/yaml-template/config.yaml', + Src\Helper\FilesystemHelper::path(dirname(__DIR__, 3), 'Fixtures/Templates/yaml-template/config.yaml'), 'yaml', ); } diff --git a/tests/src/Builder/Generator/Step/ProcessSourceFilesStepTest.php b/tests/src/Builder/Generator/Step/ProcessSourceFilesStepTest.php index b4a543d0..e5e54ab6 100644 --- a/tests/src/Builder/Generator/Step/ProcessSourceFilesStepTest.php +++ b/tests/src/Builder/Generator/Step/ProcessSourceFilesStepTest.php @@ -59,17 +59,36 @@ public function runProcessesSourceFilesAndAppliesStep(): void $actual = $this->subject->run($this->result); + $temporaryDirectory = $this->result->getInstructions()->getTemporaryDirectory(); + self::assertTrue($actual); self::assertCount(4, $this->subject->getProcessedFiles()); - self::assertSame('overrides/dummy-4.yaml', $this->subject->getProcessedFiles()[0]->getTargetFile()->getRelativePathname()); + self::assertSame( + 'overrides/dummy-4.yaml', + $this->subject->getProcessedFiles()[0]->getTargetFile()->getRelativePathname(), + ); self::assertSame('dummy.yaml', $this->subject->getProcessedFiles()[1]->getTargetFile()->getRelativePathname()); - self::assertFileExists($this->result->getInstructions()->getTemporaryDirectory().'/dummy.yaml'); - self::assertFileDoesNotExist($this->result->getInstructions()->getTemporaryDirectory().'/dummy-2.yaml'); - self::assertFileDoesNotExist($this->result->getInstructions()->getTemporaryDirectory().'/dummy-3.yaml'); - self::assertFileDoesNotExist($this->result->getInstructions()->getTemporaryDirectory().'/dummy-4.yaml'); - self::assertFileExists($this->result->getInstructions()->getTemporaryDirectory().'/overrides/dummy-4.yaml'); - self::assertFileExists($this->result->getInstructions()->getTemporaryDirectory().'/foo-baz-dummy/dummy-1.yaml'); - self::assertFileExists($this->result->getInstructions()->getTemporaryDirectory().'/foo-baz-dummy/dummy-2.yaml'); + self::assertFileExists( + Src\Helper\FilesystemHelper::path($temporaryDirectory.'/dummy.yaml'), + ); + self::assertFileDoesNotExist( + Src\Helper\FilesystemHelper::path($temporaryDirectory.'/dummy-2.yaml'), + ); + self::assertFileDoesNotExist( + Src\Helper\FilesystemHelper::path($temporaryDirectory.'/dummy-3.yaml'), + ); + self::assertFileDoesNotExist( + Src\Helper\FilesystemHelper::path($temporaryDirectory.'/dummy-4.yaml'), + ); + self::assertFileExists( + Src\Helper\FilesystemHelper::path($temporaryDirectory.'/overrides/dummy-4.yaml'), + ); + self::assertFileExists( + Src\Helper\FilesystemHelper::path($temporaryDirectory.'/foo-baz-dummy/dummy-1.yaml'), + ); + self::assertFileExists( + Src\Helper\FilesystemHelper::path($temporaryDirectory.'/foo-baz-dummy/dummy-2.yaml'), + ); self::assertTrue($this->result->isStepApplied($this->subject)); } @@ -84,7 +103,7 @@ public function runCanProcessTheSameSourceFileWithMultipleConditions( string $expected, array $notExpected, ): void { - $declaringFile = dirname(__DIR__, 3).'/Fixtures/Templates/yaml-template/config.yaml'; + $declaringFile = Src\Helper\FilesystemHelper::path(dirname(__DIR__, 3), 'Fixtures/Templates/yaml-template/config.yaml'); $step = new Src\Builder\Config\ValueObject\Step( 'processSourceFiles', new Src\Builder\Config\ValueObject\StepOptions($fileConditions), @@ -100,10 +119,14 @@ public function runCanProcessTheSameSourceFileWithMultipleConditions( $this->subject->run($result); - self::assertFileExists($result->getInstructions()->getTemporaryDirectory().'/'.$expected); + self::assertFileExists( + Src\Helper\FilesystemHelper::path($result->getInstructions()->getTemporaryDirectory(), $expected), + ); foreach ($notExpected as $notExpectedFile) { - self::assertFileDoesNotExist($result->getInstructions()->getTemporaryDirectory().'/'.$notExpectedFile); + self::assertFileDoesNotExist( + Src\Helper\FilesystemHelper::path($result->getInstructions()->getTemporaryDirectory(), $notExpectedFile), + ); } } @@ -112,11 +135,15 @@ public function revertRemovesProcessedFiles(): void { $this->subject->run($this->result); - self::assertFileExists($this->result->getInstructions()->getTemporaryDirectory().'/dummy.yaml'); + self::assertFileExists( + Src\Helper\FilesystemHelper::path($this->result->getInstructions()->getTemporaryDirectory(), 'dummy.yaml'), + ); $this->subject->revert($this->result); - self::assertFileDoesNotExist($this->result->getInstructions()->getTemporaryDirectory().'/dummy.yaml'); + self::assertFileDoesNotExist( + Src\Helper\FilesystemHelper::path($this->result->getInstructions()->getTemporaryDirectory(), 'dummy.yaml'), + ); } /** @@ -167,7 +194,7 @@ protected static function createConfig(): Src\Builder\Config\Config $configFactory = Src\Builder\Config\ConfigFactory::create(); return $configFactory->buildFromFile( - dirname(__DIR__, 3).'/Fixtures/Templates/yaml-template/config.yaml', + Src\Helper\FilesystemHelper::path(dirname(__DIR__, 3), 'Fixtures/Templates/yaml-template/config.yaml'), 'yaml', ); } diff --git a/tests/src/Builder/Generator/Step/RunCommandStepTest.php b/tests/src/Builder/Generator/Step/RunCommandStepTest.php index d3cc3fca..84b378f7 100644 --- a/tests/src/Builder/Generator/Step/RunCommandStepTest.php +++ b/tests/src/Builder/Generator/Step/RunCommandStepTest.php @@ -121,9 +121,15 @@ public function runExecutesCommandAndAllowsExecutionFailures(): void $fileSystem->mkdir($workingDirectory); } + if (PHP_OS_FAMILY === 'Windows') { + $expected = 'is not recognized as an internal or external command'; + } else { + $expected = 'not found'; + } + self::assertTrue($this->subject->run($this->result)); self::assertFalse($this->subject->isStopped()); - self::assertStringContainsString('not found', self::$io->getOutput()); + self::assertStringContainsString($expected, self::$io->getOutput()); } #[Framework\Attributes\Test] diff --git a/tests/src/Builder/Generator/Step/ShowNextStepsStepTest.php b/tests/src/Builder/Generator/Step/ShowNextStepsStepTest.php index 6b0fbc27..6ed071a2 100644 --- a/tests/src/Builder/Generator/Step/ShowNextStepsStepTest.php +++ b/tests/src/Builder/Generator/Step/ShowNextStepsStepTest.php @@ -83,7 +83,7 @@ public function runThrowsExceptionIfTemplateFileCannotBeRendered(): void Src\Builder\Generator\Step\ShowNextStepsStep::getType(), new Src\Builder\Config\ValueObject\StepOptions( [], - dirname(__DIR__, 3).'/Fixtures/Files/invalid-template.twig', + Src\Helper\FilesystemHelper::path(dirname(__DIR__, 3), 'Fixtures/Files/invalid-template.twig'), ), ), ); @@ -103,7 +103,7 @@ public function runShowsNextStepsFromRenderedTemplateFileAndAppliesStep(): void Src\Builder\Generator\Step\ShowNextStepsStep::getType(), new Src\Builder\Config\ValueObject\StepOptions( [], - dirname(__DIR__, 3).'/Fixtures/Templates/yaml-template/templates/next-steps.html.twig', + Src\Helper\FilesystemHelper::path(dirname(__DIR__, 3), 'Fixtures/Templates/yaml-template/templates/next-steps.html.twig'), ), ), ); @@ -113,7 +113,7 @@ public function runShowsNextStepsFromRenderedTemplateFileAndAppliesStep(): void self::assertTrue($actual); self::assertStringContainsString('Next steps', $output); - self::assertStringContainsString('Hello'.PHP_EOL.'World', $output); + self::assertStringContainsString('Hello'.LF.'World', $output); self::assertTrue($this->result->isStepApplied($this->subject)); } } diff --git a/tests/src/Builder/Writer/GenericFileWriterTest.php b/tests/src/Builder/Writer/GenericFileWriterTest.php index 97135d65..b64ea60f 100644 --- a/tests/src/Builder/Writer/GenericFileWriterTest.php +++ b/tests/src/Builder/Writer/GenericFileWriterTest.php @@ -57,7 +57,7 @@ public function writeCopiesGivenFileToTemporaryDirectory(): void $sourceFile = __FILE__; $file = new Finder\SplFileInfo($sourceFile, dirname($sourceFile), basename($sourceFile)); - $expected = $instructions->getTemporaryDirectory().'/'.$file->getRelativePathname(); + $expected = Src\Helper\FilesystemHelper::path($instructions->getTemporaryDirectory(), $file->getRelativePathname()); $actual = $this->subject->write($instructions, $file); self::assertSame($expected, $actual->getPathname()); @@ -76,8 +76,8 @@ public function writeCopiesGivenFileToGivenTargetFile(): void $sourceFile = __FILE__; $file = new Finder\SplFileInfo($sourceFile, dirname($sourceFile), basename($sourceFile)); - $expected = $instructions->getTemporaryDirectory().'/overrides/foo.php'; - $actual = $this->subject->write($instructions, $file, 'overrides/foo.php'); + $expected = Src\Helper\FilesystemHelper::path($instructions->getTemporaryDirectory(), 'overrides/foo.php'); + $actual = $this->subject->write($instructions, $file, Src\Helper\FilesystemHelper::path('overrides/foo.php')); self::assertSame($expected, $actual->getPathname()); self::assertFileExists($expected); diff --git a/tests/src/Builder/Writer/TemplateWriterTest.php b/tests/src/Builder/Writer/TemplateWriterTest.php index f3c597ff..9bc97f27 100644 --- a/tests/src/Builder/Writer/TemplateWriterTest.php +++ b/tests/src/Builder/Writer/TemplateWriterTest.php @@ -57,10 +57,10 @@ public function writeWritesRenderedTemplateFileToTemporaryDirectory(): void $instructions->addTemplateVariable('foo', 'foo'); $instructions->addTemplateVariable('bar', 'foo'); - $templateFile = dirname(__DIR__, 3).'/templates/dump.json.twig'; + $templateFile = Src\Helper\FilesystemHelper::path(dirname(__DIR__, 3), 'templates/dump.json.twig'); $file = new Finder\SplFileInfo($templateFile, dirname($templateFile), basename($templateFile)); - $expected = $instructions->getTemporaryDirectory().'/dump.json'; + $expected = Src\Helper\FilesystemHelper::path($instructions->getTemporaryDirectory(), 'dump.json'); $actual = $this->subject->write($instructions, $file, variables: ['bar' => 'bar']); self::assertSame($expected, $actual->getPathname()); @@ -68,8 +68,8 @@ public function writeWritesRenderedTemplateFileToTemporaryDirectory(): void $expectedJson = [ 'instructions' => [ - 'sourceDirectory' => dirname(__DIR__, 2).'/templates/src', - 'sharedSourceDirectory' => dirname(__DIR__, 2).'/templates/shared', + 'sourceDirectory' => Src\Helper\FilesystemHelper::path(dirname(__DIR__, 2), 'templates/src'), + 'sharedSourceDirectory' => Src\Helper\FilesystemHelper::path(dirname(__DIR__, 2), 'templates/shared'), ], 'foo' => 'foo', 'bar' => 'bar', @@ -91,19 +91,24 @@ public function writeWritesRenderedTemplateFileToGivenTargetFile(): void $instructions->addTemplateVariable('foo', 'foo'); $instructions->addTemplateVariable('bar', 'foo'); - $templateFile = dirname(__DIR__, 3).'/templates/dump.json.twig'; + $templateFile = Src\Helper\FilesystemHelper::path(dirname(__DIR__, 3), 'templates/dump.json.twig'); $file = new Finder\SplFileInfo($templateFile, dirname($templateFile), basename($templateFile)); - $expected = $instructions->getTemporaryDirectory().'/overrides/dump.json'; - $actual = $this->subject->write($instructions, $file, 'overrides/dump.json.twig', ['bar' => 'bar']); + $expected = Src\Helper\FilesystemHelper::path($instructions->getTemporaryDirectory(), 'overrides/dump.json'); + $actual = $this->subject->write( + $instructions, + $file, + Src\Helper\FilesystemHelper::path('overrides/dump.json.twig'), + ['bar' => 'bar'], + ); self::assertSame($expected, $actual->getPathname()); self::assertFileExists($expected); $expectedJson = [ 'instructions' => [ - 'sourceDirectory' => dirname(__DIR__, 2).'/templates/src', - 'sharedSourceDirectory' => dirname(__DIR__, 2).'/templates/shared', + 'sourceDirectory' => Src\Helper\FilesystemHelper::path(dirname(__DIR__, 2), 'templates/src'), + 'sharedSourceDirectory' => Src\Helper\FilesystemHelper::path(dirname(__DIR__, 2), 'templates/shared'), ], 'foo' => 'foo', 'bar' => 'bar', diff --git a/tests/src/Console/ApplicationTest.php b/tests/src/Console/ApplicationTest.php index 467bfc06..d3f96323 100644 --- a/tests/src/Console/ApplicationTest.php +++ b/tests/src/Console/ApplicationTest.php @@ -54,7 +54,9 @@ protected function setUp(): void $this->messenger = self::$container->get('app.messenger'); $this->filesystem = self::$container->get(Filesystem\Filesystem::class); $this->templateProvider = new Tests\Fixtures\DummyProvider(); - $this->configReader = Src\Builder\Config\ConfigReader::create(dirname(__DIR__).'/Fixtures/Templates'); + $this->configReader = Src\Builder\Config\ConfigReader::create( + Src\Helper\FilesystemHelper::path(dirname(__DIR__), 'Fixtures/Templates'), + ); $this->subject = new Src\Console\Application( $this->messenger, $this->configReader, @@ -84,7 +86,7 @@ public function runThrowsExceptionIfInputIsNonInteractive(): void #[Framework\Attributes\Test] public function runMirrorsSourceFilesToTemporaryDirectory(): void { - $temporaryDirectory = $this->targetDirectory.'/.build/src'; + $temporaryDirectory = Src\Helper\FilesystemHelper::path($this->targetDirectory, '.build/src'); self::assertDirectoryDoesNotExist($temporaryDirectory); @@ -212,7 +214,7 @@ public function runUsesDefaultTemplateProvidersIfNoProvidersAreConfigured(): voi private function createTemplateSource(): Src\Template\TemplateSource { - $sourcePath = dirname(__DIR__).'/Fixtures/Templates/json-template'; + $sourcePath = Src\Helper\FilesystemHelper::path(dirname(__DIR__), 'Fixtures/Templates/json-template'); $package = Src\Resource\Local\Composer::createComposer($sourcePath)->getPackage(); self::assertInstanceOf(Package\Package::class, $package); diff --git a/tests/src/Fixtures/DummyProvider.php b/tests/src/Fixtures/DummyProvider.php index a8b60261..cbc2582e 100644 --- a/tests/src/Fixtures/DummyProvider.php +++ b/tests/src/Fixtures/DummyProvider.php @@ -24,6 +24,7 @@ namespace CPSIT\ProjectBuilder\Tests\Fixtures; use Composer\Json; +use CPSIT\ProjectBuilder\Helper\FilesystemHelper; use CPSIT\ProjectBuilder\Template; /** @@ -63,7 +64,9 @@ public function installTemplateSource(Template\TemplateSource $templateSource): } $package = $templateSource->getPackage(); - $jsonFile = new Json\JsonFile($this->installationPath.'/composer.json'); + $jsonFile = new Json\JsonFile( + FilesystemHelper::path($this->installationPath, 'composer.json'), + ); $json = [ 'require' => [ $package->getName() => '*', diff --git a/tests/src/Helper/FilesystemHelperTest.php b/tests/src/Helper/FilesystemHelperTest.php index 56f4facd..98651a1f 100644 --- a/tests/src/Helper/FilesystemHelperTest.php +++ b/tests/src/Helper/FilesystemHelperTest.php @@ -47,7 +47,7 @@ public function createFileObjectReturnsFileObjectForGivenFile(): void self::assertSame($relativePathname, $actual->getRelativePathname()); self::assertSame('.', $actual->getRelativePath()); - self::assertSame($baseDir.'/'.$relativePathname, $actual->getPathname()); + self::assertSame(Src\Helper\FilesystemHelper::path($baseDir, $relativePathname), $actual->getPathname()); } #[Framework\Attributes\Test] diff --git a/tests/src/IO/MessengerTest.php b/tests/src/IO/MessengerTest.php index eecaf08c..ce805428 100644 --- a/tests/src/IO/MessengerTest.php +++ b/tests/src/IO/MessengerTest.php @@ -111,7 +111,7 @@ public function confirmTemplateSourceRetryAsksForConfirmationAndReturnsResult(st self::assertSame($expected, $this->subject->confirmTemplateSourceRetry($exception)); self::assertStringContainsString( - implode(PHP_EOL, [ + implode(LF, [ 'Something went wrong.', 'You can go one step back and select another template provider.', 'For more information, take a look at the documentation.', @@ -129,7 +129,7 @@ public function confirmProjectGenerationAsksForConfirmationAndReturnsResult(): v self::assertTrue($this->subject->confirmProjectRegeneration()); self::assertStringContainsString( - implode(PHP_EOL, [ + implode(LF, [ 'If you want, you can restart project generation now.', 'Restart? [Y/n]', ]), @@ -146,7 +146,7 @@ public function confirmProjectGenerationAsksForRunCommandAndReturnsResult(): voi self::assertTrue($this->subject->confirmRunCommand($dummyCommand)); self::assertStringContainsString( - implode(PHP_EOL, [ + implode(LF, [ sprintf( 'Preparing to run "%s" in the project dir.', $dummyCommand, diff --git a/tests/src/Resource/Local/ComposerTest.php b/tests/src/Resource/Local/ComposerTest.php index 04ae8a1e..f256c426 100644 --- a/tests/src/Resource/Local/ComposerTest.php +++ b/tests/src/Resource/Local/ComposerTest.php @@ -46,7 +46,7 @@ final class ComposerTest extends Tests\ContainerAwareTestCase protected function setUp(): void { $this->subject = self::$container->get(Src\Resource\Local\Composer::class); - $this->composerJson = dirname(__DIR__, 2).'/Fixtures/Templates/yaml-template/composer.json'; + $this->composerJson = Src\Helper\FilesystemHelper::path(dirname(__DIR__, 2), 'Fixtures/Templates/yaml-template/composer.json'); } #[Framework\Attributes\Test] diff --git a/tests/src/Template/Provider/BaseProviderTest.php b/tests/src/Template/Provider/BaseProviderTest.php index d8d3e9d9..e3544c2d 100644 --- a/tests/src/Template/Provider/BaseProviderTest.php +++ b/tests/src/Template/Provider/BaseProviderTest.php @@ -355,7 +355,7 @@ private static function createPackageFromTemplateFixture( string $templateName = 'json-template', string $prettyVersion = '1.0.0', ): Package\Package { - $fixturePath = dirname(__DIR__, 2).'/Fixtures/Templates/'.$templateName; + $fixturePath = Src\Helper\FilesystemHelper::path(dirname(__DIR__, 2), 'Fixtures/Templates', $templateName); self::assertDirectoryExists($fixturePath); diff --git a/tests/src/Template/Provider/ComposerProviderTest.php b/tests/src/Template/Provider/ComposerProviderTest.php index aac06dfc..f09f9c47 100644 --- a/tests/src/Template/Provider/ComposerProviderTest.php +++ b/tests/src/Template/Provider/ComposerProviderTest.php @@ -96,7 +96,7 @@ public function listTemplateSourcesAddsAdditionalEmptyLineOnWrittenOutput(): voi $this->subject->listTemplateSources(); self::assertTrue($io->isOutputWritten()); - self::assertSame(PHP_EOL, self::$io->getOutput()); + self::assertSame(LF, self::$io->getOutput()); } #[Framework\Attributes\Test] diff --git a/tests/src/Template/Provider/VcsProviderTest.php b/tests/src/Template/Provider/VcsProviderTest.php index 6245b407..8f268bd5 100644 --- a/tests/src/Template/Provider/VcsProviderTest.php +++ b/tests/src/Template/Provider/VcsProviderTest.php @@ -111,7 +111,7 @@ public function listTemplateSourcesAddsAdditionalEmptyLineOnWrittenOutput(): voi $this->subject->listTemplateSources(); self::assertTrue($io->isOutputWritten()); - self::assertStringContainsString(PHP_EOL, self::$io->getOutput()); + self::assertStringContainsString(LF, self::$io->getOutput()); $this->filesystem->remove($repoA); } @@ -187,13 +187,21 @@ public function installTemplateSourceAsksForAdditionalRepositories(): void [$templateSource] = $this->subject->listTemplateSources(); - self::assertDirectoryDoesNotExist($this->temporaryRootPath.'/.build/templates/repo-a'); - self::assertDirectoryDoesNotExist($this->temporaryRootPath.'/.build/templates/repo-b'); + self::assertDirectoryDoesNotExist( + Src\Helper\FilesystemHelper::path($this->temporaryRootPath, '.build/templates/repo-a'), + ); + self::assertDirectoryDoesNotExist( + Src\Helper\FilesystemHelper::path($this->temporaryRootPath, '.build/templates/repo-b'), + ); $this->subject->installTemplateSource($templateSource); - self::assertDirectoryExists($this->temporaryRootPath.'/.build/templates/repo-a'); - self::assertDirectoryExists($this->temporaryRootPath.'/.build/templates/repo-b'); + self::assertDirectoryExists( + Src\Helper\FilesystemHelper::path($this->temporaryRootPath, '.build/templates/repo-a'), + ); + self::assertDirectoryExists( + Src\Helper\FilesystemHelper::path($this->temporaryRootPath, '.build/templates/repo-b'), + ); $output = self::$io->getOutput(); $repositories = $this->fetchConfiguredRepositoriesViaReflection(); @@ -274,25 +282,25 @@ private function initializeGitRepository(string $composerName, array $requiremen $runner = self::$container->get(Cli\Command\Runner::class); // Initialize repository - $initCommand = (new Cli\Command\Executable('git')) + $initCommand = $this->createGitExecutable() ->addArgument('init') ; self::assertTrue($runner->run($initCommand)->isSuccessful()); // Configure author - $configEmailCommand = (new Cli\Command\Executable('git')) + $configEmailCommand = $this->createGitExecutable() ->addArgument('config') ->addArgument('user.email') ->addArgument('noreply@example.com') ; self::assertTrue($runner->run($configEmailCommand)->isSuccessful()); - $configNameCommand = (new Cli\Command\Executable('git')) + $configNameCommand = $this->createGitExecutable() ->addArgument('config') ->addArgument('user.name') ->addArgument('Test bot') ; self::assertTrue($runner->run($configNameCommand)->isSuccessful()); - $configSignCommand = (new Cli\Command\Executable('git')) + $configSignCommand = $this->createGitExecutable() ->addArgument('config') ->addArgument('commit.gpgsign') ->addArgument('false') @@ -300,36 +308,39 @@ private function initializeGitRepository(string $composerName, array $requiremen self::assertTrue($runner->run($configSignCommand)->isSuccessful()); // Add composer.json - $this->filesystem->dumpFile($repoDir.'/composer.json', Json\JsonFile::encode([ - 'name' => $composerName, - 'type' => 'project-builder-template', - 'require' => $requirements, - 'extra' => $extra, - ])); + $this->filesystem->dumpFile( + Src\Helper\FilesystemHelper::path($repoDir, 'composer.json'), + Json\JsonFile::encode([ + 'name' => $composerName, + 'type' => 'project-builder-template', + 'require' => $requirements, + 'extra' => $extra, + ]), + ); // Create branch - $checkoutCommand = (new Cli\Command\Executable('git')) + $checkoutCommand = $this->createGitExecutable() ->addArgument('checkout') ->addOption('--orphan', 'main') ; self::assertTrue($runner->run($checkoutCommand)->isSuccessful()); // Add files - $addCommand = (new Cli\Command\Executable('git')) + $addCommand = $this->createGitExecutable() ->addArgument('add') ->addArgument('composer.json') ; self::assertTrue($runner->run($addCommand)->isSuccessful()); // Commit files - $commitCommand = (new Cli\Command\Executable('git')) + $commitCommand = $this->createGitExecutable() ->addArgument('commit') ->addOption('--message', 'Add composer.json') ; self::assertTrue($runner->run($commitCommand)->isSuccessful()); // Create tag - $tagCommand = (new Cli\Command\Executable('git')) + $tagCommand = $this->createGitExecutable() ->addArgument('tag') ->addArgument('1.0.0') ; @@ -354,6 +365,17 @@ private static function executeInDirectory(string $directory, callable $code): v chdir($currentWorkingDirectory); } + private function createGitExecutable(): Cli\Command\Executable + { + if (PHP_OS_FAMILY === 'Windows') { + $binary = 'git.exe'; + } else { + $binary = 'git'; + } + + return new Cli\Command\Executable($binary); + } + protected function tearDown(): void { parent::tearDown(); diff --git a/tests/src/Twig/RendererTest.php b/tests/src/Twig/RendererTest.php index f0dd4a99..0db98377 100644 --- a/tests/src/Twig/RendererTest.php +++ b/tests/src/Twig/RendererTest.php @@ -46,7 +46,7 @@ final class RendererTest extends Tests\ContainerAwareTestCase protected function setUp(): void { $this->subject = self::$container->get(Src\Twig\Renderer::class) - ->withRootPath(dirname(__DIR__, 2).'/templates') + ->withRootPath(Src\Helper\FilesystemHelper::path(dirname(__DIR__, 2), 'templates')) ; $this->instructions = new Src\Builder\BuildInstructions( self::$container->get('app.config'), @@ -108,8 +108,8 @@ public function renderMergesBuildInstructionsAndAdditionalVariables(): void $actual = $this->subject->render($this->instructions, 'dump.json.twig', ['bar' => 'bar']); $expected = [ 'instructions' => [ - 'sourceDirectory' => dirname(__DIR__).'/templates/src', - 'sharedSourceDirectory' => dirname(__DIR__).'/templates/shared', + 'sourceDirectory' => Src\Helper\FilesystemHelper::path(dirname(__DIR__), 'templates/src'), + 'sharedSourceDirectory' => Src\Helper\FilesystemHelper::path(dirname(__DIR__), 'templates/shared'), ], 'foo' => 'foo', 'bar' => 'bar',