diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..dd84ea7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,38 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - Version [e.g. 22] + +**Smartphone (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..23a2aec --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: enhancement, request +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml new file mode 100644 index 0000000..6e823f0 --- /dev/null +++ b/.github/workflows/unit-tests.yml @@ -0,0 +1,39 @@ +name: Unit Tests + +on: [push, pull_request] + +jobs: + run: + runs-on: ubuntu-latest + strategy: + max-parallel: 10 + matrix: + laravel-version: ['^7.0', '^8.0'] + preference: ['stable'] + php-versions: ['7.4'] + name: Laravel ${{ matrix.laravel-version }} (${{ matrix.preference }}) on PHP ${{ matrix.php-versions }} + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + extensions: mbstring, xdebug + coverage: xdebug + - name: Install dependencies + run: | + composer require --no-update --no-interaction "illuminate/support:${{ matrix.laravel-version }}" + composer update --prefer-${{ matrix.preference }} --no-interaction --prefer-dist --no-suggest --no-scripts --optimize-autoloader + - name: Lint composer.json + run: composer validate + - name: Run Tests + run: composer test:ci + - name: Upload Coverage + uses: codecov/codecov-action@v1 + with: + token: ${{ secrets.CODECOV_TOKEN }} #required + file: ./coverage.xml #optional + flags: unittests #optional + name: codecov-umbrella #optional + fail_ci_if_error: true #optional (default = false) diff --git a/.php_cs b/.php_cs deleted file mode 100644 index 50488be..0000000 --- a/.php_cs +++ /dev/null @@ -1,100 +0,0 @@ - -EOF; - -$finder = PhpCsFixer\Finder::create() - ->exclude([ - 'build', - 'public', - 'resources', - ]) - ->in(__DIR__); - -$config = PhpCsFixer\Config::create() - ->setRiskyAllowed(true) - ->setRules([ - '@PHP56Migration' => true, - '@PHPUnit60Migration:risky' => true, - '@Symfony' => true, - '@Symfony:risky' => false, - 'align_multiline_comment' => true, - 'array_indentation' => true, - 'array_syntax' => ['syntax' => 'short'], - 'blank_line_before_statement' => true, - 'binary_operator_spaces' => ['default' => 'single_space'], - 'combine_consecutive_issets' => true, - 'combine_consecutive_unsets' => true, - 'comment_to_phpdoc' => true, - 'compact_nullable_typehint' => true, - 'cast_spaces' => ['space' => 'none'], - 'concat_space' => ['spacing' => 'one'], - 'escape_implicit_backslashes' => true, - 'explicit_indirect_variable' => true, - 'explicit_string_variable' => true, - 'final_internal_class' => true, - 'fully_qualified_strict_types' => true, - 'function_to_constant' => ['functions' => ['get_class', 'get_called_class', 'php_sapi_name', 'phpversion', 'pi']], - // 'header_comment' => ['header' => $header], - 'heredoc_to_nowdoc' => true, - 'list_syntax' => ['syntax' => 'long'], - 'logical_operators' => true, - 'method_argument_space' => ['on_multiline' => 'ensure_fully_multiline'], - 'method_chaining_indentation' => true, - 'multiline_comment_opening_closing' => true, - 'no_alternative_syntax' => true, - 'no_binary_string' => true, - 'no_extra_blank_lines' => ['tokens' => ['break', 'continue', 'extra', 'return', 'throw', 'use', 'parenthesis_brace_block', 'square_brace_block', 'curly_brace_block']], - 'no_null_property_initialization' => true, - 'no_short_echo_tag' => true, - 'no_superfluous_elseif' => true, - 'no_unneeded_curly_braces' => true, - 'no_unneeded_final_method' => true, - 'no_unreachable_default_argument_value' => true, - 'no_unset_on_property' => true, - 'no_useless_else' => true, - 'no_useless_return' => true, - 'ordered_class_elements' => true, - 'ordered_imports' => true, - 'php_unit_internal_class' => true, - 'php_unit_method_casing' => true, - 'php_unit_ordered_covers' => true, - 'php_unit_set_up_tear_down_visibility' => true, - 'php_unit_strict' => true, - 'php_unit_test_annotation' => true, - 'php_unit_test_case_static_method_calls' => ['call_type' => 'this'], - 'php_unit_test_class_requires_covers' => true, - 'phpdoc_add_missing_param_annotation' => true, - 'phpdoc_order' => true, - 'phpdoc_trim_consecutive_blank_line_separation' => true, - 'phpdoc_types_order' => true, - 'return_assignment' => true, - 'semicolon_after_instruction' => true, - 'single_line_comment_style' => true, - 'strict_comparison' => true, - 'strict_param' => true, - 'string_line_ending' => true, - 'yoda_style' => false, - ]) - ->setFinder($finder); - -// special handling of fabbot.io service if it's using too old PHP CS Fixer version -if (false !== getenv('FABBOT_IO')) { - try { - PhpCsFixer\FixerFactory::create() - ->registerBuiltInFixers() - ->registerCustomFixers($config->getCustomFixers()) - ->useRuleSet(new PhpCsFixer\RuleSet($config->getRules())); - } catch (PhpCsFixer\ConfigurationException\InvalidConfigurationException $e) { - $config->setRules([]); - } catch (UnexpectedValueException $e) { - $config->setRules([]); - } catch (InvalidArgumentException $e) { - $config->setRules([]); - } -} - -return $config; diff --git a/.styleci.yml b/.styleci.yml deleted file mode 100644 index ea9f280..0000000 --- a/.styleci.yml +++ /dev/null @@ -1,5 +0,0 @@ -preset: psr2 - -enabled: - - align_comments - - alpha_ordered_imports diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 765f427..0000000 --- a/.travis.yml +++ /dev/null @@ -1,31 +0,0 @@ -language: php - -php: - - 7.4 - -env: - - LARAVEL='^6.0' COMPOSER_FLAGS='--prefer-stable' - - LARAVEL='6.x-dev' - - LARAVEL='^7.0' COMPOSER_FLAGS='--prefer-stable' - - LARAVEL='dev-master' - -matrix: - fast_finish: true - allow_failures: - - env: LARAVEL='dev-master' - -cache: - directories: - - $HOME/.composer/cache - -before_install: - - travis_retry composer self-update - - travis_retry composer require --no-update --no-interaction "illuminate/support:${LARAVEL}" - -install: - - travis_retry composer update ${COMPOSER_FLAGS} --no-interaction --prefer-dist --no-suggest - -script: ./vendor/bin/phpunit --verbose --coverage-clover=coverage.xml - -after_success: - - bash <(curl -s https://codecov.io/bash) diff --git a/composer.json b/composer.json index 6a9378e..1ed9283 100644 --- a/composer.json +++ b/composer.json @@ -20,7 +20,7 @@ "require": { "php": "^7.4", "ext-json": "*", - "illuminate/support": "6 - 7", + "illuminate/support": "7 - 8", "league/commonmark": "^1.1", "league/commonmark-extras": "^1.1", "monolog/monolog": "1.24 - 2", @@ -31,11 +31,11 @@ "symfony/yaml": "^4.3" }, "require-dev": { - "phpunit/phpunit": "^8.5", - "orchestra/testbench-browser-kit": "4 - 5", - "goaop/framework": "^3.0@rc", - "codeception/aspect-mock": "^3.1", - "phpro/grumphp": "^0.18.0" + "orchestra/testbench-browser-kit": "4 - 6", + "phpunit/phpunit": "^9.3", + "phpro/grumphp": "^0.19.1", + "phpspec/prophecy-phpunit": "^2.0", + "symplify/easy-coding-standard": "^8.2" }, "autoload": { "psr-4": { diff --git a/ecs.php b/ecs.php new file mode 100644 index 0000000..1a08a91 --- /dev/null +++ b/ecs.php @@ -0,0 +1,15 @@ +parameters(); + + $parameters->set('line_ending', "\n"); + + $parameters->set('paths', [__DIR__ . '/src', __DIR__ . '/tests']); + + $parameters->set('sets', ['clean-code', 'psr12']); +}; diff --git a/grumphp.yml b/grumphp.yml index 3f86fa1..a64a9e8 100644 --- a/grumphp.yml +++ b/grumphp.yml @@ -1,17 +1,14 @@ -parameters: +grumphp: tasks: - phpcsfixer2: - allow_risky: ~ - cache_file: ~ + ecs: config: ~ - rules: [] - using_cache: ~ - config_contains_finder: true - verbose: true - diff: false - triggered_by: ['php'] + level: ~ + whitelist_patterns: [ ] + triggered_by: [ 'php' ] + clear-cache: false + no-progress-bar: true phpunit: config_file: ~ testsuite: Unit - group: [] + group: [ ] always_execute: false diff --git a/src/Contract/FileHelper.php b/src/Contract/FileHelper.php new file mode 100644 index 0000000..778a073 --- /dev/null +++ b/src/Contract/FileHelper.php @@ -0,0 +1,26 @@ +filesystem = $filesystem; $this->configProvider = $configProvider; + $this->fileHelper = $fileHelper; + $this->yamlHelper = $yamlHelper; } /** @@ -41,7 +44,14 @@ public function create(string $directory): Product throw InvalidDirectory::forDirectory($directory); } - $product = new Product($this->filesystem, $this->configProvider, $directory); + $product = new Product( + $this->filesystem, + $this->configProvider, + $this->fileHelper, + $this->yamlHelper, + $directory + ); + $product->populate(); return $product; diff --git a/src/Helper/FileHelper.php b/src/Helper/FileHelper.php new file mode 100644 index 0000000..d7eb073 --- /dev/null +++ b/src/Helper/FileHelper.php @@ -0,0 +1,24 @@ +filesystem = $filesystem; $this->configProvider = $configProvider; + $this->fileHelper = $fileHelper; + $this->yamlHelper = $yamlHelper; $this->name = Str::title(basename($directory)); $this->key = strtolower($this->name); $this->directory = $directory; @@ -256,6 +238,8 @@ public function toArray(): array * Convert the object to its JSON representation. * * @param int $options + * + * @throws JsonException */ public function toJson($options = 0): string { @@ -290,21 +274,21 @@ private function getAssetUrl(string $url, string $version): string /** * Load meta onto product. * - * @param string $version Version to load configuration from. (optional) + * @param string|null $version Version to load configuration from. (optional) * * @throws Exception if meta file could not be parsed */ - private function loadMeta(string $version = null): void + private function loadMeta(?string $version = null): void { $version = empty($version) ? $this->getDefaultVersion() : $version; - $metaFile = realpath(sprintf('%s/%s/%s', $this->directory, $version, self::META_FILE)); + $metaFile = $this->fileHelper->realPath(sprintf('%s/%s/%s', $this->directory, $version, self::META_FILE)); if (empty($metaFile)) { return; } try { - $meta = Yaml::parse(file_get_contents($metaFile)); + $meta = $this->yamlHelper->parse($this->fileHelper->getFileContents($metaFile)); if (!empty($meta['name'])) { $this->name = $meta['name']; @@ -314,8 +298,7 @@ private function loadMeta(string $version = null): void } $this->imageUrl = $this->getAssetUrl($meta['image_url'] ?? '', $version); - $this->meta = $meta; - } catch (ParseException $exception) { + } catch (RuntimeException $exception) { $message = sprintf( 'Failed to parse meta file `%s`. %s', $metaFile, diff --git a/src/Service/Documentation/Provider.php b/src/Service/Documentation/Provider.php index 7474c18..71400e1 100644 --- a/src/Service/Documentation/Provider.php +++ b/src/Service/Documentation/Provider.php @@ -114,7 +114,7 @@ public function sectionExists(Product $product, string $version, string $page): private function getFilePathForProductPage(Product $product, string $version, string $page): string { $directory = $product->getDirectory(); - $filename = ($page === self::PAGE_INDEX) ? $this->configProvider->getContentIndexPageName() : $page; + $filename = $page === self::PAGE_INDEX ? $this->configProvider->getContentIndexPageName() : $page; return sprintf('%s/%s/%s.%s', $directory, $version, $filename, self::FILE_EXTENSION); } diff --git a/src/Service/GitCommandRunner.php b/src/Service/GitCommandRunner.php index d6335f8..21c6bde 100644 --- a/src/Service/GitCommandRunner.php +++ b/src/Service/GitCommandRunner.php @@ -4,19 +4,26 @@ namespace ReliqArts\Docweaver\Service; -use ReliqArts\Docweaver\Contract\VCSCommandRunner; +use ReliqArts\Docweaver\Contract\ProcessHelper; +use ReliqArts\Docweaver\Contract\VcsCommandRunner; use Symfony\Component\Process\Exception\ProcessFailedException; -use Symfony\Component\Process\Process; -final class GitCommandRunner implements VCSCommandRunner +final class GitCommandRunner implements VcsCommandRunner { private const DEFAULT_REMOTE_NAME = 'origin'; + private ProcessHelper $processHelper; + + public function __construct(ProcessHelper $processHelper) + { + $this->processHelper = $processHelper; + } + public function clone(string $source, string $branch, string $workingDirectory): void { - $command = ['git', 'clone', '--branch', $branch, sprintf('%s', $source), $branch]; + $command = ['git', 'clone', '--branch', $branch, $source, $branch]; - $clone = new Process($command, $workingDirectory); + $clone = $this->processHelper->createProcess($command, $workingDirectory); $clone->mustRun(); } @@ -27,7 +34,7 @@ public function listTags(string $workingDirectory): array { $this->fetch($workingDirectory); - $listTags = new Process(['git', 'tag', '-l'], $workingDirectory); + $listTags = $this->processHelper->createProcess(['git', 'tag', '-l'], $workingDirectory); $listTags->mustRun(); if ($splitTags = preg_split("/[\n\r]/", $listTags->getOutput())) { @@ -42,7 +49,7 @@ public function listTags(string $workingDirectory): array */ public function pull(string $workingDirectory): void { - $pull = new Process(['git', 'pull'], $workingDirectory); + $pull = $this->processHelper->createProcess(['git', 'pull'], $workingDirectory); $pull->mustRun(); } @@ -54,7 +61,7 @@ public function getRemoteUrl(string $workingDirectory, ?string $remoteName = nul $remoteName ??= self::DEFAULT_REMOTE_NAME; $command = ['git', 'config', '--get', sprintf('remote.%s.url', $remoteName)]; - $getUrl = new Process($command, $workingDirectory); + $getUrl = $this->processHelper->createProcess($command, $workingDirectory); $getUrl->mustRun(); return trim($getUrl->getOutput()); @@ -62,7 +69,7 @@ public function getRemoteUrl(string $workingDirectory, ?string $remoteName = nul private function fetch(string $workingDirectory): void { - $pull = new Process(['git', 'fetch'], $workingDirectory); + $pull = $this->processHelper->createProcess(['git', 'fetch'], $workingDirectory); $pull->mustRun(); } } diff --git a/src/Service/Product/Publisher.php b/src/Service/Product/Publisher.php index 0d4bddd..6baf7fd 100644 --- a/src/Service/Product/Publisher.php +++ b/src/Service/Product/Publisher.php @@ -8,7 +8,7 @@ use ReliqArts\Docweaver\Contract\Filesystem; use ReliqArts\Docweaver\Contract\Logger; use ReliqArts\Docweaver\Contract\Product\Publisher as PublisherContract; -use ReliqArts\Docweaver\Contract\VCSCommandRunner; +use ReliqArts\Docweaver\Contract\VcsCommandRunner; use ReliqArts\Docweaver\Exception\Product\InvalidAssetDirectory; use ReliqArts\Docweaver\Exception\Product\PublicationFailed; use ReliqArts\Docweaver\Model\Product; @@ -22,14 +22,14 @@ final class Publisher extends BasePublisher implements PublisherContract { /** - * @var VCSCommandRunner + * @var VcsCommandRunner */ - private VCSCommandRunner $vcsCommandRunner; + private VcsCommandRunner $vcsCommandRunner; /** * Publisher constructor. */ - public function __construct(Filesystem $filesystem, Logger $logger, VCSCommandRunner $vcsCommandRunner) + public function __construct(Filesystem $filesystem, Logger $logger, VcsCommandRunner $vcsCommandRunner) { parent::__construct($filesystem, $logger); diff --git a/src/ServiceProvider.php b/src/ServiceProvider.php index 483b569..7b3eadc 100644 --- a/src/ServiceProvider.php +++ b/src/ServiceProvider.php @@ -19,14 +19,20 @@ use ReliqArts\Docweaver\Contract\ConfigProvider as ConfigProviderContract; use ReliqArts\Docweaver\Contract\Documentation\Provider as DocumentationProviderContract; use ReliqArts\Docweaver\Contract\Documentation\Publisher as DocumentationPublisherContract; +use ReliqArts\Docweaver\Contract\FileHelper as FileHelperContract; use ReliqArts\Docweaver\Contract\Filesystem as FilesystemContract; use ReliqArts\Docweaver\Contract\Logger as LoggerContract; use ReliqArts\Docweaver\Contract\MarkdownParser as MarkdownParserContract; +use ReliqArts\Docweaver\Contract\ProcessHelper as ProcessHelperContract; use ReliqArts\Docweaver\Contract\Product\Finder as ProductFinderContract; use ReliqArts\Docweaver\Contract\Product\Maker as ProductMakerContract; use ReliqArts\Docweaver\Contract\Product\Publisher as ProductPublisherContract; -use ReliqArts\Docweaver\Contract\VCSCommandRunner; +use ReliqArts\Docweaver\Contract\VcsCommandRunner; +use ReliqArts\Docweaver\Contract\YamlHelper as YamlHelperContract; use ReliqArts\Docweaver\Factory\ProductMaker; +use ReliqArts\Docweaver\Helper\FileHelper; +use ReliqArts\Docweaver\Helper\ProcessHelper; +use ReliqArts\Docweaver\Helper\YamlHelper; use ReliqArts\Docweaver\Model\Product; use ReliqArts\Docweaver\Service\ConfigProvider; use ReliqArts\Docweaver\Service\Documentation\Provider as DocumentationProvider; @@ -169,10 +175,13 @@ private function registerBindings(): self $this->app->singleton(FilesystemContract::class, Filesystem::class); $this->app->singleton(DocumentationPublisherContract::class, DocumentationPublisher::class); $this->app->singleton(DocumentationProviderContract::class, DocumentationProvider::class); - $this->app->singleton(VCSCommandRunner::class, GitCommandRunner::class); + $this->app->singleton(VcsCommandRunner::class, GitCommandRunner::class); $this->app->singleton(ProductMakerContract::class, ProductMaker::class); $this->app->singleton(ProductFinderContract::class, ProductFinder::class); $this->app->singleton(ProductPublisherContract::class, ProductPublisher::class); + $this->app->singleton(FileHelperContract::class, FileHelper::class); + $this->app->singleton(YamlHelperContract::class, YamlHelper::class); + $this->app->singleton(ProcessHelperContract::class, ProcessHelper::class); $this->app->singleton( ConfigProviderContract::class, static function (): ConfigProviderContract { diff --git a/tests/TestCase.php b/tests/TestCase.php index 6e2fa03..8bcfef6 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -68,7 +68,7 @@ protected function getEnvironmentSetUp($app) * * @return array */ - protected function getPackageProviders($app) + protected function getPackageProviders($app): array { return [ ServiceProvider::class, @@ -85,7 +85,7 @@ protected function getPackageProviders($app) * * @return array */ - protected function getPackageAliases($app) + protected function getPackageAliases($app): array { return []; } diff --git a/tests/Unit/AspectMockedTestCase.php b/tests/Unit/AspectMockedTestCase.php deleted file mode 100644 index 1589d4c..0000000 --- a/tests/Unit/AspectMockedTestCase.php +++ /dev/null @@ -1,36 +0,0 @@ -setGroups(array_merge($this->getGroups(), [$group])); - } - - protected function tearDown(): void - { - Test::clean(); - - parent::tearDown(); - } -} diff --git a/tests/Unit/Factory/ProductMakerTest.php b/tests/Unit/Factory/ProductMakerTest.php index a531184..f698847 100644 --- a/tests/Unit/Factory/ProductMakerTest.php +++ b/tests/Unit/Factory/ProductMakerTest.php @@ -5,7 +5,10 @@ namespace ReliqArts\Docweaver\Tests\Unit\Factory; use Illuminate\Support\Str; +use Prophecy\Prophecy\ObjectProphecy; use ReliqArts\Docweaver\Contract\Exception; +use ReliqArts\Docweaver\Contract\FileHelper; +use ReliqArts\Docweaver\Contract\YamlHelper; use ReliqArts\Docweaver\Factory\ProductMaker; use ReliqArts\Docweaver\Tests\Unit\TestCase; @@ -19,18 +22,33 @@ final class ProductMakerTest extends TestCase { /** - * @var ProductMaker + * @var ObjectProphecy|FileHelper */ + private ObjectProphecy $fileHelper; + + /** + * @var ObjectProphecy|YamlHelper + */ + private ObjectProphecy $yamlHelper; + private ProductMaker $subject; protected function setUp(): void { parent::setUp(); + $this->fileHelper = $this->prophesize(FileHelper::class); + $this->yamlHelper = $this->prophesize(YamlHelper::class); + $this->configProvider->isWordedDefaultVersionAllowed() ->willReturn(true); - $this->subject = new ProductMaker($this->filesystem->reveal(), $this->configProvider->reveal()); + $this->subject = new ProductMaker( + $this->filesystem->reveal(), + $this->configProvider->reveal(), + $this->fileHelper->reveal(), + $this->yamlHelper->reveal() + ); } /** @@ -58,9 +76,9 @@ public function testCreate(): void $result = $this->subject->create($directory); - $this->assertSame($directory, $result->getDirectory()); - $this->assertSame($expectedKey, $result->getKey()); - $this->assertSame($expectedName, $result->getName()); + self::assertSame($directory, $result->getDirectory()); + self::assertSame($expectedKey, $result->getKey()); + self::assertSame($expectedName, $result->getName()); } /** diff --git a/tests/Unit/Model/ProductTest.php b/tests/Unit/Model/ProductTest.php index d5ff0eb..272fa43 100644 --- a/tests/Unit/Model/ProductTest.php +++ b/tests/Unit/Model/ProductTest.php @@ -1,21 +1,29 @@ fileHelper = $this->prophesize(FileHelper::class); + $this->yamlHelper = $this->prophesize(YamlHelper::class); $this->routePrefix = 'docs'; - $this->namespace = '\ReliqArts\Docweaver\Model'; $this->productName = Str::title(basename(self::PRODUCT_DIRECTORY)); $this->productKey = strtolower($this->productName); $this->lastModified = 123456789; @@ -77,9 +79,12 @@ protected function setUp(): void sprintf('%s/1.0', self::PRODUCT_DIRECTORY), sprintf('%s/2.0', self::PRODUCT_DIRECTORY), ]; - $this->expectedVersions = array_map(static function (string $versionDirectory) { - return basename($versionDirectory); - }, $this->versionDirectories); + $this->expectedVersions = array_map( + static function (string $versionDirectory) { + return basename($versionDirectory); + }, + $this->versionDirectories + ); $this->filesystem->directories(self::PRODUCT_DIRECTORY) ->shouldBeCalledTimes(1) @@ -87,6 +92,12 @@ protected function setUp(): void $this->filesystem->lastModified(self::PRODUCT_DIRECTORY) ->shouldBeCalledTimes(1) ->willReturn($this->lastModified); + + $this->fileHelper->getFileContents(Argument::cetera()) + ->willReturn(self::ARBITRARY_FILE_CONTENTS); + $this->fileHelper->realPath(Argument::cetera()) + ->willReturn(self::ARBITRARY_REAL_PATH); + $this->configProvider->getRoutePrefix() ->shouldBeCalledTimes(1) ->willReturn($this->routePrefix); @@ -94,6 +105,8 @@ protected function setUp(): void $this->subject = new Product( $this->filesystem->reveal(), $this->configProvider->reveal(), + $this->fileHelper->reveal(), + $this->yamlHelper->reveal(), self::PRODUCT_DIRECTORY ); } @@ -116,10 +129,14 @@ protected function setUp(): void * @covers ::toJson * @small * - * @throws Exception + * @throws Exception|JsonException */ public function testPopulateWithNoMeta(): void { + $this->fileHelper->realPath(Argument::cetera()) + ->shouldBeCalledTimes(1) + ->willReturn(false); + $this->configProvider->isWordedDefaultVersionAllowed() ->willReturn(true); $this->configProvider->getRoutePrefix() @@ -131,37 +148,37 @@ public function testPopulateWithNoMeta(): void $productJson = $this->subject->toJson(); $productVersions = $this->subject->getVersions(); - $this->assertIsArray($productVersions); - $this->assertSame( + self::assertIsArray($productVersions); + self::assertSame( 'master', $this->subject->getDefaultVersion(), 'Product default version is not as expected.' ); - $this->assertSame( + self::assertSame( Carbon::createFromTimestamp($this->lastModified)->toAtomString(), $this->subject->getLastModified()->toAtomString(), 'Product last modified time is not as expected.' ); - $this->assertSame( + self::assertSame( self::PRODUCT_DIRECTORY, $this->subject->getDirectory(), 'Product directory is not as expected.' ); - $this->assertSame($this->productName, $this->subject->getName(), 'Product name is not as expected.'); - $this->assertSame($this->productKey, $this->subject->getKey(), 'Product key is not as expected.'); - $this->assertCount(count($this->expectedVersions), $productVersions); - $this->assertEmpty($this->subject->getDescription()); - $this->assertEmpty($this->subject->getImageUrl()); - $this->assertNotEmpty($productArray); - $this->assertContains($this->productName, $productArray); - $this->assertContains($this->productKey, $productArray); - $this->assertCount(count($productArray), json_decode($productJson, true, 512, JSON_THROW_ON_ERROR)); + self::assertSame($this->productName, $this->subject->getName(), 'Product name is not as expected.'); + self::assertSame($this->productKey, $this->subject->getKey(), 'Product key is not as expected.'); + self::assertCount(count($this->expectedVersions), $productVersions); + self::assertEmpty($this->subject->getDescription()); + self::assertEmpty($this->subject->getImageUrl()); + self::assertNotEmpty($productArray); + self::assertContains($this->productName, $productArray); + self::assertContains($this->productKey, $productArray); + self::assertCount(count($productArray), json_decode($productJson, true, 512, JSON_THROW_ON_ERROR)); foreach ($this->expectedVersions as $expectedVersion) { $versionName = Str::title($expectedVersion); - $this->assertArrayHasKey($expectedVersion, $productVersions); - $this->assertContains($versionName, $productVersions); - $this->assertTrue($this->subject->hasVersion($expectedVersion)); + self::assertArrayHasKey($expectedVersion, $productVersions); + self::assertContains($versionName, $productVersions); + self::assertTrue($this->subject->hasVersion($expectedVersion)); } } @@ -178,21 +195,15 @@ public function testPopulateWithNoMeta(): void * @medium * @preserveGlobalState disabled * @runInSeparateProcess - * * @throws Exception + * @noinspection DisconnectedForeachInstructionInspection */ public function testPopulateWithMeta(): void { $metaProductName = 'Bravo'; $description = 'A product'; - $metaFile = 'meta-file'; $expectedDefaultVersion = '2.0'; $metaImageScenarios = $this->getMetaImageScenariosForVersion($expectedDefaultVersion); - $metaImageScenarioCount = count($metaImageScenarios); - - $realPath = Test::func($this->namespace, 'realpath', $metaFile); - $fileGetContents = Test::func($this->namespace, 'file_get_contents', $metaFile); - $yaml = null; $this->filesystem->directories(self::PRODUCT_DIRECTORY) ->shouldBeCalledTimes(2) @@ -204,7 +215,7 @@ public function testPopulateWithMeta(): void ->willReturn(false); foreach ($metaImageScenarios as $scenario) { - list($imageFilename, $expectedImageUrl) = $scenario; + [$imageFilename, $expectedImageUrl] = $scenario; $metaInfo = [ 'name' => $metaProductName, 'description' => $description, @@ -213,35 +224,36 @@ public function testPopulateWithMeta(): void : sprintf('{{docs}}/%s', $imageFilename), ]; - $yaml = Test::double(Yaml::class, ['parse' => $metaInfo]); + $this->yamlHelper->parse(Argument::type('string')) + ->shouldBeCalledTimes(2) + ->willReturn($metaInfo); $this->subject->populate(); - $this->assertSame( + self::assertSame( + $expectedImageUrl, + $this->subject->getImageUrl(), + 'Product image URL is not as expected.' + ); + + self::assertSame( $metaProductName, $this->subject->getName(), 'Product name is not as expected.' ); - $this->assertSame( + + self::assertSame( $description, $this->subject->getDescription(), 'Product description is not as expected.' ); - $this->assertSame( - $expectedImageUrl, - $this->subject->getImageUrl(), - 'Product image URL is not as expected.' - ); - $this->assertSame( + + self::assertSame( $expectedDefaultVersion, $this->subject->getDefaultVersion(), 'Product default version is not as expected.' ); } - - $realPath->verifyInvokedMultipleTimes($metaImageScenarioCount); - $fileGetContents->verifyInvokedMultipleTimes($metaImageScenarioCount); - $yaml->verifyInvokedMultipleTimes('parse', $metaImageScenarioCount); } /** @@ -262,15 +274,11 @@ public function testPopulateWithMeta(): void public function testPopulateWhenMetaIsInvalid(): void { $this->expectException(ParsingFailed::class); - $this->expectExceptionMessage('Failed to parse meta file `meta-file`. foo'); - - $metaFile = 'meta-file'; + $this->expectExceptionMessage(sprintf('Failed to parse meta file `%s`. foo', self::ARBITRARY_REAL_PATH)); - $realPath = Test::func($this->namespace, 'realpath', $metaFile); - $fileGetContents = Test::func($this->namespace, 'file_get_contents', $metaFile); - $yaml = Test::double(Yaml::class, ['parse' => function () { - throw new ParseException('foo'); - }]); + $this->yamlHelper->parse(Argument::cetera()) + ->shouldBeCalled() + ->willThrow(new ParseException('foo')); $this->configProvider->getRoutePrefix() ->shouldNotBeCalled(); @@ -278,10 +286,6 @@ public function testPopulateWhenMetaIsInvalid(): void ->willReturn(false); $this->subject->populate(); - - $realPath->verifyInvokedOnce(); - $fileGetContents->verifyInvokedOnce([$metaFile]); - $yaml->verifyInvokedOnce('parse'); } /** @@ -312,6 +316,7 @@ public function testPublishAssets(): void * @covers ::publishAssets * @covers \ReliqArts\Docweaver\Exception\Product\InvalidAssetDirectory * @small + * @throws Exception */ public function testPublishAssetsWhenImageDirectoryIsInvalid(): void { @@ -369,13 +374,15 @@ private function getMetaImageScenariosForVersion(string $version): array return [ 'relative image path' => [ $relativeImagePath, - asset(sprintf( - 'storage/%s/%s/%s/%s', - $this->routePrefix, - $this->productKey, - $version, - $relativeImagePath - )), + asset( + sprintf( + 'storage/%s/%s/%s/%s', + $this->routePrefix, + $this->productKey, + $version, + $relativeImagePath + ) + ), ], 'absolute image path' => [ $absoluteImagePath, diff --git a/tests/Unit/Service/ConfigProviderTest.php b/tests/Unit/Service/ConfigProviderTest.php index cadd795..1d8403a 100644 --- a/tests/Unit/Service/ConfigProviderTest.php +++ b/tests/Unit/Service/ConfigProviderTest.php @@ -51,10 +51,10 @@ public function testGetDocumentationDirectory(): void $result1 = $this->configProvider->getDocumentationDirectory(); $result2 = $this->configProvider->getDocumentationDirectory(true); - $this->assertIsString($result1); - $this->assertIsString($result2); - $this->assertSame(self::ARBITRARY_CONFIG_VALUE, $result1); - $this->assertSame(base_path(self::ARBITRARY_CONFIG_VALUE), $result2); + self::assertIsString($result1); + self::assertIsString($result2); + self::assertSame(self::ARBITRARY_CONFIG_VALUE, $result1); + self::assertSame(base_path(self::ARBITRARY_CONFIG_VALUE), $result2); } /** @@ -66,8 +66,8 @@ public function testGetRouteConfig(): void { $result = $this->configProvider->getRouteConfig(); - $this->assertIsArray($result); - $this->assertSame(self::ARBITRARY_CONFIG_ARRAY, $result); + self::assertIsArray($result); + self::assertSame(self::ARBITRARY_CONFIG_ARRAY, $result); } /** @@ -79,8 +79,8 @@ public function testGetRoutePrefix(): void { $result = $this->configProvider->getRoutePrefix(); - $this->assertIsString($result); - $this->assertSame(self::ARBITRARY_CONFIG_VALUE, $result); + self::assertIsString($result); + self::assertSame(self::ARBITRARY_CONFIG_VALUE, $result); } /** @@ -92,9 +92,9 @@ public function testGetRouteGroupBindings(): void { $result = $this->configProvider->getRouteGroupBindings(); - $this->assertIsArray($result); - $this->assertArrayHasKey('prefix', $result); - $this->assertSame(self::ARBITRARY_CONFIG_VALUE, $result['key']); + self::assertIsArray($result); + self::assertArrayHasKey('prefix', $result); + self::assertSame(self::ARBITRARY_CONFIG_VALUE, $result['key']); } /** @@ -106,8 +106,8 @@ public function testIsDebug(): void { $result = $this->configProvider->isDebug(); - $this->assertIsBool($result); - $this->assertTrue($result); + self::assertIsBool($result); + self::assertTrue($result); } /** @@ -119,8 +119,8 @@ public function testIsWordedDefaultVersionAllowed(): void { $result = $this->configProvider->isWordedDefaultVersionAllowed(); - $this->assertIsBool($result); - $this->assertTrue($result); + self::assertIsBool($result); + self::assertTrue($result); } /** @@ -132,8 +132,8 @@ public function testGetIndexRouteName(): void { $result = $this->configProvider->getIndexRouteName(); - $this->assertIsString($result); - $this->assertSame(self::ARBITRARY_CONFIG_VALUE, $result); + self::assertIsString($result); + self::assertSame(self::ARBITRARY_CONFIG_VALUE, $result); } /** @@ -145,8 +145,8 @@ public function testGetProductIndexRouteName(): void { $result = $this->configProvider->getProductIndexRouteName(); - $this->assertIsString($result); - $this->assertSame(self::ARBITRARY_CONFIG_VALUE, $result); + self::assertIsString($result); + self::assertSame(self::ARBITRARY_CONFIG_VALUE, $result); } /** @@ -158,8 +158,8 @@ public function testGetProductPageRouteName(): void { $result = $this->configProvider->getProductPageRouteName(); - $this->assertIsString($result); - $this->assertSame(self::ARBITRARY_CONFIG_VALUE, $result); + self::assertIsString($result); + self::assertSame(self::ARBITRARY_CONFIG_VALUE, $result); } /** @@ -171,8 +171,8 @@ public function testGetCacheKey(): void { $result = $this->configProvider->getCacheKey(); - $this->assertIsString($result); - $this->assertSame(self::ARBITRARY_CONFIG_VALUE, $result); + self::assertIsString($result); + self::assertSame(self::ARBITRARY_CONFIG_VALUE, $result); } /** @@ -184,8 +184,8 @@ public function testGetContentIndexPageName(): void { $result = $this->configProvider->getContentIndexPageName(); - $this->assertIsString($result); - $this->assertSame(self::ARBITRARY_CONFIG_VALUE, $result); + self::assertIsString($result); + self::assertSame(self::ARBITRARY_CONFIG_VALUE, $result); } /** @@ -198,15 +198,15 @@ public function testGetTemplateConfig(): void { $result = $this->configProvider->getTemplateConfig(); - $this->assertSame(self::ARBITRARY_CONFIG_VALUE, $result->getMasterTemplate()); - $this->assertSame(self::ARBITRARY_CONFIG_VALUE, $result->getMasterSection()); - $this->assertSame(self::ARBITRARY_CONFIG_VALUE, $result->getStyleStack()); - $this->assertSame(self::ARBITRARY_CONFIG_VALUE, $result->getScriptStack()); - $this->assertSame(self::ARBITRARY_CONFIG_VALUE, $result->getIndexTitle()); - $this->assertSame(self::ARBITRARY_CONFIG_VALUE, $result->getIndexIntro()); - $this->assertTrue($result->isShowProductLine()); - $this->assertTrue($result->isShowFootnotes()); - $this->assertTrue($result->hasStyleStack()); - $this->assertTrue($result->hasScriptStack()); + self::assertSame(self::ARBITRARY_CONFIG_VALUE, $result->getMasterTemplate()); + self::assertSame(self::ARBITRARY_CONFIG_VALUE, $result->getMasterSection()); + self::assertSame(self::ARBITRARY_CONFIG_VALUE, $result->getStyleStack()); + self::assertSame(self::ARBITRARY_CONFIG_VALUE, $result->getScriptStack()); + self::assertSame(self::ARBITRARY_CONFIG_VALUE, $result->getIndexTitle()); + self::assertSame(self::ARBITRARY_CONFIG_VALUE, $result->getIndexIntro()); + self::assertTrue($result->isShowProductLine()); + self::assertTrue($result->isShowFootnotes()); + self::assertTrue($result->hasStyleStack()); + self::assertTrue($result->hasScriptStack()); } } diff --git a/tests/Unit/Service/Documentation/ProviderTest.php b/tests/Unit/Service/Documentation/ProviderTest.php index 64b7586..eb22b7a 100644 --- a/tests/Unit/Service/Documentation/ProviderTest.php +++ b/tests/Unit/Service/Documentation/ProviderTest.php @@ -1,5 +1,11 @@ subject->getPage($this->product->reveal(), $version, $page); - $this->assertIsString($result); - $this->assertSame($pageContent, $result); + self::assertIsString($result); + self::assertSame($pageContent, $result); } /** @@ -201,8 +204,8 @@ public function testGetCachedPage(): void $result = $this->subject->getPage($this->product->reveal(), $version, $page); - $this->assertIsString($result); - $this->assertSame($pageContent, $result); + self::assertIsString($result); + self::assertSame($pageContent, $result); } /** @@ -225,8 +228,8 @@ public function testSectionExists(bool $exists): void ->willReturn($exists); $result = $this->subject->sectionExists($this->product->reveal(), $version, $page); - $this->assertIsBool($result); - $this->assertSame($exists, $result); + self::assertIsBool($result); + self::assertSame($exists, $result); } public function sectionExistenceDataProvider(): array diff --git a/tests/Unit/Service/Documentation/PublisherTest.php b/tests/Unit/Service/Documentation/PublisherTest.php index 10eec50..49fa74b 100644 --- a/tests/Unit/Service/Documentation/PublisherTest.php +++ b/tests/Unit/Service/Documentation/PublisherTest.php @@ -1,5 +1,11 @@ prophesize(Product::class)->reveal(); $messages = ['Test message 1', 'Test message 2']; - /** - * @var ObjectProphecy|Result - */ + /** @var ObjectProphecy|Result */ $productPublisherResult = $this->prophesize(Result::class); $productPublisherResult->getMessages() @@ -172,8 +176,8 @@ public function testPublish(): void $result = $this->subject->publish($productName, $source); - $this->assertInstanceOf(Result::class, $result); - $this->assertSame($messages, $result->getMessages()); + self::assertInstanceOf(Result::class, $result); + self::assertSame($messages, $result->getMessages()); } /** @@ -230,9 +234,7 @@ public function testUpdate(): void $product = $this->prophesize(Product::class)->reveal(); $messages = ['Successfully updated X']; - /** - * @var ObjectProphecy|Result - */ + /** @var ObjectProphecy|Result */ $productPublisherResult = $this->prophesize(Result::class); $productPublisherResult->getMessages() @@ -260,8 +262,8 @@ public function testUpdate(): void $result = $this->subject->update($productName); - $this->assertInstanceOf(Result::class, $result); - $this->assertSame($messages, $result->getMessages()); + self::assertInstanceOf(Result::class, $result); + self::assertSame($messages, $result->getMessages()); } /** @@ -320,9 +322,7 @@ public function testUpdateAll(array $productDirectories): void $productDirectoryCount = count($productDirectories); $messages = ['Successfully updated X']; - /** - * @var ObjectProphecy|Result - */ + /** @var ObjectProphecy|Result */ $productPublisherResult = $this->prophesize(Result::class); $productPublisherResult->getMessages() ->shouldBeCalledTimes($productDirectoryCount) @@ -362,13 +362,13 @@ public function testUpdateAll(array $productDirectories): void $result = $this->subject->updateAll(); $productsUpdated = $result->getExtra()->productsUpdated; - $this->assertInstanceOf(Result::class, $result); - $this->assertCount($productDirectoryCount, $productsUpdated); + self::assertInstanceOf(Result::class, $result); + self::assertCount($productDirectoryCount, $productsUpdated); foreach ($productDirectories as $productDirectory) { $productName = basename($productDirectory); - $this->assertContains($productName, $productsUpdated); + self::assertContains($productName, $productsUpdated); } } diff --git a/tests/Unit/Service/FilesystemTest.php b/tests/Unit/Service/FilesystemTest.php deleted file mode 100644 index 332aa03..0000000 --- a/tests/Unit/Service/FilesystemTest.php +++ /dev/null @@ -1,79 +0,0 @@ -namespace = '\ReliqArts\Docweaver\Service'; - $this->parentNamespace = '\Illuminate\Filesystem'; - $this->filesystem = new Filesystem(); - } - - /** - * @covers ::deleteDirectory - * @small - * @preserveGlobalState disabled - * @runInSeparateProcess - */ - public function testDeleteDirectory(): void - { - $directory = 'foo'; - $fakeDirectory = 'bar'; - $files = ['file 1', 'file 2', 'dir 1', 'dir 2', 'file 3']; - $fileCount = count($files); - $glob = Test::func($this->namespace, 'glob', function ($pattern) use ($directory, $files) { - return stripos($pattern, sprintf('%s/', $directory)) !== false ? $files : []; - }); - $isDir = Test::func($this->namespace, 'is_dir', function ($file) { - return stripos($file, 'dir') !== false; - }); - $parentIsDir = Test::func($this->parentNamespace, 'is_dir', function ($file) use ($fakeDirectory) { - return $file !== $fakeDirectory; - }); - $rmDir = Test::func($this->namespace, 'rmdir', true); - $chmod = Test::func($this->namespace, 'chmod', true); - $unlink = Test::func($this->namespace, 'unlink', true); - $subdirectoryCount = 0; - - $result1 = $this->filesystem->deleteDirectory($directory); - $result2 = $this->filesystem->deleteDirectory($fakeDirectory); - - foreach ($files as $file) { - if (stripos($file, 'dir') !== false) { - ++$subdirectoryCount; - } - } - - $glob->verifyInvokedMultipleTimes($subdirectoryCount + 1); - $isDir->verifyInvokedMultipleTimes($fileCount); - $parentIsDir->verifyInvokedOnce([$directory]); - $parentIsDir->verifyInvokedOnce([$fakeDirectory]); - $chmod->verifyInvokedMultipleTimes($fileCount - $subdirectoryCount); - $unlink->verifyInvokedMultipleTimes($fileCount - $subdirectoryCount); - $parentIsDir->verifyInvokedMultipleTimes($subdirectoryCount + 2); - $rmDir->verifyInvokedMultipleTimes($subdirectoryCount + 1); - $rmDir->verifyInvokedOnce([$directory]); - - $this->assertIsBool($result1); - $this->assertIsBool($result2); - $this->assertTrue($result1); - $this->assertFalse($result2); - } -} diff --git a/tests/Unit/Service/GitCommandRunnerTest.php b/tests/Unit/Service/GitCommandRunnerTest.php index 34008b3..ff9d3a9 100644 --- a/tests/Unit/Service/GitCommandRunnerTest.php +++ b/tests/Unit/Service/GitCommandRunnerTest.php @@ -1,15 +1,22 @@ namespace = '\ReliqArts\Docweaver\Service'; $this->returnedProcess = $this->prophesize(Process::class); - $this->subject = new GitCommandRunner(); + $this->processHelper = $this->prophesize(ProcessHelper::class); + + $this->processHelper->createProcess(Argument::cetera()) + ->willReturn($this->returnedProcess->reveal()); + + $this->subject = new GitCommandRunner($this->processHelper->reveal()); $this->workingDirectory = 'dir'; } @@ -65,13 +71,22 @@ public function testClone(): void { $source = 'my-src'; $branch = 'master'; - $process = Test::double(Process::class, [self::PROCESS_METHOD_MUST_RUN => $this->returnedProcess->reveal()]); - $this->subject->clone($source, $branch, $this->workingDirectory); + $this->processHelper->createProcess( + Argument::that( + fn (array $argument) => in_array($source, $argument, true) + && in_array($branch, $argument, true) + ), + $this->workingDirectory + )->willReturn($this->returnedProcess->reveal()); + + $this->returnedProcess + ->mustRun() + ->shouldBeCalledTimes(1); - $process->verifyInvokedMultipleTimes(self::PROCESS_METHOD_MUST_RUN, 1); + $this->subject->clone($source, $branch, $this->workingDirectory); - $this->assertTrue(true); + self::assertTrue(true); } /** @@ -82,32 +97,25 @@ public function testClone(): void * @preserveGlobalState disabled * @runInSeparateProcess * - * @throws Exception + * @param mixed $tagList */ - public function testGetTags(string $tagList): void + public function testGetTags($tagList): void { - $process = Test::double( - Process::class, - [ - self::PROCESS_METHOD_MUST_RUN => $this->returnedProcess->reveal(), - self::PROCESS_METHOD_GET_OUTPUT => $tagList, - ] - ); - $pregSplit = Test::func($this->namespace, 'preg_split', static function ($pattern, $text) { - return $text === self::SPLIT_ERROR_STATE ? false : \preg_split($pattern, $text); - }); - $expectedTags = $tagList !== self::SPLIT_ERROR_STATE - ? array_filter(array_map('trim', preg_split("/[\n\r]/", $tagList))) - : []; + $this->returnedProcess + ->mustRun() + ->shouldBeCalledTimes(2); - $results = $this->subject->listTags($this->workingDirectory); + $this->returnedProcess + ->getOutput() + ->shouldBeCalledTimes(1) + ->willReturn($tagList); - $process->verifyInvokedMultipleTimes(self::PROCESS_METHOD_MUST_RUN, 2); - $process->verifyInvokedMultipleTimes(self::PROCESS_METHOD_GET_OUTPUT, 1); - $pregSplit->verifyInvokedMultipleTimes(1); + $expectedTags = array_filter(array_map('trim', preg_split("/[\n\r]/", $tagList))); - $this->assertIsArray($results); - $this->assertSame($expectedTags, $results); + $results = $this->subject->listTags($this->workingDirectory); + + self::assertIsArray($results); + self::assertSame($expectedTags, $results); } /** @@ -120,15 +128,13 @@ public function testGetTags(string $tagList): void */ public function testPull(): void { - $process = Test::double(Process::class, [ - self::PROCESS_METHOD_MUST_RUN => $this->returnedProcess->reveal(), - ]); + $this->returnedProcess + ->mustRun() + ->shouldBeCalledTimes(1); $this->subject->pull($this->workingDirectory); - $process->verifyInvokedMultipleTimes(self::PROCESS_METHOD_MUST_RUN, 1); - - $this->assertTrue(true); + self::assertTrue(true); } /** @@ -142,17 +148,18 @@ public function testPull(): void public function testGetRemoteUrl(): void { $remoteUrl = 'url://remote-url'; - $process = Test::double(Process::class, [ - self::PROCESS_METHOD_MUST_RUN => $this->returnedProcess->reveal(), - self::PROCESS_METHOD_GET_OUTPUT => $remoteUrl, - ]); - $result = $this->subject->getRemoteUrl($this->workingDirectory); + $this->returnedProcess + ->mustRun() + ->shouldBeCalledTimes(1); + $this->returnedProcess + ->getOutput() + ->shouldBeCalledTimes(1) + ->willReturn($remoteUrl); - $process->verifyInvokedMultipleTimes(self::PROCESS_METHOD_MUST_RUN, 1); - $process->verifyInvokedMultipleTimes(self::PROCESS_METHOD_GET_OUTPUT, 1); + $result = $this->subject->getRemoteUrl($this->workingDirectory); - $this->assertSame($remoteUrl, $result); + self::assertSame($remoteUrl, $result); } public function tagListProvider(): array @@ -162,7 +169,6 @@ public function tagListProvider(): array 'precise tags' => ["1.1.0-beta\n2.0.0-alpha.2\r"], 'spaces' => ['\n\r\r\n'], 'no tags' => [''], - 'split error' => [self::SPLIT_ERROR_STATE], ]; } } diff --git a/tests/Unit/Service/MarkdownParserTest.php b/tests/Unit/Service/MarkdownParserTest.php index 28af1c7..987b45d 100644 --- a/tests/Unit/Service/MarkdownParserTest.php +++ b/tests/Unit/Service/MarkdownParserTest.php @@ -49,8 +49,8 @@ public function testParse(string $text, string $expectedResult): void ->willReturn($expectedResult); $result = $this->subject->parse($text); - $this->assertIsString($result); - $this->assertSame($result, $expectedResult); + self::assertIsString($result); + self::assertSame($result, $expectedResult); } public function textProvider(): array diff --git a/tests/Unit/Service/Product/FinderTest.php b/tests/Unit/Service/Product/FinderTest.php index 6ddd73a..6e8cdb7 100644 --- a/tests/Unit/Service/Product/FinderTest.php +++ b/tests/Unit/Service/Product/FinderTest.php @@ -74,9 +74,7 @@ public function testListProducts(): void foreach ($productDirectories as $productDirectory) { $key = basename($productDirectory); - /** - * @var ObjectProphecy|Product - */ + /** @var ObjectProphecy|Product */ $product = $this->prophesize(Product::class); $product->getDefaultVersion()->willReturn('1.0'); $product->getKey()->willReturn($key); @@ -96,12 +94,12 @@ public function testListProducts(): void $results = $this->subject->listProducts(); - $this->assertIsArray($results); - $this->assertCount(count($productDirectories) - $failedCount, $results); + self::assertIsArray($results); + self::assertCount(count($productDirectories) - $failedCount, $results); foreach ($results as $result) { - $this->assertInstanceOf(Product::class, $result); - $this->assertContains($result->getKey(), $productDirectories); + self::assertInstanceOf(Product::class, $result); + self::assertContains($result->getKey(), $productDirectories); } } @@ -126,9 +124,7 @@ public function testFindProduct(array $productDirectories, string $productName, foreach ($productDirectories as $productDirectory) { $key = strtolower(basename($productDirectory)); - /** - * @var ObjectProphecy|Product - */ + /** @var ObjectProphecy|Product */ $product = $this->prophesize(Product::class); $product->getDefaultVersion()->willReturn('1.0'); $product->getKey()->willReturn($key); @@ -140,13 +136,13 @@ public function testFindProduct(array $productDirectories, string $productName, $result = $this->subject->findProduct($productName); if (!$expectedToFindProduct) { - $this->assertNull($result); + self::assertNull($result); return; } - $this->assertInstanceOf(Product::class, $result); - $this->assertSame(strtolower($productName), $result->getKey()); + self::assertInstanceOf(Product::class, $result); + self::assertSame(strtolower($productName), $result->getKey()); } public function findProductDataProvider(): array diff --git a/tests/Unit/Service/Product/PublisherTest.php b/tests/Unit/Service/Product/PublisherTest.php index df71668..eafe8af 100644 --- a/tests/Unit/Service/Product/PublisherTest.php +++ b/tests/Unit/Service/Product/PublisherTest.php @@ -8,7 +8,7 @@ use Prophecy\Prophecy\ObjectProphecy; use ReliqArts\Docweaver\Contract\Exception; use ReliqArts\Docweaver\Contract\Logger; -use ReliqArts\Docweaver\Contract\VCSCommandRunner; +use ReliqArts\Docweaver\Contract\VcsCommandRunner; use ReliqArts\Docweaver\Exception\Product\AssetPublicationFailed; use ReliqArts\Docweaver\Exception\Product\InvalidAssetDirectory; use ReliqArts\Docweaver\Model\Product; @@ -42,7 +42,7 @@ final class PublisherTest extends TestCase private Publisher $subject; /** - * @var ObjectProphecy|VCSCommandRunner + * @var ObjectProphecy|VcsCommandRunner */ private ObjectProphecy $vcsCommandRunner; @@ -50,7 +50,7 @@ protected function setUp(): void { parent::setUp(); - $this->vcsCommandRunner = $this->prophesize(VCSCommandRunner::class); + $this->vcsCommandRunner = $this->prophesize(VcsCommandRunner::class); $this->product = $this->prophesize(Product::class); $this->logger = $this->prophesize(Logger::class); @@ -107,8 +107,8 @@ public function testPublish(): void $this->setTagExpectations($tags, $productDirectory, $source); $result = $this->subject->publish($product, $source); - $this->assertPublishSuccess($result, $productName, $tags); - $this->assertContains(Product::VERSION_MASTER, $result->getExtra()->versionsPublished); + self::assertPublishSuccess($result, $productName, $tags); + self::assertContains(Product::VERSION_MASTER, $result->getExtra()->versionsPublished); } /** @@ -158,7 +158,7 @@ public function testPublishWhenMasterExists(): void $this->setTagExpectations($tags, $productDirectory, $source); $result = $this->subject->publish($product, $source); - $this->assertPublishSuccess($result, $productName, $tags); + self::assertPublishSuccess($result, $productName, $tags); } /** @@ -207,7 +207,7 @@ public function testPublishWhenAssetDirectoryIsInvalid(): void $this->setTagExpectations($tags, $productDirectory, $source, ['1.0' => true]); $result = $this->subject->publish($product, $source); - $this->assertPublishSuccess($result, $productName, ['2.0']); + self::assertPublishSuccess($result, $productName, ['2.0']); } /** @@ -270,10 +270,10 @@ public function testPublishWhenAVersionPublicationFails(): void ->shouldNotBeCalled(); $result = $this->subject->publish($product, $source); - $this->assertInstanceOf(Result::class, $result); - $this->assertTrue($result->isSuccess()); - $this->assertContains('master', $result->getExtra()->versionsPublished); - $this->assertNotContains($tag, $result->getExtra()->versionsPublished); + self::assertInstanceOf(Result::class, $result); + self::assertTrue($result->isSuccess()); + self::assertContains('master', $result->getExtra()->versionsPublished); + self::assertNotContains($tag, $result->getExtra()->versionsPublished); } /** @@ -326,7 +326,7 @@ public function testPublishWhenAssetPublicationFails(): void $this->setTagExpectations($tags, $productDirectory, $source); $result = $this->subject->publish($product, $source); - $this->assertPublishSuccess($result, $productName, $tags); + self::assertPublishSuccess($result, $productName, $tags); } /** @@ -366,10 +366,10 @@ public function testPublishFailsIfProductDirectoryIsNotWritable(): void $result = $this->subject->publish($product, $source); - $this->assertInstanceOf(Result::class, $result); - $this->assertFalse($result->isSuccess()); - $this->assertIsString($result->getExtra()->executionTime); - $this->assertSame(sprintf('Product directory %s is not writable.', $productDirectory), $result->getError()); + self::assertInstanceOf(Result::class, $result); + self::assertFalse($result->isSuccess()); + self::assertIsString($result->getExtra()->executionTime); + self::assertSame(sprintf('Product directory %s is not writable.', $productDirectory), $result->getError()); } /** @@ -477,14 +477,14 @@ public function testUpdate(): void $result = $this->subject->update($this->product->reveal()); - $this->assertTrue($result->isSuccess()); + self::assertTrue($result->isSuccess()); foreach ($branches as $version) { - $this->assertContains($version, $result->getExtra()->versionsUpdated); + self::assertContains($version, $result->getExtra()->versionsUpdated); } foreach ($unpublishedTags as $version) { - $this->assertContains($version, $result->getExtra()->versionsPublished); + self::assertContains($version, $result->getExtra()->versionsPublished); } } @@ -536,22 +536,22 @@ public function testUpdateWhenAVersionUpdateFails(): void $result = $this->subject->update($this->product->reveal()); - $this->assertTrue($result->isSuccess()); - $this->assertNotContains('master', $result->getExtra()->versionsUpdated); - $this->assertContains('2.0', $result->getExtra()->versionsPublished); - $this->assertNotContains('1.0', $result->getExtra()->versionsPublished); + self::assertTrue($result->isSuccess()); + self::assertNotContains('master', $result->getExtra()->versionsUpdated); + self::assertContains('2.0', $result->getExtra()->versionsPublished); + self::assertNotContains('1.0', $result->getExtra()->versionsPublished); } private function assertPublishSuccess(Result $result, string $productName, array $tagsPublished): void { - $this->assertInstanceOf(Result::class, $result); - $this->assertTrue($result->isSuccess()); - $this->assertIsString($result->getExtra()->executionTime); - $this->assertSame(sprintf('%s was successfully published.', $productName), $result->getMessage()); - $this->assertContains(Product::VERSION_MASTER, $result->getExtra()->versions); + self::assertInstanceOf(Result::class, $result); + self::assertTrue($result->isSuccess()); + self::assertIsString($result->getExtra()->executionTime); + self::assertSame(sprintf('%s was successfully published.', $productName), $result->getMessage()); + self::assertContains(Product::VERSION_MASTER, $result->getExtra()->versions); foreach ($tagsPublished as $tag) { - $this->assertContains($tag, $result->getExtra()->versionsPublished); + self::assertContains($tag, $result->getExtra()->versionsPublished); } } diff --git a/tests/Unit/TestCase.php b/tests/Unit/TestCase.php index 3ec306b..b6d334a 100644 --- a/tests/Unit/TestCase.php +++ b/tests/Unit/TestCase.php @@ -4,12 +4,15 @@ namespace ReliqArts\Docweaver\Tests\Unit; +use Prophecy\PhpUnit\ProphecyTrait; use ReliqArts\Docweaver\Contract\ConfigProvider; use ReliqArts\Docweaver\Contract\Filesystem; use ReliqArts\Docweaver\Tests\TestCase as BaseTestCase; abstract class TestCase extends BaseTestCase { + use ProphecyTrait; + protected function setUp(): void { parent::setUp(); diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 1552e9d..36432a0 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -3,15 +3,3 @@ declare(strict_types=1); include __DIR__ . '/../vendor/autoload.php'; // composer autoload - -$kernel = \AspectMock\Kernel::getInstance(); -$kernel->init([ - 'debug' => true, - 'cacheDir' => __DIR__ . '/../build/cache', - 'includePaths' => [ - __DIR__ . '/../src', - __DIR__ . '/../vendor/symfony/process', - __DIR__ . '/../vendor/symfony/yaml', - ], - 'excludePaths' => [__DIR__], -]);