From 4c600b7143beb7421c0c604d428709b6e3b558d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Denis=20=C5=BDoljom?= Date: Thu, 26 Oct 2023 08:31:39 +0200 Subject: [PATCH 01/24] Update libs with wpcs 3 changes [beta] (#373) * Update composer dependencies * Update phpcs config * Remove unused ignored error * Fix deprecation notice Depth parameter shouldn't be set to 0. * Fix the tests failures because of inability to check the list of items vs source items * Remove extra space from init blocks command * Update readme * Fix phpcs violation * Fix deprecations with using traits directly Added anonymous classes instead. * Add mocks for the failing tests * Fix test deprecations * Update the gh action workflow * Workflow fix * Workflow update 8.3 allow failure for non-released version of PHP. * Minor formatting fix on helpers * Replace assertions with expectations API Should prevent failures on PHPUnit <9 where assertObjectHasProperty isn't defined. * Prevent the dynamic properties deprecation notices in tests This will still be an issue on composer installs with lowest dependencies where dynamic properties isn't allowed/fixed in mockery. * Minor grammar typo fix in a test * Update workflow to allow failures on lowest composer dependencies * Update moveItem method * Improve type description in moveItem method * Improve the moveItems method In real life cases, the sourceItem array will contain list of items in the folder, and the folder as a value, so we need to check that as well. This should probably come up in tests, unless the dataset is not correctly set to mimick how the real life projects are behaving. This needs investigation. --- .github/workflows/integrate.yml | 33 +++++--- composer.json | 12 +-- phpcs.xml.dist | 25 +++++- phpstan.neon.dist | 2 - src/Blocks/AbstractBlocksCli.php | 32 +++++--- src/Blocks/UseAssetsCli.php | 2 +- src/Blocks/UseGlobalAssetsCli.php | 2 +- src/Blocks/UseManifestCli.php | 2 +- src/Blocks/UseStorybookCli.php | 2 +- src/Db/DbExport.php | 6 +- src/Db/DbImport.php | 18 +++-- src/Init/InitBlocksCli.php | 1 - src/Menu/BemMenuWalker.php | 2 +- src/Readme/README.md | 4 +- tests/BaseTest.php | 65 +++++++++++++++ tests/Helpers.php | 3 +- tests/Unit/Blocks/BlocksExampleTest.php | 2 +- tests/Unit/Cli/CliHelpersTest.php | 6 +- tests/Unit/Columns/Media/MediaColumnsTest.php | 8 +- .../Unit/Exception/ComponentExceptionTest.php | 49 +++++++----- tests/Unit/Exception/FailedToLoadViewTest.php | 9 ++- tests/Unit/Exception/InvalidBlockTest.php | 80 ++++++++++++------- tests/Unit/Exception/InvalidCallbackTest.php | 8 +- tests/Unit/Exception/InvalidManifestTest.php | 24 +++--- tests/Unit/Exception/InvalidServiceTest.php | 8 +- .../Exception/PluginActivationFailureTest.php | 8 +- 26 files changed, 284 insertions(+), 129 deletions(-) diff --git a/.github/workflows/integrate.yml b/.github/workflows/integrate.yml index 0667510b5..b63f2f470 100644 --- a/.github/workflows/integrate.yml +++ b/.github/workflows/integrate.yml @@ -23,7 +23,7 @@ jobs: runs-on: "ubuntu-latest" steps: - name: "Checkout code" - uses: "actions/checkout@v3" + uses: "actions/checkout@v4" - name: "Check file permissions" run: | @@ -40,7 +40,7 @@ jobs: coverage: "none" - name: "Checkout code" - uses: "actions/checkout@v3" + uses: "actions/checkout@v4" - name: "Find non-printable ASCII characters (box-drawing characters excluded)" run: | @@ -63,12 +63,23 @@ jobs: strategy: fail-fast: false matrix: - php-version: - - "7.4" + php-version: ["7.4", "8.0", "8.1", "8.2"] dependencies: - "lowest" - "highest" + allowed_failure: [ false ] + # Allow failure on non-released version of PHP. + include: + - php: "8.1" + dependencies: "lowest" + allowed_failure: true + - php: "8.2" + dependencies: "lowest" + allowed_failure: true + - php: "8.3" + allowed_failure: true runs-on: "ubuntu-latest" + continue-on-error: ${{ matrix.allowed_failure }} steps: - name: "Set up PHP" uses: "shivammathur/setup-php@v2" @@ -77,14 +88,18 @@ jobs: coverage: "xdebug" - name: "Checkout code" - uses: "actions/checkout@v3" + uses: "actions/checkout@v4" - name: "Install dependencies" uses: "ramsey/composer-install@v2" with: dependency-versions: "${{ matrix.dependencies }}" - - name: "Execute unit tests" + - name: "Execute unit tests without coverage" + run: "composer run test:unit" + + - name: "Execute unit tests with coverage" + if: "${{ env.CODECOV_TOKEN && matrix.php-version == '7.4' && matrix.dependencies == 'highest' }}" run: "composer run test:coverage" - name: "Upload coverage to Codecov" @@ -113,7 +128,7 @@ jobs: coverage: "none" - name: "Checkout code" - uses: "actions/checkout@v3" + uses: "actions/checkout@v4" - name: "Validate Composer configuration" run: "composer validate --strict" @@ -142,7 +157,7 @@ jobs: tools: "cs2pr" - name: "Checkout code" - uses: "actions/checkout@v3" + uses: "actions/checkout@v4" - name: "Check adherence to EditorConfig" uses: "greut/eclint-action@v0" @@ -166,7 +181,7 @@ jobs: runs-on: "ubuntu-latest" steps: - name: "Checkout code" - uses: "actions/checkout@v3" + uses: "actions/checkout@v4" - name: "Check exported files" run: | diff --git a/composer.json b/composer.json index ea0262af3..476aa854a 100644 --- a/composer.json +++ b/composer.json @@ -24,21 +24,21 @@ "source": "https://github.com/infinum/eightshift-libs" }, "require": { - "php": "^7.4", + "php": "^7.4 || >=8.0", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", "php-di/invoker": "^2.3", - "php-di/php-di": "^6.3" + "php-di/php-di": "^7" }, "require-dev": { - "captainhook/captainhook": "^5.10", "brain/monkey": "^2.6.1", - "dealerdirect/phpcodesniffer-composer-installer": "^0.7", - "infinum/eightshift-coding-standards": "^1.6", + "captainhook/captainhook": "^5.10", + "dealerdirect/phpcodesniffer-composer-installer": "^v1.0.0", + "infinum/eightshift-coding-standards": "2.0.0-beta", "pestphp/pest": "^1.20", "php-parallel-lint/php-parallel-lint": "^1.3", - "php-stubs/wordpress-stubs": "^5.9", + "php-stubs/wordpress-stubs": "^6.3", "roave/security-advisories": "dev-master", "szepeviktor/phpstan-wordpress": "^1.0.3", "wp-cli/wp-cli": "^2.4", diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 9461e5cc1..00bbf7f21 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -24,7 +24,7 @@ - + /src/CompiledContainer\.php @@ -55,9 +55,26 @@ */src/Cli/* - - */src/**/*Cli.php - */src/Cli/* + + + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 0d831c80c..26ea174b8 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -13,7 +13,5 @@ parameters: excludePaths: - src/**/*Example.php ignoreErrors: - # Uses func_get_args() - - '/^Function apply_filters(_ref_array)? invoked with [34567] parameters, 2 required\.$/' # Ignore errors about reflection class variable being undefined. Errors are caught. - '/^Variable \$reflectionClass might not be defined\.$/' diff --git a/src/Blocks/AbstractBlocksCli.php b/src/Blocks/AbstractBlocksCli.php index a930773bd..6e2bbdbaa 100644 --- a/src/Blocks/AbstractBlocksCli.php +++ b/src/Blocks/AbstractBlocksCli.php @@ -56,7 +56,7 @@ protected function moveItems(array $args, string $source, string $destination, s self::cliError( \sprintf( // translators: %s will be replaced with type of item, and shorten cli path. - "%s files doesn't exist on this path: `%s`. Please check if you have eightshift-frontend-libs installed.", + "%s file doesn't exist on this path: `%s`. Please check if you have eightshift-frontend-libs installed.", $type, $this->getShortenCliPathOutput($source) ) @@ -74,25 +74,35 @@ protected function moveItems(array $args, string $source, string $destination, s $sourceItems = \array_merge($sourceItems, $sourceItemsPrivate); - if (($isSingleFolder || $isFile) && isset($sourceItems[$name])) { - $sourceItems = [ - $name => $sourceItems[$name], - ]; - } - if (!$sourceItems) { self::cliError( \sprintf( - // translators: %s will be replaced with type of item, and shorten cli path. - "%s files doesn't exist on this path: `%s`. Please check if you have eightshift-frontend-libs installed.", + // translators: %1$s will be replaced with type of item, %2$s the type and %3$s and shorten cli path. + '%1$s %2$s doesn\'t exist on this path: `%3$s`. Please check if you have eightshift-frontend-libs installed.', $type, + $isFile ? 'file' : 'folder', $this->getShortenCliPathOutput($source) ) ); } + $itemExists = false; foreach ($itemsList as $item) { - if (!isset($sourceItems[$item])) { + foreach ($sourceItems as $sourceItem => $sourceFolder) { + if (\strpos($sourceItem, $item) !== false) { + $itemExists = true; + break; + } + + // in the case of folders, we should also check the source folders. + if (\strpos($sourceFolder, $item) !== false) { + $itemExists = true; + break; + } + } + + + if (!$itemExists) { self::cliError( \sprintf( // translators: %s will be replaced with type of item, item name and shorten cli path. @@ -104,8 +114,6 @@ protected function moveItems(array $args, string $source, string $destination, s ); } - $source = $sourceItems[$item]; - $fullSource = Components::joinPaths([$source, $item]); $fullDestination = Components::joinPaths([$destination, $item]); diff --git a/src/Blocks/UseAssetsCli.php b/src/Blocks/UseAssetsCli.php index 0130193e4..5105f5aa4 100644 --- a/src/Blocks/UseAssetsCli.php +++ b/src/Blocks/UseAssetsCli.php @@ -82,7 +82,7 @@ public function __invoke(array $args, array $assocArgs) ), Components::getProjectPaths('blocksAssetsSource'), Components::getProjectPaths('blocksAssetsDestination'), - 'assets', + 'assets folder', true ); diff --git a/src/Blocks/UseGlobalAssetsCli.php b/src/Blocks/UseGlobalAssetsCli.php index 588d11735..209f5cebd 100644 --- a/src/Blocks/UseGlobalAssetsCli.php +++ b/src/Blocks/UseGlobalAssetsCli.php @@ -82,7 +82,7 @@ public function __invoke(array $args, array $assocArgs) ), Components::getProjectPaths('blocksGlobalAssetsSource'), Components::getProjectPaths('blocksGlobalAssetsDestination'), - 'assets', + 'assets folder', true ); diff --git a/src/Blocks/UseManifestCli.php b/src/Blocks/UseManifestCli.php index 090e3217e..dad611c5a 100644 --- a/src/Blocks/UseManifestCli.php +++ b/src/Blocks/UseManifestCli.php @@ -81,7 +81,7 @@ public function __invoke(array $args, array $assocArgs) ), Components::getProjectPaths('blocksSource'), Components::getProjectPaths('blocksDestination'), - 'manifest.json' + 'file' ); if (!$groupOutput) { diff --git a/src/Blocks/UseStorybookCli.php b/src/Blocks/UseStorybookCli.php index f3081a5a5..1d3740da4 100644 --- a/src/Blocks/UseStorybookCli.php +++ b/src/Blocks/UseStorybookCli.php @@ -87,7 +87,7 @@ public function __invoke(array $args, array $assocArgs) ), Components::getProjectPaths('blocksStorybookSource'), Components::getProjectPaths('blocksStorybookDestination'), - 'storybook', + 'storybook folder', true ); diff --git a/src/Db/DbExport.php b/src/Db/DbExport.php index 2ca2d93a8..223eee470 100644 --- a/src/Db/DbExport.php +++ b/src/Db/DbExport.php @@ -27,7 +27,11 @@ function dbExport(string $projectRootPath, array $args = []) // Change execution folder. if (!is_dir($projectRootPath)) { - CliHelpers::cliError("Folder doesn't exist on this path: {$projectRootPath}."); + $errorClass = new class () { + use CliHelpers; + }; + + $errorClass::cliError("Folder doesn't exist on this path: {$projectRootPath}."); } chdir($projectRootPath); diff --git a/src/Db/DbImport.php b/src/Db/DbImport.php index a273689b1..652ad281a 100644 --- a/src/Db/DbImport.php +++ b/src/Db/DbImport.php @@ -26,17 +26,21 @@ function dbImport(string $setupFile, array $args = []) $from = $args['from'] ?? ''; $to = $args['to'] ?? ''; + $errorClass = new class () { + use CliHelpers; + }; + if (empty($from)) { - CliHelpers::cliError("--from parameter is mandatory. Please provide one url key from setup.json file."); + $errorClass::cliError("--from parameter is mandatory. Please provide one url key from setup.json file."); } if (empty($to)) { - CliHelpers::cliError("--to parameter is mandatory. Please provide one url key from setup.json file."); + $errorClass::cliError("--to parameter is mandatory. Please provide one url key from setup.json file."); } // Check if file exists. if (is_dir($setupFile) && !file_exists($setupFile)) { - CliHelpers::cliError("Setup file doesn't exist on this path: {$setupFile}."); + $errorClass::cliError("Setup file doesn't exist on this path: {$setupFile}."); } // Parse json file to array. @@ -44,14 +48,14 @@ function dbImport(string $setupFile, array $args = []) // Check if $data is empty. if (empty($data)) { - CliHelpers::cliError("Setup file is empty on this path: {$setupFile}."); + $errorClass::cliError("Setup file is empty on this path: {$setupFile}."); } // Check if urls key exists. $urls = $data['urls'] ?? []; if (empty($urls)) { - CliHelpers::cliError('Urls key is missing or empty.'); + $errorClass::cliError('Urls key is missing or empty.'); } $fromHost = ''; @@ -59,7 +63,7 @@ function dbImport(string $setupFile, array $args = []) // Die if from key is missing and not valid. if (!isset($urls[$from]) || empty($urls[$from])) { - CliHelpers::cliError("{$from} key is missing or empty in urls."); + $errorClass::cliError("{$from} key is missing or empty in urls."); } else { $from = wp_parse_url($urls[$from]); $fromHost = $from['host']; @@ -71,7 +75,7 @@ function dbImport(string $setupFile, array $args = []) // Die if to key is missing and not valid. if (!isset($urls[$to]) || empty($urls[$to])) { - CliHelpers::cliError("{$to} key is missing or empty in urls."); + $errorClass::cliError("{$to} key is missing or empty in urls."); } else { $to = wp_parse_url($urls[$to]); $toHost = $to['host']; diff --git a/src/Init/InitBlocksCli.php b/src/Init/InitBlocksCli.php index 9983de458..a342af271 100644 --- a/src/Init/InitBlocksCli.php +++ b/src/Init/InitBlocksCli.php @@ -156,7 +156,6 @@ public function __invoke(array $args, array $assocArgs) $this->cliLog("%w╭\n│ %nCreating block editor files", 'mixed'); - $commands = static::COMMANDS; if ($all) { diff --git a/src/Menu/BemMenuWalker.php b/src/Menu/BemMenuWalker.php index bf35bde70..3e3f6341e 100644 --- a/src/Menu/BemMenuWalker.php +++ b/src/Menu/BemMenuWalker.php @@ -72,7 +72,7 @@ public function display_element( // phpcs:ignore PSR1.Methods.CamelCapsMethodNam $element, &$children_elements, $max_depth, // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps, PEAR.Functions.ValidDefaultValue.NotAtEnd - $depth = 0, + $depth, $args, // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps, PEAR.Functions.ValidDefaultValue.NotAtEnd &$output ) { diff --git a/src/Readme/README.md b/src/Readme/README.md index c8721e2a3..0b91a243f 100644 --- a/src/Readme/README.md +++ b/src/Readme/README.md @@ -4,8 +4,8 @@ This is the official repository of the {Project name}. ## Requirements -1. PHP 7.4 -2. Node 12 +1. PHP 7.4 or higher +2. Node 16+ 3. [Node.js](https://nodejs.org/en/) 4. [Composer](https://getcomposer.org/) 5. [(Optional) WP cli](https://wp-cli.org/) diff --git a/tests/BaseTest.php b/tests/BaseTest.php index c40b96ffb..6d26436ad 100644 --- a/tests/BaseTest.php +++ b/tests/BaseTest.php @@ -13,6 +13,47 @@ class BaseTest extends TestCase { + // Preventing dynamic properties deprecation notices in tests. + protected $adminEnqueue; + protected $blocksEnqueue; + protected $blocksExample; + protected $cli; + protected $example; + protected $field; + protected $geolocation; + protected $geolocationCli; + protected $germanIp; + protected $hookSuffix; + protected $i18n; + protected $login; + protected $main; + protected $manualDepsNoPrimitive; + protected $manuallyDefinedDependencies; + protected $media; + protected $mediaCli; + protected $mock; + protected $mockFileName; + protected $mockHelper; + protected $mockLogger; + protected $mockMedia; + protected $mockPath; + protected $mockRequestKey; + protected $modifyAdminAppearance; + protected $pluginManage; + protected $post; + protected $projectName; + protected $projectNamespace; + protected $projectVersion; + protected $regenerateWebPMediaCli; + protected $route; + protected $service; + protected $shortcode; + protected $themeEnqueue; + protected $webPMediaColumnCliMock; + protected $webPMediaColumnExampleMock; + protected $webPMediaColumnExampleMockColumns; + protected $wpRestServer; + protected MockInterface $wpCliMock; protected function set_up() @@ -150,6 +191,30 @@ protected function set_up() Functions\when('is_wp_version_compatible')->justReturn(true); Functions\when('wp_nonce_field')->justReturn('nonce'); + + // Mock https://developer.wordpress.org/reference/functions/wp_is_json_media_type/ function + Functions\when('wp_is_json_media_type')->alias(function ($mediaType) { + static $cache = array(); + + if ( ! isset( $cache[ $mediaType ] ) ) { + $cache[ $mediaType ] = (bool) preg_match( '/(^|\s|,)application\/([\w!#\$&-\^\.\+]+\+)?json(\+oembed)?($|\s|;|,)/i', $mediaType ); + } + + return $cache[ $mediaType ]; + }); + + // Mock https://developer.wordpress.org/reference/functions/wp_is_json_request/ function + Functions\when('wp_is_json_request')->alias(function () { + if ( isset( $_SERVER['HTTP_ACCEPT'] ) && wp_is_json_media_type( $_SERVER['HTTP_ACCEPT'] ) ) { + return true; + } + + if ( isset( $_SERVER['CONTENT_TYPE'] ) && wp_is_json_media_type( $_SERVER['CONTENT_TYPE'] ) ) { + return true; + } + + return false; + }); } protected function tear_down() diff --git a/tests/Helpers.php b/tests/Helpers.php index 755b1d2b3..7940256a2 100644 --- a/tests/Helpers.php +++ b/tests/Helpers.php @@ -12,7 +12,8 @@ * * @return void */ -function buildTestBlocks() { +function buildTestBlocks() +{ (new InitBlocksCli('boilerplate'))->__invoke([], []); (new BlocksExample())->getBlocksDataFullRaw(); diff --git a/tests/Unit/Blocks/BlocksExampleTest.php b/tests/Unit/Blocks/BlocksExampleTest.php index c8a29fea0..c45e45add 100644 --- a/tests/Unit/Blocks/BlocksExampleTest.php +++ b/tests/Unit/Blocks/BlocksExampleTest.php @@ -84,7 +84,7 @@ })->throws(\TypeError::class) ->with('getAllAllowedBlocksListAllTypesArguments'); -test('Asserts that getAllBlocksList is not influence by the first parameter', function ($argument) { +test('Asserts that getAllBlocksList is not influenced by the first parameter', function ($argument) { $blockContext = mock(WP_Block_Editor_Context::class); $blockContext->post = null; diff --git a/tests/Unit/Cli/CliHelpersTest.php b/tests/Unit/Cli/CliHelpersTest.php index 6c8d5a678..af9d878b1 100644 --- a/tests/Unit/Cli/CliHelpersTest.php +++ b/tests/Unit/Cli/CliHelpersTest.php @@ -5,5 +5,9 @@ use EightshiftLibs\Cli\CliHelpers; test('cliError wrapper will return a WPCLI error', function () { - CliHelpers::cliError('Some random cli error happened'); + $class = new class { + use CliHelpers; + }; + + $class::cliError('Some random cli error happened'); })->expectExceptionMessage('Some random cli error happened'); diff --git a/tests/Unit/Columns/Media/MediaColumnsTest.php b/tests/Unit/Columns/Media/MediaColumnsTest.php index 46b31eac5..dd862e057 100644 --- a/tests/Unit/Columns/Media/MediaColumnsTest.php +++ b/tests/Unit/Columns/Media/MediaColumnsTest.php @@ -27,10 +27,10 @@ public function sortAddedColumns(array $columns): array $mockUserColumn->register(); - $this->assertNotFalse(has_filter('manage_media_columns', 'Tests\Unit\Columns\MediaColumnMock->addColumnName()'), 'manage_media_columns filter wasn\'t registered'); + $this->assertNotFalse(has_filter('manage_upload_columns', 'Tests\Unit\Columns\MediaColumnMock->addColumnName()'), 'manage_upload_columns filter wasn\'t registered'); $this->assertNotFalse(has_filter('manage_media_custom_column', 'Tests\Unit\Columns\MediaColumnMock->renderColumnContent()'), 'manage_media_custom_column filter wasn\'t registered'); - $this->assertNotFalse(has_filter('manage_media_sortable_columns', 'Tests\Unit\Columns\MediaColumnMock->sortAddedColumns()'), 'manage_media_sortable_columns filter wasn\'t registered'); - $this->assertSame(10, has_filter('manage_media_columns', 'Tests\Unit\Columns\MediaColumnMock->addColumnName()'), 'manage_media_columns filter priority was not correct'); + $this->assertNotFalse(has_filter('manage_upload_sortable_columns', 'Tests\Unit\Columns\MediaColumnMock->sortAddedColumns()'), 'manage_upload_sortable_columns filter wasn\'t registered'); + $this->assertSame(10, has_filter('manage_upload_columns', 'Tests\Unit\Columns\MediaColumnMock->addColumnName()'), 'manage_upload_columns filter priority was not correct'); $this->assertSame(10, has_filter('manage_media_custom_column', 'Tests\Unit\Columns\MediaColumnMock->renderColumnContent()'), 'manage_media_custom_column filter priority was not correct'); - $this->assertSame(10, has_filter('manage_media_sortable_columns', 'Tests\Unit\Columns\MediaColumnMock->sortAddedColumns()'), 'manage_media_sortable_columns filter priority was not correct'); + $this->assertSame(10, has_filter('manage_upload_sortable_columns', 'Tests\Unit\Columns\MediaColumnMock->sortAddedColumns()'), 'manage_upload_sortable_columns filter priority was not correct'); }); diff --git a/tests/Unit/Exception/ComponentExceptionTest.php b/tests/Unit/Exception/ComponentExceptionTest.php index 0e1f18b9e..a569fabd5 100644 --- a/tests/Unit/Exception/ComponentExceptionTest.php +++ b/tests/Unit/Exception/ComponentExceptionTest.php @@ -9,32 +9,37 @@ function ($argument) { $exceptionObject = ComponentException::throwNotStringOrArray($argument); $type = \gettype($argument); - - $this->assertIsObject($exceptionObject, "The {$exceptionObject} should be an instance of ComponentException class"); - $this->assertObjectHasAttribute('message', $exceptionObject, "Object doesn't contain message attribute"); - $this->assertSame("{$argument} variable is not a string or array but rather {$type}", $exceptionObject->getMessage(), "Strings for message if item is {$type} do not match!"); - - }) - ->with('exceptionArguments'); - - test('Checks if the throwNotStringOrArray method functions correctly with objects.', - function () { - - $object = new stdClass(); - $exceptionObject = ComponentException::throwNotStringOrArray($object); - - $this->assertIsObject($exceptionObject, "The object should be an instance of ComponentException class"); - $this->assertObjectHasAttribute('message', $exceptionObject, "Object doesn't contain message attribute"); - $this->assertSame('Object couldn\'t be converted to string. Please provide only string or array.', $exceptionObject->getMessage(), "Strings for 'Object couldn't be converted to string' message do not match!"); - - }); + $message = "{$argument} variable is not a string or array but rather {$type}"; + + expect($exceptionObject)->toBeObject() + ->toBeInstanceOf(ComponentException::class) + ->toHaveProperty('message') + ->and($message) + ->toEqual($exceptionObject->getMessage()); +}) +->with('exceptionArguments'); + +test('Checks if the throwNotStringOrArray method functions correctly with objects.', +function () { + + $object = new stdClass(); + $exceptionObject = ComponentException::throwNotStringOrArray($object); + + expect($exceptionObject)->toBeObject() + ->toBeInstanceOf(ComponentException::class) + ->toHaveProperty('message') + ->and('Object couldn\'t be converted to string. Please provide only string or array.') + ->toEqual($exceptionObject->getMessage()); +}); test('Checks if throwUnableToLocateComponent method will return correct response.', function () { $component = 'nonexistent'; $output = ComponentException::throwUnableToLocateComponent($component); - $this->assertIsObject($output, "The {$output} should be an instance of ComponentException class"); - $this->assertObjectHasAttribute('message', $output, "Object doesn't contain message attribute"); - $this->assertSame("Unable to locate component by path: {$component}", $output->getMessage(), "Strings for 'Unable to locate component by path' message do not match!"); + expect($output)->toBeObject() + ->toBeInstanceOf(ComponentException::class) + ->toHaveProperty('message') + ->and("Unable to locate component by path: {$component}") + ->toEqual($output->getMessage()); }); diff --git a/tests/Unit/Exception/FailedToLoadViewTest.php b/tests/Unit/Exception/FailedToLoadViewTest.php index f0d038661..a5829c451 100644 --- a/tests/Unit/Exception/FailedToLoadViewTest.php +++ b/tests/Unit/Exception/FailedToLoadViewTest.php @@ -11,8 +11,11 @@ $exception = new Exception('Error message'); $exceptionObject = FailedToLoadView::viewException($uri, $exception); + $message = "Could not load the View URI: {$uri}. Reason: {$exception->getMessage()}."; - $this->assertIsObject($exceptionObject, "The {$exceptionObject} should be an instance of FailedToLoadView class"); - $this->assertObjectHasAttribute('message', $exceptionObject, "Object doesn't contain message attribute"); - $this->assertSame("Could not load the View URI: {$uri}. Reason: {$exception->getMessage()}.", $exceptionObject->getMessage(), "Strings for exception messages do not match!"); + expect($exceptionObject)->toBeObject() + ->toBeInstanceOf(FailedToLoadView::class) + ->toHaveProperty('message') + ->and($message) + ->toEqual($exceptionObject->getMessage()); }); diff --git a/tests/Unit/Exception/InvalidBlockTest.php b/tests/Unit/Exception/InvalidBlockTest.php index 11ed8fc46..dc3fdee60 100644 --- a/tests/Unit/Exception/InvalidBlockTest.php +++ b/tests/Unit/Exception/InvalidBlockTest.php @@ -8,18 +8,22 @@ $missingBlocks = InvalidBlock::missingBlocksException(); - $this->assertIsObject($missingBlocks, "The {$missingBlocks} should be an instance of InvalidBlock class"); - $this->assertObjectHasAttribute('message', $missingBlocks, "Object doesn't contain message attribute"); - $this->assertSame('There are no blocks added in your project.', $missingBlocks->getMessage(), "Strings for message if there are no blocks added to the project do not match!"); + expect($missingBlocks)->toBeObject() + ->toBeInstanceOf(InvalidBlock::class) + ->toHaveProperty('message') + ->and('There are no blocks added in your project.') + ->toEqual($missingBlocks->getMessage()); }); test('Checks if missingComponentsException will return correct response.', function () { $missingComponents = InvalidBlock::missingComponentsException(); - $this->assertIsObject($missingComponents); - $this->assertObjectHasAttribute('message', $missingComponents); - $this->assertSame('There are no components added in your project.', $missingComponents->getMessage(), "Strings for message if there are no components added to the project do not match!"); + expect($missingComponents)->toBeObject() + ->toBeInstanceOf(InvalidBlock::class) + ->toHaveProperty('message') + ->and('There are no components added in your project.') + ->toEqual($missingComponents->getMessage()); }); test('Checks if missingNameException will return correct response.', function () { @@ -27,9 +31,11 @@ $blockPath = 'some/random/path'; $missingName = InvalidBlock::missingNameException($blockPath); - $this->assertIsObject($missingName); - $this->assertObjectHasAttribute('message', $missingName); - $this->assertSame("Block in this path {$blockPath} is missing blockName key in its manifest.json.", $missingName->getMessage(), "Strings for message if blockName key is missing in manifest.json do not match!"); + expect($missingName)->toBeObject() + ->toBeInstanceOf(InvalidBlock::class) + ->toHaveProperty('message') + ->and("Block in this path {$blockPath} is missing blockName key in its manifest.json.") + ->toEqual($missingName->getMessage()); }); test('Checks if missingViewException will return correct response.', function () { @@ -38,9 +44,11 @@ $blockPath = 'some/random/path'; $missingView = InvalidBlock::missingViewException($blockName, $blockPath); - $this->assertIsObject($missingView); - $this->assertObjectHasAttribute('message', $missingView); - $this->assertSame("Block with this name {$blockName} is missing view template. Template name should be called {$blockName}.php, and it should be located in this path {$blockPath}", $missingView->getMessage(), "Strings for message if block is missing view template do not match!"); + expect($missingView)->toBeObject() + ->toBeInstanceOf(InvalidBlock::class) + ->toHaveProperty('message') + ->and("Block with this name {$blockName} is missing view template. Template name should be called {$blockName}.php, and it should be located in this path {$blockPath}") + ->toEqual($missingView->getMessage()); }); test('Checks if missingRenderViewException will return correct response.', function () { @@ -48,9 +56,11 @@ $blockPath = 'some/random/path'; $missingRenderView = InvalidBlock::missingRenderViewException($blockPath); - $this->assertIsObject($missingRenderView); - $this->assertObjectHasAttribute('message', $missingRenderView); - $this->assertSame("Block view is missing in the provided path. Please check if {$blockPath} is the right path for your block view.", $missingRenderView->getMessage(), "Strings for message if block view is missing provided path do not match!"); + expect($missingRenderView)->toBeObject() + ->toBeInstanceOf(InvalidBlock::class) + ->toHaveProperty('message') + ->and("Block view is missing in the provided path. Please check if {$blockPath} is the right path for your block view.") + ->toEqual($missingRenderView->getMessage()); }); test('Checks if missingSettingsManifestException will return correct response.', function () { @@ -58,9 +68,11 @@ $manifestPath = 'some/random/path'; $missingManifestPath = InvalidBlock::missingSettingsManifestException($manifestPath); - $this->assertIsObject($missingManifestPath); - $this->assertObjectHasAttribute('message', $missingManifestPath); - $this->assertSame("Global blocks settings manifest.json is missing on this location: {$manifestPath}.", $missingManifestPath->getMessage(), "Strings for message if global blocks settings manifest.json is missing do not match!"); + expect($missingManifestPath)->toBeObject() + ->toBeInstanceOf(InvalidBlock::class) + ->toHaveProperty('message') + ->and("Global blocks settings manifest.json is missing on this location: {$manifestPath}.") + ->toEqual($missingManifestPath->getMessage()); }); test('Checks if missingWrapperManifestException will return correct response.', function () { @@ -68,9 +80,11 @@ $manifestPath = 'some/random/path'; $missingManifestPath = InvalidBlock::missingWrapperManifestException($manifestPath); - $this->assertIsObject($missingManifestPath); - $this->assertObjectHasAttribute('message', $missingManifestPath); - $this->assertSame("Wrapper blocks settings manifest.json is missing on this location: {$manifestPath}.", $missingManifestPath->getMessage(), "Strings for message if wrapper blocks settings manifest.json is missing do not match!"); + expect($missingManifestPath)->toBeObject() + ->toBeInstanceOf(InvalidBlock::class) + ->toHaveProperty('message') + ->and("Wrapper blocks settings manifest.json is missing on this location: {$manifestPath}.") + ->toEqual($missingManifestPath->getMessage()); }); test('Checks if missingComponentManifestException will return correct response.', function () { @@ -78,9 +92,11 @@ $manifestPath = 'some/random/path'; $missingComponentManifest = InvalidBlock::missingComponentManifestException($manifestPath); - $this->assertIsObject($missingComponentManifest); - $this->assertObjectHasAttribute('message', $missingComponentManifest); - $this->assertSame("Component manifest.json is missing on this location: {$manifestPath}.", $missingComponentManifest->getMessage(), "Strings for message if component manifest.json is missing do not match!"); + expect($missingComponentManifest)->toBeObject() + ->toBeInstanceOf(InvalidBlock::class) + ->toHaveProperty('message') + ->and("Component manifest.json is missing on this location: {$manifestPath}.") + ->toEqual($missingComponentManifest->getMessage()); }); test('Checks if missingWrapperViewException will return correct response.', function () { @@ -88,16 +104,20 @@ $wrapperPath = 'some/random/path'; $missingWrapperView = InvalidBlock::missingWrapperViewException($wrapperPath); - $this->assertIsObject($missingWrapperView); - $this->assertObjectHasAttribute('message', $missingWrapperView); - $this->assertSame("Wrapper view is missing. Template should be located in this path {$wrapperPath}", $missingWrapperView->getMessage(), "Strings for message if wrapper view is missing do not match!"); + expect($missingWrapperView)->toBeObject() + ->toBeInstanceOf(InvalidBlock::class) + ->toHaveProperty('message') + ->and("Wrapper view is missing. Template should be located in this path {$wrapperPath}") + ->toEqual($missingWrapperView->getMessage()); }); test('Checks if missingNamespaceException will return correct response.', function () { $missingNamespace = InvalidBlock::missingNamespaceException(); - $this->assertIsObject($missingNamespace); - $this->assertObjectHasAttribute('message', $missingNamespace); - $this->assertSame('Global Blocks settings manifest.json is missing a key called namespace. This key prefixes all block names.', $missingNamespace->getMessage(), "Strings for message global settings manifest.json is missing a key called namespace do not match!"); + expect($missingNamespace)->toBeObject() + ->toBeInstanceOf(InvalidBlock::class) + ->toHaveProperty('message') + ->and('Global Blocks settings manifest.json is missing a key called namespace. This key prefixes all block names.') + ->toEqual($missingNamespace->getMessage()); }); diff --git a/tests/Unit/Exception/InvalidCallbackTest.php b/tests/Unit/Exception/InvalidCallbackTest.php index e4478a585..d423c15e4 100644 --- a/tests/Unit/Exception/InvalidCallbackTest.php +++ b/tests/Unit/Exception/InvalidCallbackTest.php @@ -10,7 +10,9 @@ $exceptionObject = InvalidCallback::fromCallback($callback); - $this->assertIsObject($exceptionObject, "The {$exceptionObject} should be an instance of InvalidBlock class"); - $this->assertObjectHasAttribute('message', $exceptionObject, "Object doesn't contain message attribute"); - $this->assertSame("The callback {$callback} is not recognized and cannot be registered.", $exceptionObject->getMessage(), "Strings for message if callback isn't recognised do not match!"); + expect($exceptionObject)->toBeObject() + ->toBeInstanceOf(InvalidCallback::class) + ->toHaveProperty('message') + ->and("The callback {$callback} is not recognized and cannot be registered.") + ->toEqual($exceptionObject->getMessage()); }); diff --git a/tests/Unit/Exception/InvalidManifestTest.php b/tests/Unit/Exception/InvalidManifestTest.php index c1f2ab1c3..cb305b4cc 100644 --- a/tests/Unit/Exception/InvalidManifestTest.php +++ b/tests/Unit/Exception/InvalidManifestTest.php @@ -10,9 +10,11 @@ $exceptionObject = InvalidManifest::missingManifestItemException($key); - $this->assertIsObject($exceptionObject, "The {$exceptionObject} should be an instance of InvalidManifest class"); - $this->assertObjectHasAttribute('message', $exceptionObject, "Object doesn't contain message attribute"); - $this->assertSame("{$key} key does not exist in manifest.json. Please check if provided key is correct.", $exceptionObject->getMessage(), "Strings for message if manifest key is missing do not match!"); + expect($exceptionObject)->toBeObject() + ->toBeInstanceOf(InvalidManifest::class) + ->toHaveProperty('message') + ->and("{$key} key does not exist in manifest.json. Please check if provided key is correct.") + ->toEqual($exceptionObject->getMessage()); }); test('Checks if the missingManifestException method will return correct response.', function () { @@ -21,9 +23,11 @@ $exceptionObject = InvalidManifest::missingManifestException($manifestPath); - $this->assertIsObject($exceptionObject, "The {$exceptionObject} should be an instance of InvalidManifest class"); - $this->assertObjectHasAttribute('message', $exceptionObject, "Object doesn't contain message attribute"); - $this->assertSame("manifest.json is missing at this path: {$manifestPath}. Bundle the theme before using it. Or your bundling process is returning an error.", $exceptionObject->getMessage(), "Strings for message if manifest is missing do not match!"); + expect($exceptionObject)->toBeObject() + ->toBeInstanceOf(InvalidManifest::class) + ->toHaveProperty('message') + ->and("manifest.json is missing at this path: {$manifestPath}. Bundle the theme before using it. Or your bundling process is returning an error.") + ->toEqual($exceptionObject->getMessage()); }); test('Checks if the manifestStructureException method will return correct response.', function () { @@ -32,7 +36,9 @@ $exceptionObject = InvalidManifest::manifestStructureException($errorMessage); - $this->assertIsObject($exceptionObject, "The {$exceptionObject} should be an instance of InvalidManifest class"); - $this->assertObjectHasAttribute('message', $exceptionObject, "Object doesn't contain message attribute"); - $this->assertSame($errorMessage, $exceptionObject->getMessage(), "Strings for manifest structure error message do not match!"); + expect($exceptionObject)->toBeObject() + ->toBeInstanceOf(InvalidManifest::class) + ->toHaveProperty('message') + ->and($errorMessage) + ->toEqual($exceptionObject->getMessage()); }); diff --git a/tests/Unit/Exception/InvalidServiceTest.php b/tests/Unit/Exception/InvalidServiceTest.php index 26609f3e1..7edac3e84 100644 --- a/tests/Unit/Exception/InvalidServiceTest.php +++ b/tests/Unit/Exception/InvalidServiceTest.php @@ -10,7 +10,9 @@ $exceptionObject = InvalidService::fromService($service); - $this->assertIsObject($exceptionObject, "The {$exceptionObject} should be an instance of InvalidService class"); - $this->assertObjectHasAttribute('message', $exceptionObject, "Object doesn't contain message attribute"); - $this->assertSame("The service {$service} is not recognized and cannot be registered.", $exceptionObject->getMessage(), "Strings for message if service name isn't recognised do not match!"); + expect($exceptionObject)->toBeObject() + ->toBeInstanceOf(InvalidService::class) + ->toHaveProperty('message') + ->and("The service {$service} is not recognized and cannot be registered.") + ->toEqual($exceptionObject->getMessage()); }); diff --git a/tests/Unit/Exception/PluginActivationFailureTest.php b/tests/Unit/Exception/PluginActivationFailureTest.php index f065262b3..19fff6aa6 100644 --- a/tests/Unit/Exception/PluginActivationFailureTest.php +++ b/tests/Unit/Exception/PluginActivationFailureTest.php @@ -10,7 +10,9 @@ $exceptionObject = PluginActivationFailure::activationMessage($message); - $this->assertIsObject($exceptionObject, "The {$exceptionObject} should be an instance of PluginActivationFailure class"); - $this->assertObjectHasAttribute('message', $exceptionObject, "Object doesn't contain message attribute"); - $this->assertSame($message, $exceptionObject->getMessage(), "Strings for error activation message do not match!"); + expect($exceptionObject)->toBeObject() + ->toBeInstanceOf(PluginActivationFailure::class) + ->toHaveProperty('message') + ->and($message) + ->toEqual($exceptionObject->getMessage()); }); From 70034dd126c582c6a70849d92098c9d8a556ba82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Ruz=CC=8Cevic=CC=81?= Date: Thu, 26 Oct 2023 09:14:53 +0200 Subject: [PATCH 02/24] changing the commands registration order --- src/Cli/Cli.php | 46 ++++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/src/Cli/Cli.php b/src/Cli/Cli.php index 022af1663..1812c7304 100644 --- a/src/Cli/Cli.php +++ b/src/Cli/Cli.php @@ -13,6 +13,7 @@ use EightshiftLibs\AdminMenus\AdminMenuCli; use EightshiftLibs\AdminMenus\AdminReusableBlocksMenuCli; use EightshiftLibs\AdminMenus\AdminSubMenuCli; +use EightshiftLibs\AdminMenus\ReusableBlocksHeaderFooterCli; use EightshiftLibs\AnalyticsGdpr\AnalyticsGdprCli; use EightshiftLibs\BlockPatterns\BlockPatternCli; use EightshiftLibs\Blocks\BlocksCli; @@ -98,15 +99,19 @@ class Cli AdminMenuCli::class, AdminReusableBlocksMenuCli::class, AdminSubMenuCli::class, - AcfMetaCli::class, + ReusableBlocksHeaderFooterCli::class, AnalyticsGdprCli::class, - EnqueueAdminCli::class, - EnqueueBlocksCli::class, - EnqueueThemeCli::class, - EscapedViewCli::class, + WebPMediaColumnCli::class, ConfigCli::class, + ConfigProjectCli::class, + AcfMetaCli::class, PostTypeCli::class, TaxonomyCli::class, + EnqueueAdminCli::class, + EnqueueBlocksCli::class, + EnqueueThemeCli::class, + GeolocationCli::class, + GitIgnoreCli::class, I18nCli::class, LoginCli::class, MainCli::class, @@ -114,18 +119,15 @@ class Cli MediaCli::class, MenuCli::class, ModifyAdminAppearanceCli::class, + ReadmeCli::class, FieldCli::class, RouteCli::class, + LoadMoreRouteCli::class, ServiceExampleCli::class, - ThemeOptionsCli::class, - ConfigProjectCli::class, - GitIgnoreCli::class, - WebPMediaColumnCli::class, - ReadmeCli::class, SetupCli::class, + ThemeOptionsCli::class, + EscapedViewCli::class, WpCli::class, - GeolocationCli::class, - LoadMoreRouteCli::class, ]; /** @@ -134,10 +136,10 @@ class Cli * @var class-string[] */ public const RUN_COMMANDS = [ - RegenerateWebPMediaCli::class, - UseWebPMediaCli::class, ExportCli::class, ImportCli::class, + RegenerateWebPMediaCli::class, + UseWebPMediaCli::class, PluginManageCli::class, ]; @@ -147,14 +149,14 @@ class Cli * @var class-string[] */ public const BLOCKS_COMMANDS = [ - BlocksCli::class, BlockPatternCli::class, - UseStorybookCli::class, - UseManifestCli::class, + BlocksCli::class, UseAssetsCli::class, - UseGlobalAssetsCli::class, UseBlockCli::class, UseComponentCli::class, + UseGlobalAssetsCli::class, + UseManifestCli::class, + UseStorybookCli::class, UseVariationCli::class, UseWrapperCli::class, ]; @@ -165,12 +167,12 @@ class Cli * @var class-string[] */ public const INIT_COMMANDS = [ - InitThemeCli::class, - InitPluginCli::class, - InitProjectCli::class, - InitBlocksCli::class, InitAllCli::class, + InitBlocksCli::class, InitHeaderFooter::class, + InitPluginCli::class, + InitProjectCli::class, + InitThemeCli::class, ]; /** From 06da106a0e4e3f4a89618512ede67b076892e574 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Ruz=CC=8Cevic=CC=81?= Date: Thu, 26 Oct 2023 09:47:31 +0200 Subject: [PATCH 03/24] addings fixes for php8 --- composer.json | 2 +- phpstan.neon.dist | 1 + src/AdminMenus/AdminReusableBlocksMenuCli.php | 2 +- src/AdminMenus/AdminReusableBlocksMenuExample.php | 2 +- src/AdminMenus/ReusableBlocksHeaderFooterExample.php | 2 +- src/AnalyticsGdpr/AnalyticsGdprExample.php | 2 +- .../ModifyAdminAppearanceExample.php | 2 +- src/Rest/Fields/FieldExample.php | 10 +++++----- src/Rest/Routes/LoadMore/LoadMoreRouteExample.php | 2 +- src/Rest/Routes/RouteExample.php | 2 +- 10 files changed, 14 insertions(+), 13 deletions(-) diff --git a/composer.json b/composer.json index 476aa854a..1a573f03f 100644 --- a/composer.json +++ b/composer.json @@ -41,7 +41,7 @@ "php-stubs/wordpress-stubs": "^6.3", "roave/security-advisories": "dev-master", "szepeviktor/phpstan-wordpress": "^1.0.3", - "wp-cli/wp-cli": "^2.4", + "wp-cli/wp-cli": "^2.9", "yoast/wp-test-utils": "^1.0" }, "autoload": { diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 26ea174b8..758015e47 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -15,3 +15,4 @@ parameters: ignoreErrors: # Ignore errors about reflection class variable being undefined. Errors are caught. - '/^Variable \$reflectionClass might not be defined\.$/' + checkGenericClassInNonGenericObjectType: false diff --git a/src/AdminMenus/AdminReusableBlocksMenuCli.php b/src/AdminMenus/AdminReusableBlocksMenuCli.php index 9bc6dad41..9a8419851 100644 --- a/src/AdminMenus/AdminReusableBlocksMenuCli.php +++ b/src/AdminMenus/AdminReusableBlocksMenuCli.php @@ -50,7 +50,7 @@ public function getDefaultArgs(): array 'title' => 'Reusable blocks', 'menu_title' => 'Reusable blocks', 'capability' => 'edit_posts', - 'menu_icon' => '', // phpcs:ignore + 'menu_icon' => 'dashicons-welcome-widgets-menus', 'menu_position' => 4, ]; } diff --git a/src/AdminMenus/AdminReusableBlocksMenuExample.php b/src/AdminMenus/AdminReusableBlocksMenuExample.php index 9b83ec800..94a9116b9 100644 --- a/src/AdminMenus/AdminReusableBlocksMenuExample.php +++ b/src/AdminMenus/AdminReusableBlocksMenuExample.php @@ -58,7 +58,7 @@ function () { $this->getMenuTitle(), $this->getCapability(), $this->getMenuSlug(), - '', + '', // @phpstan-ignore-line $this->getIcon(), $this->getPosition() ); diff --git a/src/AdminMenus/ReusableBlocksHeaderFooterExample.php b/src/AdminMenus/ReusableBlocksHeaderFooterExample.php index c4f463a2b..5cd7ffefe 100644 --- a/src/AdminMenus/ReusableBlocksHeaderFooterExample.php +++ b/src/AdminMenus/ReusableBlocksHeaderFooterExample.php @@ -34,7 +34,7 @@ class ReusableBlocksHeaderFooterExample extends AbstractAdminMenu /** * Admin icon. */ - public const ADMIN_ICON = ''; // phpcs:ignore + public const ADMIN_ICON = 'dashicons-embed-photo'; /** * Menu position for reusable blocks menu. diff --git a/src/AnalyticsGdpr/AnalyticsGdprExample.php b/src/AnalyticsGdpr/AnalyticsGdprExample.php index 6891a8184..f26095d00 100644 --- a/src/AnalyticsGdpr/AnalyticsGdprExample.php +++ b/src/AnalyticsGdpr/AnalyticsGdprExample.php @@ -836,7 +836,7 @@ public function registerGdprModalSettings(): void /** * Prepare the data for usage inside of the GDPR modal template. * - * @return array Prepared array filled with the data from options page. + * @return array> Prepared array filled with the data from options page. */ public function prepareGdprModalData(): array { diff --git a/src/ModifyAdminAppearance/ModifyAdminAppearanceExample.php b/src/ModifyAdminAppearance/ModifyAdminAppearanceExample.php index c8f2be314..a717a2ecd 100644 --- a/src/ModifyAdminAppearance/ModifyAdminAppearanceExample.php +++ b/src/ModifyAdminAppearance/ModifyAdminAppearanceExample.php @@ -22,7 +22,7 @@ class ModifyAdminAppearanceExample implements ServiceInterface /** * List of admin color schemes. * - * @var array + * @var array */ public const COLOR_SCHEMES = [ 'development' => 'fresh', diff --git a/src/Rest/Fields/FieldExample.php b/src/Rest/Fields/FieldExample.php index cf6f9e6bd..3d4c057a1 100644 --- a/src/Rest/Fields/FieldExample.php +++ b/src/Rest/Fields/FieldExample.php @@ -23,11 +23,11 @@ class FieldExample extends AbstractField implements CallableFieldInterface * * Object(s) the field is being registered to, "post"|"term"|"comment" etc. * - * @return string|array + * @return array */ - protected function getObjectType() + protected function getObjectType(): array { - return '%object_type%'; + return ['%object_type%']; } /** @@ -43,7 +43,7 @@ protected function getFieldName(): string /** * Get callback arguments array * - * @return array Either an array of options for the endpoint, or an array of arrays for multiple methods. + * @return array Either an array of options for the endpoint, or an array of arrays for multiple methods. */ protected function getCallbackArguments(): array { @@ -66,7 +66,7 @@ protected function getCallbackArguments(): array * is already an instance, WP_HTTP_Response, otherwise * returns a new WP_REST_Response instance. */ - public function fieldCallback($postObject, string $attr, object $request, string $objectType) + public function fieldCallback($postObject, string $attr, object $request, string $objectType) // @phpstan-ignore-line { return \rest_ensure_response('output data'); } diff --git a/src/Rest/Routes/LoadMore/LoadMoreRouteExample.php b/src/Rest/Routes/LoadMore/LoadMoreRouteExample.php index 1afefa771..a978c0ac2 100644 --- a/src/Rest/Routes/LoadMore/LoadMoreRouteExample.php +++ b/src/Rest/Routes/LoadMore/LoadMoreRouteExample.php @@ -63,7 +63,7 @@ protected function getRouteName(): string /** * Get callback arguments array * - * @return array Either an array of options for the endpoint or an array of arrays for multiple methods. + * @return array Either an array of options for the endpoint or an array of arrays for multiple methods. */ protected function getCallbackArguments(): array { diff --git a/src/Rest/Routes/RouteExample.php b/src/Rest/Routes/RouteExample.php index f56bf3c81..22ab3dbc9 100644 --- a/src/Rest/Routes/RouteExample.php +++ b/src/Rest/Routes/RouteExample.php @@ -53,7 +53,7 @@ protected function getRouteName(): string /** * Get callback arguments array * - * @return array Either an array of options for the endpoint, or an array of arrays for multiple methods. + * @return array Either an array of options for the endpoint, or an array of arrays for multiple methods. */ protected function getCallbackArguments(): array { From 619669d4a7246f90bce5ebd5348a692a7656841d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Ruz=CC=8Cevic=CC=81?= Date: Thu, 26 Oct 2023 10:35:30 +0200 Subject: [PATCH 04/24] addings fixes for php8 --- src/Init/InitHeaderFooter.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Init/InitHeaderFooter.php b/src/Init/InitHeaderFooter.php index a8fc1073c..f693fccbd 100644 --- a/src/Init/InitHeaderFooter.php +++ b/src/Init/InitHeaderFooter.php @@ -58,6 +58,9 @@ public function getDoc(): array # Setup theme: $ wp {$this->commandParentName} {$this->getCommandParentName()} {$this->getCommandName()} + + Command details can be found here: + https://github.com/infinum/eightshift-libs/blob/develop/src/Init/InitHeaderFooter.php "), ]; } From 2f9f3d7c0aa148c6679e5c562ff0f3fa0df6d6d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Ruz=CC=8Cevic=CC=81?= Date: Thu, 26 Oct 2023 10:45:44 +0200 Subject: [PATCH 05/24] addings fixes for php8 --- src/Geolocation/GeolocationExample.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Geolocation/GeolocationExample.php b/src/Geolocation/GeolocationExample.php index ac5d38fa4..aa7b4c224 100644 --- a/src/Geolocation/GeolocationExample.php +++ b/src/Geolocation/GeolocationExample.php @@ -22,7 +22,7 @@ class GeolocationExample extends AbstractGeolocation */ public function register(): void { - \add_filter('init', [$this, 'setLocationCookie']); + \add_action('init', [$this, 'setLocationCookie']); } /** From 38416458a61735f864a7ab58e9fe0f2e6bba76a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Ru=C5=BEevi=C4=87?= Date: Fri, 27 Oct 2023 13:42:36 +0200 Subject: [PATCH 06/24] Update composer.json MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Denis Žoljom --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 1a573f03f..d3de3a6e5 100644 --- a/composer.json +++ b/composer.json @@ -40,7 +40,7 @@ "php-parallel-lint/php-parallel-lint": "^1.3", "php-stubs/wordpress-stubs": "^6.3", "roave/security-advisories": "dev-master", - "szepeviktor/phpstan-wordpress": "^1.0.3", + "szepeviktor/phpstan-wordpress": "^1.3", "wp-cli/wp-cli": "^2.9", "yoast/wp-test-utils": "^1.0" }, From dcc6c6547e1d34ab24aac9d67412e6ab662244db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Ruz=CC=8Cevic=CC=81?= Date: Fri, 27 Oct 2023 14:35:09 +0200 Subject: [PATCH 07/24] updating tests --- .../ReusableBlocksHeaderFooterExample.php | 2 +- src/Helpers/Components.php | 12 ++++++---- .../Unit/AdminMenus/AdminMenuExampleTest.php | 6 +++++ tests/Unit/Cli/CliTest.php | 2 +- .../Unit/Exception/ComponentExceptionTest.php | 23 +++++++++++++++++++ .../Geolocation/GeolocationExampleTest.php | 2 +- tests/Unit/Rest/Fields/FieldCliTest.php | 4 ++-- 7 files changed, 42 insertions(+), 9 deletions(-) diff --git a/src/AdminMenus/ReusableBlocksHeaderFooterExample.php b/src/AdminMenus/ReusableBlocksHeaderFooterExample.php index 5cd7ffefe..4a5df703f 100644 --- a/src/AdminMenus/ReusableBlocksHeaderFooterExample.php +++ b/src/AdminMenus/ReusableBlocksHeaderFooterExample.php @@ -136,7 +136,7 @@ protected function getMenuSlug(): string */ protected function getIcon(): string { - return 'data:image/svg+xml;base64,' . base64_encode(self::ADMIN_ICON); // phpcs:ignore; + return self::ADMIN_ICON; } /** diff --git a/src/Helpers/Components.php b/src/Helpers/Components.php index 6289d70dd..2da28c992 100644 --- a/src/Helpers/Components.php +++ b/src/Helpers/Components.php @@ -149,8 +149,10 @@ public static function render(string $component, array $attributes = [], string $componentPath = "{$parentPath}{$componentPath}"; // Security check. - if (!\preg_match('(themes|plugins)', $componentPath)) { - throw ComponentException::throwPrivatePath(); + if (!\getenv('ES_TEST')) { + if (!\preg_match('(themes|plugins)', $componentPath)) { + throw ComponentException::throwPrivatePath(); + } } if ($useComponentDefaults) { @@ -242,8 +244,10 @@ public static function renderPartial( } // Security check. - if (!\preg_match('(themes|plugins)', $path)) { - throw ComponentException::throwPrivatePath(); + if (!\getenv('ES_TEST')) { + if (!\preg_match('(themes|plugins)', $path)) { + throw ComponentException::throwPrivatePath(); + } } \ob_start(); diff --git a/tests/Unit/AdminMenus/AdminMenuExampleTest.php b/tests/Unit/AdminMenus/AdminMenuExampleTest.php index 82ac49d8d..d7a223e35 100644 --- a/tests/Unit/AdminMenus/AdminMenuExampleTest.php +++ b/tests/Unit/AdminMenus/AdminMenuExampleTest.php @@ -40,6 +40,12 @@ //---------------------------------------------------------------------------------// test('processAdminMenu will echo component view', function () { + $mock = new class extends AdminMenuExample { + protected function getViewComponent(): string + { + return 'themes/missing'; + } + }; buildTestBlocks(); diff --git a/tests/Unit/Cli/CliTest.php b/tests/Unit/Cli/CliTest.php index b9c7b9f7c..0fac57cc3 100644 --- a/tests/Unit/Cli/CliTest.php +++ b/tests/Unit/Cli/CliTest.php @@ -26,7 +26,7 @@ ->not->toHaveKey(CliShowAll::class) ->and(\count($publicClasses)) ->toBeInt() - ->toBe(52); + ->toBe(53); // Public classes count. }); diff --git a/tests/Unit/Exception/ComponentExceptionTest.php b/tests/Unit/Exception/ComponentExceptionTest.php index a569fabd5..a83417a90 100644 --- a/tests/Unit/Exception/ComponentExceptionTest.php +++ b/tests/Unit/Exception/ComponentExceptionTest.php @@ -43,3 +43,26 @@ function () { ->and("Unable to locate component by path: {$component}") ->toEqual($output->getMessage()); }); + +test('Checks if throwUnableToLocatePartial method will return correct response.', function () { + + $path = 'nonexistent'; + $output = ComponentException::throwUnableToLocatePartial($path); + + expect($output)->toBeObject() + ->toBeInstanceOf(ComponentException::class) + ->toHaveProperty('message') + ->and("Unable to locate partial on this path: {$path}") + ->toEqual($output->getMessage()); +}); + +test('Checks if throwPrivatePath method will return correct response.', function () { + + $output = ComponentException::throwPrivatePath(); + + expect($output)->toBeObject() + ->toBeInstanceOf(ComponentException::class) + ->toHaveProperty('message') + ->and('You are not allowed to access paths outside of themes or plugins folder!') + ->toEqual($output->getMessage()); +}); diff --git a/tests/Unit/Geolocation/GeolocationExampleTest.php b/tests/Unit/Geolocation/GeolocationExampleTest.php index 4ddb20e9f..bd57c33ce 100644 --- a/tests/Unit/Geolocation/GeolocationExampleTest.php +++ b/tests/Unit/Geolocation/GeolocationExampleTest.php @@ -13,7 +13,7 @@ $this->geolocation->register(); expect(\method_exists($this->geolocation, 'register'))->toBeTrue(); - expect(\has_filter('init', [$this->geolocation, 'setLocationCookie']))->toBe(10); + expect(\has_action('init', [$this->geolocation, 'setLocationCookie']))->toBe(10); }); test('getGeolocationCookieName will return correct cookie name', function () { diff --git a/tests/Unit/Rest/Fields/FieldCliTest.php b/tests/Unit/Rest/Fields/FieldCliTest.php index b2924d8e3..edd9d45c7 100644 --- a/tests/Unit/Rest/Fields/FieldCliTest.php +++ b/tests/Unit/Rest/Fields/FieldCliTest.php @@ -22,7 +22,7 @@ $this->assertStringContainsString('class TitleCustomField extends AbstractField implements CallableFieldInterface', $output); $this->assertStringContainsString('return \'title-custom\';', $output); - $this->assertStringContainsString('return \'example\';', $output); + $this->assertStringContainsString('return [\'example\'];', $output); $this->assertStringContainsString('get_callback', $output); $this->assertStringContainsString('rest_ensure_response', $output); $this->assertStringNotContainsString('ExampleRoute', $output); @@ -39,7 +39,7 @@ $output = \file_get_contents(Components::getProjectPaths('cliOutput', "src{$sep}Rest{$sep}Fields{$sep}{$fullFieldName}.php")); $this->assertStringContainsString("class {$fullFieldName} extends AbstractField implements CallableFieldInterface", $output); - $this->assertStringContainsString("return '{$objectType}';", $output); + $this->assertStringContainsString("return ['{$objectType}'];", $output); $this->assertStringNotContainsString('example-post-type', $output); $this->assertStringNotContainsString('example-field', $output); })->with('correctFieldNameArguments'); From 658036940f9e7bff7acaabb1664b2159ca124281 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Ruz=CC=8Cevic=CC=81?= Date: Fri, 27 Oct 2023 14:36:07 +0200 Subject: [PATCH 08/24] updating tests --- .github/workflows/integrate.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/integrate.yml b/.github/workflows/integrate.yml index b63f2f470..7d94396d8 100644 --- a/.github/workflows/integrate.yml +++ b/.github/workflows/integrate.yml @@ -65,9 +65,7 @@ jobs: matrix: php-version: ["7.4", "8.0", "8.1", "8.2"] dependencies: - - "lowest" - "highest" - allowed_failure: [ false ] # Allow failure on non-released version of PHP. include: - php: "8.1" From 7d8c23fde7778b861141e8dbf5fe5d01976e18d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Ruz=CC=8Cevic=CC=81?= Date: Fri, 27 Oct 2023 14:38:58 +0200 Subject: [PATCH 09/24] updating tests --- src/Rest/CallableRouteInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Rest/CallableRouteInterface.php b/src/Rest/CallableRouteInterface.php index 4cf7739df..d459b6790 100644 --- a/src/Rest/CallableRouteInterface.php +++ b/src/Rest/CallableRouteInterface.php @@ -26,5 +26,5 @@ interface CallableRouteInterface * is already an instance, WP_HTTP_Response, otherwise * returns a new WP_REST_Response instance. */ - public function routeCallback(WP_REST_Request $request); // @phpstan-ignore-line + public function routeCallback(WP_REST_Request $request); } From 2fef3b551231d1225ce0ec70315db59aa41eff9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Ruz=CC=8Cevic=CC=81?= Date: Fri, 27 Oct 2023 14:41:50 +0200 Subject: [PATCH 10/24] updating tests --- .github/workflows/integrate.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/.github/workflows/integrate.yml b/.github/workflows/integrate.yml index 7d94396d8..8d0d8c803 100644 --- a/.github/workflows/integrate.yml +++ b/.github/workflows/integrate.yml @@ -66,16 +66,6 @@ jobs: php-version: ["7.4", "8.0", "8.1", "8.2"] dependencies: - "highest" - # Allow failure on non-released version of PHP. - include: - - php: "8.1" - dependencies: "lowest" - allowed_failure: true - - php: "8.2" - dependencies: "lowest" - allowed_failure: true - - php: "8.3" - allowed_failure: true runs-on: "ubuntu-latest" continue-on-error: ${{ matrix.allowed_failure }} steps: From 7776018f5e86b779088e5267882e623e8b63ba52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Ruz=CC=8Cevic=CC=81?= Date: Fri, 27 Oct 2023 14:45:59 +0200 Subject: [PATCH 11/24] updating tests --- .github/workflows/integrate.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/integrate.yml b/.github/workflows/integrate.yml index 8d0d8c803..de8c9efe3 100644 --- a/.github/workflows/integrate.yml +++ b/.github/workflows/integrate.yml @@ -67,7 +67,6 @@ jobs: dependencies: - "highest" runs-on: "ubuntu-latest" - continue-on-error: ${{ matrix.allowed_failure }} steps: - name: "Set up PHP" uses: "shivammathur/setup-php@v2" From d84ce12a030e182adb7f4587ebb3ccd66e9b8cc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Ruz=CC=8Cevic=CC=81?= Date: Fri, 27 Oct 2023 15:21:19 +0200 Subject: [PATCH 12/24] removing 'Old' function in blocks --- src/Blocks/AbstractBlocks.php | 59 ---------------------- src/Blocks/BlocksExample.php | 6 +-- tests/Unit/Blocks/BlocksExampleTest.php | 66 ------------------------- 3 files changed, 1 insertion(+), 130 deletions(-) diff --git a/src/Blocks/AbstractBlocks.php b/src/Blocks/AbstractBlocks.php index db1b10e2c..da35b2547 100644 --- a/src/Blocks/AbstractBlocks.php +++ b/src/Blocks/AbstractBlocks.php @@ -153,39 +153,6 @@ public function getAllBlocksList($allowedBlockTypes, WP_Block_Editor_Context $bl return $this->getAllAllowedBlocksList([], $blockEditorContext); } - /** - * Get all blocks with full block name - legacy. - * - * Used to limit what blocks are going to be used in your project using allowed_block_types filter. - * - * @hook allowed_block_types This is a WP 5 - WP 5.7 compatible hook callback. Will not work with WP 5.8! - * - * @param bool|string[] $allowedBlockTypes Array of block type slugs, or boolean to enable/disable all. - * @param WP_Post $post The post resource data. - * - * @return bool|string[] Boolean if you want to disallow or allow all blocks, or a list of allowed blocks. - */ - public function getAllBlocksListOld($allowedBlockTypes, WP_Post $post) - { - if (\gettype($allowedBlockTypes) === 'boolean') { - return $allowedBlockTypes; - } - - $allowedBlockTypes = \array_map( - function ($block) { - return $block['blockFullName']; - }, - Components::getBlocks() - ); - - // Allow reusable block. - $allowedBlockTypes[] = 'eightshift-forms/forms'; - $allowedBlockTypes[] = 'core/block'; - $allowedBlockTypes[] = 'core/template'; - - return $allowedBlockTypes; - } - /** * Method used to register all custom blocks with data fetched from blocks manifest.json. * @@ -274,32 +241,6 @@ public function getCustomCategory(array $categories, WP_Block_Editor_Context $bl ); } - /** - * Create custom category to assign all custom blocks - legacy. - * - * This category will be shown on all blocks list in "Add Block" button. - * - * @hook block_categories This is a WP 5 - WP 5.7 compatible hook callback. Will not work with WP 5.8! - * - * @param array> $categories Array of categories for block types. - * @param WP_Post $post Post being loaded. - * - * @return array> Array of categories for block types. - */ - public function getCustomCategoryOld(array $categories, WP_Post $post): array - { - return \array_merge( - $categories, - [ - [ - 'slug' => 'eightshift', - 'title' => \esc_html__('Eightshift', 'eightshift-libs'), - 'icon' => 'admin-settings', - ], - ] - ); - } - /** * Locate and return template part with passed attributes for wrapper. * diff --git a/src/Blocks/BlocksExample.php b/src/Blocks/BlocksExample.php index 81a358002..35f5bcaa9 100644 --- a/src/Blocks/BlocksExample.php +++ b/src/Blocks/BlocksExample.php @@ -33,11 +33,7 @@ public function register(): void \remove_filter('the_content', 'wpautop'); // Create new custom category for custom blocks. - if (\is_wp_version_compatible('5.8')) { - \add_filter('block_categories_all', [$this, 'getCustomCategory'], 10, 2); - } else { - \add_filter('block_categories', [$this, 'getCustomCategoryOld'], 10, 2); - } + \add_filter('block_categories_all', [$this, 'getCustomCategory'], 10, 2); // Register custom theme support options. \add_action('after_setup_theme', [$this, 'addThemeSupport'], 25); diff --git a/tests/Unit/Blocks/BlocksExampleTest.php b/tests/Unit/Blocks/BlocksExampleTest.php index c45e45add..8850c5c73 100644 --- a/tests/Unit/Blocks/BlocksExampleTest.php +++ b/tests/Unit/Blocks/BlocksExampleTest.php @@ -42,48 +42,6 @@ expect(\getenv('ALIGN_WIDE'))->toBe('true'); }); -test('Asserts that getAllBlocksListOld first argument is boolean and return the provided attribute as return value for older WP versions.', function () { - - Functions\when('is_wp_version_compatible')->justReturn(false); - - $post = mock('WP_Post'); - - $blocks = $this->mock->getAllBlocksListOld(true, $post); - - expect($blocks)->toBeTrue(); - - $blocks = $this->mock->getAllBlocksListOld(false, $post); - - expect($blocks)->toBeFalse(); -}); - -test('Asserts that getAllBlocksListOld will return only projects blocks for older WP versions.', function () { - - Functions\when('is_wp_version_compatible')->justReturn(false); - - $post = mock(\WP_Post::class); - - buildTestBlocks(); - - $list = $this->mock->getAllBlocksListOld([], $post); - - expect($list) - ->toBeArray() - ->not->toContain('core/paragraph') - ->toContain('eightshift-boilerplate/button', 'core/block', 'core/template'); -}); - - -test('Asserts that getAllBlocksList with all types of arguments throw error for older WP versions.', function ($argument) { - - Functions\when('is_wp_version_compatible')->justReturn(false); - - $post = mock('WP_Post'); - - $this->mock->getAllBlocksList($argument, $post); -})->throws(\TypeError::class) -->with('getAllAllowedBlocksListAllTypesArguments'); - test('Asserts that getAllBlocksList is not influenced by the first parameter', function ($argument) { $blockContext = mock(WP_Block_Editor_Context::class); @@ -146,16 +104,6 @@ ->toContain('test', 'eightshift-boilerplate/button', 'core/block', 'core/template'); }); -test('Asserts that getAllAllowedBlocksList with all types of arguments throw error for older WP versions.', function ($argument) { - - Functions\when('is_wp_version_compatible')->justReturn(false); - - $post = mock('WP_Post'); - - $this->mock->getAllAllowedBlocksList($argument, $post); -})->throws(\TypeError::class) -->with('getAllAllowedBlocksListAllTypesArguments'); - test('Asserts that getAllAllowedBlocksList will return projects blocks and passed blocks for WP 5.8.', function () { $blockContext = mock(WP_Block_Editor_Context::class); $blockContext->post = null; @@ -293,20 +241,6 @@ expect(\getenv('BLOCK_TYPE'))->toBe('true'); }); -test('getCustomCategoryOld method will return an array.', function () { - $post = mock('WP_Post'); - - $categoryList = $this->mock->getCustomCategoryOld([], $post); - - expect($categoryList)->toBeArray(); - - expect($categoryList[0]) - ->toBeArray() - ->toHaveKey('slug') - ->toHaveKey('title') - ->toHaveKey('icon'); -}); - test('filterBlocksContent method will return an array.', function () { $parsedBlock = [ From be389feaa99e23b3943d07cb3b4186c7cd8e44bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Ruz=CC=8Cevic=CC=81?= Date: Fri, 27 Oct 2023 23:25:41 +0200 Subject: [PATCH 13/24] changing config version and name definition --- composer.json | 2 +- src/Cli/AbstractCli.php | 21 +++++++++++++++++++++ src/Config/ConfigCli.php | 26 -------------------------- src/Config/ConfigExample.php | 4 ++-- src/Init/InitThemeCli.php | 27 +++++++++++++++++++++++++++ tests/BaseTest.php | 7 +++++++ 6 files changed, 58 insertions(+), 29 deletions(-) diff --git a/composer.json b/composer.json index d3de3a6e5..ca63db773 100644 --- a/composer.json +++ b/composer.json @@ -28,7 +28,7 @@ "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", - "php-di/invoker": "^2.3", + "php-di/invoker": "^2.3.4", "php-di/php-di": "^7" }, "require-dev": { diff --git a/src/Cli/AbstractCli.php b/src/Cli/AbstractCli.php index e38b0ad03..d0a5f57c9 100644 --- a/src/Cli/AbstractCli.php +++ b/src/Cli/AbstractCli.php @@ -57,6 +57,27 @@ abstract class AbstractCli implements CliInterface */ public const TEMPLATE = ''; + /** + * Output project name arg. + * + * @var string + */ + public const PROJECT_NAME_ARG = 'project_name'; + + /** + * Output theme name arg. + * + * @var string + */ + public const THEME_NAME_ARG = 'theme_name'; + + /** + * Output plugin name arg. + * + * @var string + */ + public const PLUGIN_NAME_ARG = 'plugin_name'; + /** * Construct Method. * diff --git a/src/Config/ConfigCli.php b/src/Config/ConfigCli.php index 850a2ada6..c3920b57b 100644 --- a/src/Config/ConfigCli.php +++ b/src/Config/ConfigCli.php @@ -47,8 +47,6 @@ public function getCommandName(): string public function getDefaultArgs(): array { return [ - 'name' => 'Boilerplate', - 'version' => '1', 'routes_version' => '1', ]; } @@ -63,20 +61,6 @@ public function getDoc(): array return [ 'shortdesc' => 'Create project config service class.', 'synopsis' => [ - [ - 'type' => 'assoc', - 'name' => 'name', - 'description' => 'Define project name.', - 'optional' => true, - 'default' => $this->getDefaultArg('name'), - ], - [ - 'type' => 'assoc', - 'name' => 'version', - 'description' => 'Define project version.', - 'optional' => true, - 'default' => $this->getDefaultArg('version'), - ], [ 'type' => 'assoc', 'name' => 'routes_version', @@ -109,8 +93,6 @@ public function __invoke(array $args, array $assocArgs) $this->getIntroText($assocArgs); // Get Props. - $name = $this->getArg($assocArgs, 'name'); - $version = $this->getArg($assocArgs, 'version'); $routesVersion = $this->getArg($assocArgs, 'routes_version'); $className = $this->getClassShortName(); @@ -121,14 +103,6 @@ public function __invoke(array $args, array $assocArgs) ->renameNamespace($assocArgs) ->renameUse($assocArgs); - if (!empty($name)) { - $class->searchReplaceString($this->getArgTemplate('name'), $name); - } - - if (!empty($version)) { - $class->searchReplaceString($this->getArgTemplate('version'), $version); - } - if (!empty($routesVersion)) { $class->searchReplaceString($this->getArgTemplate('routes_version'), $routesVersion); } diff --git a/src/Config/ConfigExample.php b/src/Config/ConfigExample.php index 047c3e22a..c4bb760de 100644 --- a/src/Config/ConfigExample.php +++ b/src/Config/ConfigExample.php @@ -27,7 +27,7 @@ class ConfigExample extends AbstractConfigData */ public static function getProjectName(): string { - return '%name%'; + return \wp_get_theme('', \dirname(__DIR__, 3))->get('TextDomain'); } /** @@ -37,7 +37,7 @@ public static function getProjectName(): string */ public static function getProjectVersion(): string { - return '%version%'; + return \wp_get_theme('', \dirname(__DIR__, 3))->get('Version'); } /** diff --git a/src/Init/InitThemeCli.php b/src/Init/InitThemeCli.php index 5521ba18a..d974c1bc4 100644 --- a/src/Init/InitThemeCli.php +++ b/src/Init/InitThemeCli.php @@ -76,6 +76,18 @@ public function getCommandName(): string return 'theme'; } + /** + * Define default arguments. + * + * @return array + */ + public function getDefaultArgs(): array + { + return [ + AbstractCli::THEME_NAME_ARG => 'Boilerplate', + ]; + } + /** * Get WP-CLI command doc. * @@ -85,6 +97,15 @@ public function getDoc(): array { return [ 'shortdesc' => 'Kickstart your WordPress theme with this simple command.', + 'synopsis' => [ + [ + 'type' => 'assoc', + 'name' => AbstractCli::THEME_NAME_ARG, + 'description' => 'Define theme name.', + 'optional' => true, + 'default' => $this->getDefaultArg(AbstractCli::THEME_NAME_ARG), + ], + ], 'longdesc' => $this->prepareLongDesc(" ## USAGE @@ -107,6 +128,11 @@ public function __invoke(array $args, array $assocArgs) $this->getIntroText(); } + $themeName = $this->getArg($assocArgs, AbstractCli::THEME_NAME_ARG); + if ($themeName) { + unset($assocArgs[AbstractCli::THEME_NAME_ARG]); + } + foreach (static::COMMANDS as $item) { $label = $item['label'] ?? ''; $items = $item['items'] ?? []; @@ -126,6 +152,7 @@ public function __invoke(array $args, array $assocArgs) [ 'groupOutput' => $type === 'blocks', 'introOutput' => false, + AbstractCli::PROJECT_NAME_ARG => $themeName, ] )); } diff --git a/tests/BaseTest.php b/tests/BaseTest.php index 6d26436ad..1de552add 100644 --- a/tests/BaseTest.php +++ b/tests/BaseTest.php @@ -9,6 +9,7 @@ use Mockery\MockInterface; use RecursiveDirectoryIterator; use RecursiveIteratorIterator; +use WP_Theme; use Yoast\WPTestUtils\BrainMonkey\TestCase; class BaseTest extends TestCase @@ -192,6 +193,12 @@ protected function set_up() Functions\when('wp_nonce_field')->justReturn('nonce'); + Functions\when('wp_get_theme')->justReturn(new class { + public function get( $header ) { + return 'test'; + } + }); + // Mock https://developer.wordpress.org/reference/functions/wp_is_json_media_type/ function Functions\when('wp_is_json_media_type')->alias(function ($mediaType) { static $cache = array(); From a61ed51ea70961f5d08cadbfe7e3248c38cf95e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Ruz=CC=8Cevic=CC=81?= Date: Fri, 27 Oct 2023 23:34:39 +0200 Subject: [PATCH 14/24] removing storybook --- src/Blocks/UseStorybookCli.php | 117 ------------------ src/Cli/AbstractCli.php | 1 - src/Cli/Cli.php | 2 - src/Helpers/Components.php | 17 --- src/Init/InitBlocksCli.php | 2 - tests/Unit/Blocks/BlocksStorybookCliTest.php | 27 ---- tests/Unit/Cli/AbstractCliTest.php | 1 - tests/Unit/Cli/CliTest.php | 2 +- .../src/Blocks/custom/button/docs/readme.mdx | 16 --- .../src/Blocks/custom/button/docs/story.js | 18 --- tests/data/storybook/storybook.php | 2 - 11 files changed, 1 insertion(+), 204 deletions(-) delete mode 100644 src/Blocks/UseStorybookCli.php delete mode 100644 tests/Unit/Blocks/BlocksStorybookCliTest.php delete mode 100644 tests/data/src/Blocks/custom/button/docs/readme.mdx delete mode 100644 tests/data/src/Blocks/custom/button/docs/story.js delete mode 100644 tests/data/storybook/storybook.php diff --git a/src/Blocks/UseStorybookCli.php b/src/Blocks/UseStorybookCli.php deleted file mode 100644 index 1d3740da4..000000000 --- a/src/Blocks/UseStorybookCli.php +++ /dev/null @@ -1,117 +0,0 @@ ->|string> - */ - public function getDoc(): array - { - return [ - 'shortdesc' => 'Copy storybook config from our library to your project.', - 'longdesc' => $this->prepareLongDesc(" - ## USAGE - - Used to copy all configuration files to your project needed to run Storybook. - - ## INSTALATION - - After you run the cli command please follow these steps: - {$this->getCommonAfterIntallInstructions()} - - ## EXAMPLES - - # Create Storybook config: - $ wp {$this->commandParentName} {$this->getCommandParentName()} {$this->getCommandName()} - - ## RESOURCES - - Storybook config will be created from this folder: - https://github.com/infinum/eightshift-frontend-libs/tree/develop/blocks/init/storybook - "), - ]; - } - - /* @phpstan-ignore-next-line */ - public function __invoke(array $args, array $assocArgs) - { - $this->getIntroText($assocArgs); - - $groupOutput = $assocArgs['groupOutput'] ?? false; - - $this->moveItems( - \array_merge( - $assocArgs, - [ - 'name' => 'storybook', - ], - ), - Components::getProjectPaths('blocksStorybookSource'), - Components::getProjectPaths('blocksStorybookDestination'), - 'storybook folder', - true - ); - - if (!$groupOutput) { - WP_CLI::log('--------------------------------------------------'); - - $this->cliLog('Please follow these steps to complete your Storybook setup:', 'M'); - $this->cliLog($this->prepareLongDesc($this->getCommonAfterIntallInstructions()), 'M'); - } - } - - /** - * Common instalation steps. - * - * @return string - */ - private function getCommonAfterIntallInstructions(): string - { - return ' - 1. Run `npm install @eightshift/storybook --save-dev` command in the terminal to install the storybook package. - 2. Open package.json. - 3. Add to scripts: `"storybookBuild": "build-storybook -s public -o storybook"` - 4. Add to scripts: `"storybook": "start-storybook -s public"` - 5. Start storybook by running this command `npm run storybook`. - '; - } -} diff --git a/src/Cli/AbstractCli.php b/src/Cli/AbstractCli.php index d0a5f57c9..58f79aa08 100644 --- a/src/Cli/AbstractCli.php +++ b/src/Cli/AbstractCli.php @@ -815,7 +815,6 @@ public function getFullBlocksFiles(string $name): array "{$name}-hooks.js", "{$name}-transforms.js", "{$name}.js", - "docs{$ds}story.js", "components{$ds}{$name}-editor.js", "components{$ds}{$name}-toolbar.js", "components{$ds}{$name}-options.js", diff --git a/src/Cli/Cli.php b/src/Cli/Cli.php index 1812c7304..76c0e6fdc 100644 --- a/src/Cli/Cli.php +++ b/src/Cli/Cli.php @@ -22,7 +22,6 @@ use EightshiftLibs\Blocks\UseAssetsCli; use EightshiftLibs\Blocks\UseGlobalAssetsCli; use EightshiftLibs\Blocks\UseManifestCli; -use EightshiftLibs\Blocks\UseStorybookCli; use EightshiftLibs\Blocks\UseVariationCli; use EightshiftLibs\Blocks\UseWrapperCli; use EightshiftLibs\Cli\ParentGroups\CliBoilerplate; @@ -156,7 +155,6 @@ class Cli UseComponentCli::class, UseGlobalAssetsCli::class, UseManifestCli::class, - UseStorybookCli::class, UseVariationCli::class, UseWrapperCli::class, ]; diff --git a/src/Helpers/Components.php b/src/Helpers/Components.php index 2da28c992..6802c307b 100644 --- a/src/Helpers/Components.php +++ b/src/Helpers/Components.php @@ -76,7 +76,6 @@ class Components 'blocksGlobalAssetsSource', 'blocksAssetsSource', - 'blocksStorybookSource', 'blocksSource', 'blocksSourceCustom', 'blocksSourceComponents', @@ -85,7 +84,6 @@ class Components 'blocksGlobalAssetsDestination', 'blocksAssetsDestination', - 'blocksStorybookDestination', 'blocksDestination', 'blocksDestinationCustom', 'blocksDestinationComponents', @@ -361,7 +359,6 @@ public static function getProjectPaths(string $type = '', string $suffix = '', s $testsDataPath = ["tests", "data"]; $srcPath = "src"; $blocksPath = [$srcPath, "Blocks"]; - $storybookPath = "storybook"; $assetsPath = "assets"; $cliOutputPath = "cliOutput"; @@ -426,13 +423,6 @@ public static function getProjectPaths(string $type = '', string $suffix = '', s $path = self::joinPaths([...$testsDataPath, ...$blocksPath, $assetsPath]); } break; - case 'blocksStorybookSource': - $path = self::joinPaths([...$flibsPath, $storybookPath]); - - if (\getenv('ES_TEST')) { - $path = self::joinPaths([...$testsDataPath, $storybookPath]); - } - break; case 'blocksSource': $path = self::joinPaths([...$flibsPath, ...$blocksPath]); @@ -481,13 +471,6 @@ public static function getProjectPaths(string $type = '', string $suffix = '', s $path = self::joinPaths([$cliOutputPath, ...$blocksPath, $assetsPath]); } break; - case 'blocksStorybookDestination': - $path = self::joinPaths([".{$storybookPath}"]); - - if (\getenv('ES_TEST')) { - $path = self::joinPaths([$cliOutputPath, ".{$storybookPath}"]); - } - break; case 'blocksDestination': $path = self::joinPaths($blocksPath); diff --git a/src/Init/InitBlocksCli.php b/src/Init/InitBlocksCli.php index a342af271..fdc52ec20 100644 --- a/src/Init/InitBlocksCli.php +++ b/src/Init/InitBlocksCli.php @@ -16,7 +16,6 @@ use EightshiftLibs\Blocks\UseComponentCli; use EightshiftLibs\Blocks\UseGlobalAssetsCli; use EightshiftLibs\Blocks\UseManifestCli; -use EightshiftLibs\Blocks\UseStorybookCli; use EightshiftLibs\Blocks\UseVariationCli; use EightshiftLibs\Blocks\UseWrapperCli; use EightshiftLibs\Cli\AbstractCli; @@ -35,7 +34,6 @@ class InitBlocksCli extends AbstractCli public const COMMANDS = [ BlocksCli::class => [], UseAssetsCli::class => [], - UseStorybookCli::class => [], UseGlobalAssetsCli::class => [], UseWrapperCli::class => [], UseManifestCli::class => [], diff --git a/tests/Unit/Blocks/BlocksStorybookCliTest.php b/tests/Unit/Blocks/BlocksStorybookCliTest.php deleted file mode 100644 index c1a59285a..000000000 --- a/tests/Unit/Blocks/BlocksStorybookCliTest.php +++ /dev/null @@ -1,27 +0,0 @@ -mock = new UseStorybookCli('boilerplate'); -}); - -afterEach(function () { - unset($this->mock); -}); - -test('Storybook CLI command will correctly copy the Storybook class with defaults', function () { - $mock = $this->mock; - $mock([], []); - - $output = \file_get_contents(Components::getProjectPaths('blocksStorybookDestination', 'storybook.php')); - - expect($output)->toContain('Storybook example file'); -}); - -test('Storybook CLI documentation is correct', function () { - expect($this->mock->getDoc())->toBeArray(); -}); diff --git a/tests/Unit/Cli/AbstractCliTest.php b/tests/Unit/Cli/AbstractCliTest.php index f181ef386..3894949ec 100644 --- a/tests/Unit/Cli/AbstractCliTest.php +++ b/tests/Unit/Cli/AbstractCliTest.php @@ -130,7 +130,6 @@ public function getCommandName(): string $this->assertTrue(\array_key_exists('button-hooks.js', \array_flip($output)), 'button-hooks.js is missing.'); $this->assertTrue(\array_key_exists('button-transforms.js', \array_flip($output)), 'button-transforms.js is missing.'); $this->assertTrue(\array_key_exists('button.js', \array_flip($output)), 'button.js is missing.'); - $this->assertTrue(\array_key_exists('docs/story.js', \array_flip($output)), 'docs/story.js is missing.'); $this->assertTrue(\array_key_exists('components/button-editor.js', \array_flip($output)), 'components/button-editor.js is missing.'); $this->assertTrue(\array_key_exists('components/button-toolbar.js', \array_flip($output)), 'components/button-toolbar.js is missing.'); $this->assertTrue(\array_key_exists('components/button-options.js', \array_flip($output)), 'components/button-options.js is missing.'); diff --git a/tests/Unit/Cli/CliTest.php b/tests/Unit/Cli/CliTest.php index 0fac57cc3..b9c7b9f7c 100644 --- a/tests/Unit/Cli/CliTest.php +++ b/tests/Unit/Cli/CliTest.php @@ -26,7 +26,7 @@ ->not->toHaveKey(CliShowAll::class) ->and(\count($publicClasses)) ->toBeInt() - ->toBe(53); + ->toBe(52); // Public classes count. }); diff --git a/tests/data/src/Blocks/custom/button/docs/readme.mdx b/tests/data/src/Blocks/custom/button/docs/readme.mdx deleted file mode 100644 index 243e38bbb..000000000 --- a/tests/data/src/Blocks/custom/button/docs/readme.mdx +++ /dev/null @@ -1,16 +0,0 @@ -# Button Block - -Block used to provide button functionality to your project. - -## Dependencies - -1. components/button - -## Implementation - -Open a terminal and type in this command inside your projects root: - -```shell -wp boilerplate use_block --name=button -wp boilerplate use_component --name=button -``` diff --git a/tests/data/src/Blocks/custom/button/docs/story.js b/tests/data/src/Blocks/custom/button/docs/story.js deleted file mode 100644 index 9b4819389..000000000 --- a/tests/data/src/Blocks/custom/button/docs/story.js +++ /dev/null @@ -1,18 +0,0 @@ -import React from 'react'; -import { Gutenberg, blockDetails } from '@eightshift/frontend-libs/scripts/storybook'; -import manifest from './../manifest.json'; -import globalManifest from './../../../manifest.json'; -import readme from './readme.mdx'; - -export default { - title: `Blocks/${manifest.title}`, - parameters: { - docs: { - page: readme - } - }, -}; - -export const block = () => ( - -); diff --git a/tests/data/storybook/storybook.php b/tests/data/storybook/storybook.php deleted file mode 100644 index c6ff23209..000000000 --- a/tests/data/storybook/storybook.php +++ /dev/null @@ -1,2 +0,0 @@ - Date: Fri, 27 Oct 2023 23:45:19 +0200 Subject: [PATCH 15/24] fixing missing frontend libs private dir --- src/Blocks/AbstractBlocksCli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Blocks/AbstractBlocksCli.php b/src/Blocks/AbstractBlocksCli.php index 6e2bbdbaa..a1c901d45 100644 --- a/src/Blocks/AbstractBlocksCli.php +++ b/src/Blocks/AbstractBlocksCli.php @@ -67,7 +67,7 @@ protected function moveItems(array $args, string $source, string $destination, s $sourceItems = \array_fill_keys(\array_values($sourceItems), $source); $sourceItemsPrivate = []; - if ($sourcePrivate) { + if (\is_dir($sourcePrivate)) { $sourceItemsPrivate = \array_diff(\scandir($sourcePrivate) ?: [], ['..', '.']); // phpcs:ignore WordPress.PHP.DisallowShortTernary.Found $sourceItemsPrivate = \array_fill_keys(\array_values($sourceItemsPrivate), $sourcePrivate); } From 1d3d3688441fb60f075b086576366e6307102ce0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Ruz=CC=8Cevic=CC=81?= Date: Sat, 28 Oct 2023 00:08:45 +0200 Subject: [PATCH 16/24] fixing wrong block dependeny output --- src/Blocks/AbstractBlocksCli.php | 37 +++++++++++++++++++++++--------- src/Blocks/UseBlockCli.php | 9 +++++++- 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/Blocks/AbstractBlocksCli.php b/src/Blocks/AbstractBlocksCli.php index a1c901d45..98bf18099 100644 --- a/src/Blocks/AbstractBlocksCli.php +++ b/src/Blocks/AbstractBlocksCli.php @@ -232,17 +232,34 @@ private function outputDependencyItems(string $source, string $type): void if ($dependencies) { $componentsCommandName = UseComponentCli::COMMAND_NAME; - $allDependencies = \array_map(static fn ($item) => Components::camelToKebabCase($item), $dependencies); - $allDependencies = \implode(', ', \array_unique(\array_values($allDependencies))); + $blocksCommandName = UseBlockCli::COMMAND_NAME; - $this->cliLogAlert(\implode("\n", [ - "This {$type} may need some dependencies to work correctly.", - '', - 'To add them to your project, run:', - "%Uwp boilerplate {$this->getCommandParentName()} {$componentsCommandName} --name='{$allDependencies}'%n", - '', - 'If a dependency already exists in your project, you can skip it.', - ]), 'info', 'Dependencies found'); + $outputComand = []; + + if ($componentsDependencies) { + $componentsDependenciesAll = \array_map(static fn ($item) => Components::camelToKebabCase($item), $componentsDependencies); + $componentsDependenciesAll = \implode(', ', \array_unique(\array_values($componentsDependenciesAll))); + + $outputComand[] = "%Uwp boilerplate {$this->getCommandParentName()} {$componentsCommandName} --name='{$componentsDependenciesAll}'%n"; + } + + if ($innerBlocksDependency) { + $innerBlocksDependencyAll = \array_map(static fn ($item) => Components::camelToKebabCase($item), $innerBlocksDependency); + $innerBlocksDependencyAll = \implode(', ', \array_unique(\array_values($innerBlocksDependencyAll))); + + $outputComand[] = "%Uwp boilerplate {$this->getCommandParentName()} {$blocksCommandName} --name='{$innerBlocksDependencyAll}'%n"; + } + + if ($outputComand) { + $this->cliLogAlert(\implode("\n", [ + "This {$type} may need some dependencies to work correctly.", + '', + 'To add them to your project, run:', + ...$outputComand, + '', + 'If a dependency already exists in your project, you can skip it.', + ]), 'info', 'Dependencies found'); + } } } diff --git a/src/Blocks/UseBlockCli.php b/src/Blocks/UseBlockCli.php index 17556032d..bea3ebef3 100644 --- a/src/Blocks/UseBlockCli.php +++ b/src/Blocks/UseBlockCli.php @@ -18,6 +18,13 @@ */ class UseBlockCli extends AbstractBlocksCli { + /** + * Command name. + * + * @var string + */ + public const COMMAND_NAME = 'use-block'; + /** * Get WPCLI command parent name * @@ -35,7 +42,7 @@ public function getCommandParentName(): string */ public function getCommandName(): string { - return 'use-block'; + return self::COMMAND_NAME; } /** From 841855902d191fa3f619e826c24b502f122b9981 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Ruz=CC=8Cevic=CC=81?= Date: Sat, 28 Oct 2023 01:04:05 +0200 Subject: [PATCH 17/24] fixing command examples --- src/Cli/ParentGroups/CliCreate.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Cli/ParentGroups/CliCreate.php b/src/Cli/ParentGroups/CliCreate.php index 2139dd6cd..a31f17bbe 100644 --- a/src/Cli/ParentGroups/CliCreate.php +++ b/src/Cli/ParentGroups/CliCreate.php @@ -21,13 +21,13 @@ * $ wp boilerplate create media * * # Create custom post type service class. - * $ wp boilerplate create post_type --url='project.test' --label="Jobs" --slug="jobs" --rewrite_url="jobs" --rest_endpoint_slug="jobs" + * $ wp boilerplate create post-type --url='project.test' --label="Jobs" --slug="jobs" --rewrite_url="jobs" --rest_endpoint_slug="jobs" * * # Create custom taxonomy service class. - * $ wp boilerplate create_taxonomy --label='Job Positions' --slug='job-position' --rest_endpoint_slug='job-positions' --post_type_slug='user' + * $ wp boilerplate create taxonomy --label='Job Positions' --slug='job-position' --rest_endpoint_slug='job-positions' --post_type_slug='user' * * # Create create custom admin appearance service class. - * $ wp boilerplate create_modify_admin_appearance + * $ wp boilerplate create modify-admin-appearance */ class CliCreate extends WP_CLI_Command { From 954b1d9b6b107b70133e2a0fbfef22390c6c3d87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Ruz=CC=8Cevic=CC=81?= Date: Sun, 29 Oct 2023 22:48:34 +0100 Subject: [PATCH 18/24] adding new command for changing version name --- src/Cli/AbstractCli.php | 26 +++++++- src/Cli/Cli.php | 2 + src/Misc/VersionCli.php | 122 +++++++++++++++++++++++++++++++++++++ tests/Unit/Cli/CliTest.php | 2 +- 4 files changed, 148 insertions(+), 4 deletions(-) create mode 100644 src/Misc/VersionCli.php diff --git a/src/Cli/AbstractCli.php b/src/Cli/AbstractCli.php index 58f79aa08..3b61d30fd 100644 --- a/src/Cli/AbstractCli.php +++ b/src/Cli/AbstractCli.php @@ -298,6 +298,7 @@ function ($item) { public function getExampleTemplate(string $currentDir, string $fileName, bool $skipMissing = false): self { $ds = \DIRECTORY_SEPARATOR; + $currentDir = \rtrim($currentDir, $ds); $path = "{$currentDir}{$ds}{$this->getExampleFileName($fileName)}.php"; // If you pass file name with extension the version will be used. @@ -347,7 +348,8 @@ public function getExampleFileName(string $filename): string public function outputWrite(string $destination, string $fileName, array $args = []): void { $groupOutput = $args['groupOutput'] ?? false; - $typeOutput = $args['typeOutput'] ?? 'Service class'; + $typeOutput = $args['typeOutput'] ?? \__('Service class', 'eightshift-libs'); + $actionOutput = $args['actionOutput'] ?? null; // Set optional arguments. $skipExisting = $this->getSkipExisting($args); @@ -390,9 +392,11 @@ public function outputWrite(string $destination, string $fileName, array $args = $path = $this->getShortenCliPathOutput($destinationFile); if ($skipExisting) { - $this->cliLogAlert($path, 'success', "'{$fileName}' renamed"); + $action = $actionOutput ?? 'renamed'; + $this->cliLogAlert($path, 'success', "'{$fileName}' {$action}"); } else { - $this->cliLogAlert($path, 'success', "'{$fileName}' created"); + $action = $actionOutput ?? 'created'; + $this->cliLogAlert($path, 'success', "'{$fileName}' {$action}"); } } @@ -666,6 +670,22 @@ public function renameClassNameWithPrefix(string $templateName, string $newName) return $this; } + /** + * Change version number as a string. + * + * @param string $version New version. + * + * @return AbstractCli Current CLI class. + */ + public function renameVersionString(string $version): self + { + $this->fileContents = \preg_replace('/Version: .*/', "Version: {$version}", $this->fileContents); + $this->fileContents = \preg_replace('/"version": ".*"/', "\"version\": \"{$version}\"", $this->fileContents); + + return $this; + } + + /** * Search and replace wrapper * diff --git a/src/Cli/Cli.php b/src/Cli/Cli.php index 76c0e6fdc..be37505d9 100644 --- a/src/Cli/Cli.php +++ b/src/Cli/Cli.php @@ -63,6 +63,7 @@ use EightshiftLibs\Init\InitThemeCli; use EightshiftLibs\Media\RegenerateWebPMediaCli; use EightshiftLibs\Media\UseWebPMediaCli; +use EightshiftLibs\Misc\VersionCli; use EightshiftLibs\Readme\ReadmeCli; use EightshiftLibs\Rest\Routes\LoadMore\LoadMoreRouteCli; use EightshiftLibs\ThemeOptions\ThemeOptionsCli; @@ -139,6 +140,7 @@ class Cli ImportCli::class, RegenerateWebPMediaCli::class, UseWebPMediaCli::class, + VersionCli::class, PluginManageCli::class, ]; diff --git a/src/Misc/VersionCli.php b/src/Misc/VersionCli.php new file mode 100644 index 000000000..74e21cca0 --- /dev/null +++ b/src/Misc/VersionCli.php @@ -0,0 +1,122 @@ + + */ + public function getDefaultArgs(): array + { + return [ + 'version' => '1.0.0', + ]; + } + + /** + * Get WPCLI command doc + * + * @return array>|string> + */ + public function getDoc(): array + { + return [ + 'shortdesc' => 'Change projects version number.', + 'synopsis' => [ + [ + 'type' => 'assoc', + 'name' => 'version', + 'description' => 'Set new verion number.', + 'optional' => true, + 'default' => $this->getDefaultArg('version'), + ], + ], + 'longdesc' => $this->prepareLongDesc(" + ## USAGE + + Used to update projects version number. + + ## EXAMPLES + + # Update project version: + $ wp {$this->commandParentName} {$this->getCommandParentName()} {$this->getCommandName()} + + ## RESOURCES + + Command will be run using this code: + https://github.com/infinum/eightshift-libs/blob/develop/src/Misc/VersionCli.php + "), + ]; + } + + /* @phpstan-ignore-next-line */ + public function __invoke(array $args, array $assocArgs) + { + $this->getIntroText($assocArgs); + + // Get Props. + $version = $this->getArg($assocArgs, 'version'); + + $assocArgs['skip_existing'] = 'true'; + // translators: %s is replaced with the new version number. + $assocArgs['actionOutput'] = \sprintf(\__("version number changed to %s.", 'eightshift-libs'), $version); + + $path = Components::getProjectPaths('cliOutput'); + + $sep = \DIRECTORY_SEPARATOR; + $pluginName = \explode($sep, \rtrim($path, $sep)); + + $files = [ + 'package.json', + 'style.css', + 'functions.php', + \end($pluginName) . '.php', + ]; + + foreach ($files as $file) { + if (\file_exists(Components::getProjectPaths('cliOutput', $file))) { + $this->getExampleTemplate($path, $file, true) + ->renameVersionString($version) + ->outputWrite(Components::getProjectPaths('cliOutput'), $file, $assocArgs); + } + } + } +} diff --git a/tests/Unit/Cli/CliTest.php b/tests/Unit/Cli/CliTest.php index b9c7b9f7c..0fac57cc3 100644 --- a/tests/Unit/Cli/CliTest.php +++ b/tests/Unit/Cli/CliTest.php @@ -26,7 +26,7 @@ ->not->toHaveKey(CliShowAll::class) ->and(\count($publicClasses)) ->toBeInt() - ->toBe(52); + ->toBe(53); // Public classes count. }); From 401ed353fa7562642177df0d5040f2819820e1d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Ruz=CC=8Cevic=CC=81?= Date: Mon, 30 Oct 2023 08:38:56 +0100 Subject: [PATCH 19/24] fixing import command --- src/Db/DbExport.php | 2 +- src/Db/DbImport.php | 2 +- src/Db/ImportCli.php | 25 +++++++++++++------ tests/Unit/Db/DbImportTest.php | 13 +++++++--- tests/data/setup/setup-missing-urls-from.json | 6 +++++ tests/data/setup/setup-missing-urls-to.json | 7 ++++++ 6 files changed, 42 insertions(+), 13 deletions(-) create mode 100644 tests/data/setup/setup-missing-urls-from.json create mode 100644 tests/data/setup/setup-missing-urls-to.json diff --git a/src/Db/DbExport.php b/src/Db/DbExport.php index 223eee470..96435465f 100644 --- a/src/Db/DbExport.php +++ b/src/Db/DbExport.php @@ -52,7 +52,7 @@ function dbExport(string $projectRootPath, array $args = []) // Execute db export. if (!$skipDb) { - WP_CLI::runcommand("db export {$dbFileName}"); + WP_CLI::runcommand("db export {$dbFileName} --set-gtid-purged=OFF"); WP_CLI::log("Exported db to {$projectRootPath} folder."); WP_CLI::log('--------------------------------------------------'); diff --git a/src/Db/DbImport.php b/src/Db/DbImport.php index 652ad281a..662b5c8e1 100644 --- a/src/Db/DbImport.php +++ b/src/Db/DbImport.php @@ -110,7 +110,7 @@ function dbImport(string $setupFile, array $args = []) WP_CLI::log('--------------------------------------------------'); // Execute db export. - WP_CLI::runcommand('db export'); + WP_CLI::runcommand('db export --set-gtid-purged=OFF'); WP_CLI::log('Db exported successfully.'); WP_CLI::log('--------------------------------------------------'); diff --git a/src/Db/ImportCli.php b/src/Db/ImportCli.php index 3e9ff1959..56b6a654e 100644 --- a/src/Db/ImportCli.php +++ b/src/Db/ImportCli.php @@ -47,12 +47,10 @@ public function getCommandName(): string */ public function getDefaultArgs(): array { - $sep = \DIRECTORY_SEPARATOR; - return [ 'from' => '', 'to' => '', - 'setup_file' => Components::getProjectPaths('cliOutput', "setup{$sep}setup.json"), + 'setup_file' => Components::getProjectPaths('projectRoot', 'setup.json'), ]; } @@ -78,6 +76,13 @@ public function getDoc(): array 'description' => 'Set to what environment you want to import the data.', 'optional' => false, ], + [ + 'type' => 'assoc', + 'name' => 'setup_file', + 'description' => 'Set custom absolute path to your setup.json file.', + 'optional' => true, + 'default' => $this->getDefaultArg('setup_file'), + ], ], 'longdesc' => $this->prepareLongDesc(" ## USAGE @@ -89,6 +94,9 @@ public function getDoc(): array # Run db import command: $ wp {$this->commandParentName} {$this->getCommandParentName()} {$this->getCommandName()} --from='production' --to='develop' + # Run db import command with custom setup.json file path: + $ wp {$this->commandParentName} {$this->getCommandParentName()} {$this->getCommandName()} --from='production' --to='develop' --setup_file='new/setup.json' + ## RESOURCES Command will be run using this code: @@ -107,10 +115,13 @@ public function __invoke(array $args, array $assocArgs) try { dbImport( // phpcs:ignore $this->getArg($assocArgs, 'setup_file'), - [ - 'from' => $this->getArg($assocArgs, 'from'), - 'to' => $this->getArg($assocArgs, 'to'), - ] + \array_merge( + [ + 'from' => $this->getArg($assocArgs, 'from'), + 'to' => $this->getArg($assocArgs, 'to'), + ], + $assocArgs + ) ); } catch (ExitException $e) { exit("{$e->getCode()}: {$e->getMessage()}"); // phpcs:ignore Eightshift.Security.ComponentsEscape.OutputNotEscaped diff --git a/tests/Unit/Db/DbImportTest.php b/tests/Unit/Db/DbImportTest.php index c4d13d96f..17b424560 100644 --- a/tests/Unit/Db/DbImportTest.php +++ b/tests/Unit/Db/DbImportTest.php @@ -48,9 +48,10 @@ expect($docs) ->toBeArray() ->toHaveKeys(['shortdesc', 'synopsis', 'longdesc']) - ->and(count($docs['synopsis']))->toEqual(2) + ->and(count($docs['synopsis']))->toEqual(3) ->and($docs['synopsis'][0]['name'])->toEqual('from') - ->and($docs['synopsis'][1]['name'])->toEqual('to'); + ->and($docs['synopsis'][1]['name'])->toEqual('to') + ->and($docs['synopsis'][2]['name'])->toEqual('setup_file'); }); //---------------------------------------------------------------------------------// @@ -123,6 +124,7 @@ test('__invoke will fail if setup.json is missing url "from" key', function () { (new SetupCli('boilerplate'))->__invoke([], [ 'path' => Components::getProjectPaths('cliOutput', 'setup'), + 'file_name' => 'setup-missing-urls-from.json', 'source_path' => Components::getProjectPaths('testsData', 'setup'), ]); @@ -130,6 +132,7 @@ $mock([], [ 'from' => 'test', 'to' => 'develop', + 'setup_file' => Components::getProjectPaths('cliOutput', 'setup' . \DIRECTORY_SEPARATOR . 'setup-missing-urls-from.json'), ]); })->throws(Exception::class, 'test key is missing or empty in urls.'); @@ -137,13 +140,15 @@ test('__invoke will fail if setup.json is missing url "to" key', function () { (new SetupCli('boilerplate'))->__invoke([], [ 'path' => Components::getProjectPaths('cliOutput', 'setup'), + 'file_name' => 'setup-missing-urls-to.json', 'source_path' => Components::getProjectPaths('testsData', 'setup'), ]); $mock = $this->mock; $mock([], [ - 'from' => 'production', - 'to' => 'test', + 'from' => 'test', + 'to' => 'develop', + 'setup_file' => Components::getProjectPaths('cliOutput', 'setup' . \DIRECTORY_SEPARATOR . 'setup-missing-urls-to.json'), ]); })->throws(Exception::class, 'test key is missing or empty in urls.'); diff --git a/tests/data/setup/setup-missing-urls-from.json b/tests/data/setup/setup-missing-urls-from.json new file mode 100644 index 000000000..1b03c8eb5 --- /dev/null +++ b/tests/data/setup/setup-missing-urls-from.json @@ -0,0 +1,6 @@ +{ + "core": "5.9.1", + "urls": { + "to": "test" + } +} diff --git a/tests/data/setup/setup-missing-urls-to.json b/tests/data/setup/setup-missing-urls-to.json new file mode 100644 index 000000000..9c821c802 --- /dev/null +++ b/tests/data/setup/setup-missing-urls-to.json @@ -0,0 +1,7 @@ +{ + "core": "5.9.1", + "urls": { + "to": "", + "from": "test" + } +} From c5cd9321ae698eeeb92e1502f32414f7c1d52c51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Ruz=CC=8Cevic=CC=81?= Date: Mon, 30 Oct 2023 08:55:39 +0100 Subject: [PATCH 20/24] adding better copy for missing attribute --- src/Helpers/AttributesTrait.php | 10 ++++++++-- tests/Unit/Helpers/AttributesTraitTest.php | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Helpers/AttributesTrait.php b/src/Helpers/AttributesTrait.php index 39ccbf035..9b6af7993 100644 --- a/src/Helpers/AttributesTrait.php +++ b/src/Helpers/AttributesTrait.php @@ -43,11 +43,17 @@ public static function checkAttr(string $key, array $attributes, array $manifest $manifestKey = $manifest['attributes'][$key] ?? null; + $tipOutput = ''; + + if (isset($manifest['components'])) { + $tipOutput = ' If you are using additional components, check if you used the correct block/component prefix in your attribute name.'; + } + if ($manifestKey === null) { if (isset($manifest['blockName']) || \array_key_exists('blockName', $manifest)) { - throw new Exception("{$key} key does not exist in the {$manifest['blockName']} block manifest. Please check your implementation."); + throw new Exception("{$key} key does not exist in the {$manifest['blockName']} block manifest.{$tipOutput} Please check your implementation."); } else { - throw new Exception("{$key} key does not exist in the {$manifest['componentName']} component manifest. Please check your implementation."); + throw new Exception("{$key} key does not exist in the {$manifest['componentName']} component manifest.{$tipOutput} Please check your implementation."); } } diff --git a/tests/Unit/Helpers/AttributesTraitTest.php b/tests/Unit/Helpers/AttributesTraitTest.php index a7d48f0ea..3430a38d4 100644 --- a/tests/Unit/Helpers/AttributesTraitTest.php +++ b/tests/Unit/Helpers/AttributesTraitTest.php @@ -33,7 +33,7 @@ $attributes['buttonText'] = 'left'; Components::checkAttr('buttonAlign', $attributes, $manifest); -})->throws(Exception::class, 'buttonAlign key does not exist in the button block manifest. Please check your implementation.'); +})->throws(Exception::class, 'buttonAlign key does not exist in the button block manifest. If you are using additional components, check if you used the correct block/component prefix in your attribute name. Please check your implementation.'); test('Asserts that checkAttr works in case attribute is boolean', function () { From 6c9cf8585a59096c7f1782391021e23ecc70bea4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Ruz=CC=8Cevic=CC=81?= Date: Mon, 30 Oct 2023 09:25:56 +0100 Subject: [PATCH 21/24] adding is used method to every enqueu hook --- src/Enqueue/Admin/AbstractEnqueueAdmin.php | 49 +++++- src/Enqueue/Blocks/AbstractEnqueueBlocks.php | 166 ++++++++++++++---- src/Enqueue/Theme/AbstractEnqueueTheme.php | 20 ++- .../Blocks/EnqueueBlockExampleTest.php | 13 +- .../Enqueue/Theme/EnqueueThemeExampleTest.php | 8 +- 5 files changed, 202 insertions(+), 54 deletions(-) diff --git a/src/Enqueue/Admin/AbstractEnqueueAdmin.php b/src/Enqueue/Admin/AbstractEnqueueAdmin.php index 5f744f18a..308ebb3ec 100644 --- a/src/Enqueue/Admin/AbstractEnqueueAdmin.php +++ b/src/Enqueue/Admin/AbstractEnqueueAdmin.php @@ -30,7 +30,6 @@ abstract class AbstractEnqueueAdmin extends AbstractAssets */ protected ManifestInterface $manifest; - /** * Get admin Stylesheet handle. * @@ -42,22 +41,30 @@ public function getAdminStyleHandle(): string } /** - * Get admin JavaScript handle. + * Method that returns assets hook used to determine hook usage. * - * @return string + * @param string $hook Hook name. + * + * @return boolean */ - public function getAdminScriptHandle(): string + public function isEnqueueStylesUsed(string $hook): bool { - return "{$this->getAssetsPrefix()}-scripts"; + return true; } /** * Register the Stylesheets for the admin area. * + * @param string $hook Hook name. + * * @return void */ - public function enqueueStyles(): void + public function enqueueStyles(string $hook): void { + if (!$this->isEnqueueStylesUsed($hook)) { + return; + } + if (!$this->getConditionUse()) { $handle = $this->getAdminStyleHandle(); @@ -73,13 +80,41 @@ public function enqueueStyles(): void } } + /** + * Get admin JavaScript handle. + * + * @return string + */ + public function getAdminScriptHandle(): string + { + return "{$this->getAssetsPrefix()}-scripts"; + } + + /** + * Method that returns assets hook used to determine hook usage. + * + * @param string $hook Hook name. + * + * @return boolean + */ + public function isEnqueueScriptsUsed(string $hook): bool + { + return true; + } + /** * Register the JavaScript for the admin area. * + * @param string $hook Hook name. + * * @return void */ - public function enqueueScripts(): void + public function enqueueScripts(string $hook): void { + if (!$this->isEnqueueScriptsUsed($hook)) { + return; + } + if (!$this->getConditionUse()) { $handle = $this->getAdminScriptHandle(); diff --git a/src/Enqueue/Blocks/AbstractEnqueueBlocks.php b/src/Enqueue/Blocks/AbstractEnqueueBlocks.php index 7708b43ba..a468f3704 100644 --- a/src/Enqueue/Blocks/AbstractEnqueueBlocks.php +++ b/src/Enqueue/Blocks/AbstractEnqueueBlocks.php @@ -44,52 +44,30 @@ public function getBlockEditorScriptsHandle(): string } /** - * Get block editor Stylesheet handle. + * Method that returns assets hook used to determine hook usage. * - * @return string - */ - public function getBlockEditorStyleHandle(): string - { - return "{$this->getAssetsPrefix()}-block-editor-style"; - } - - /** - * Get block Stylesheet handle. - * - * @return string - */ - public function getBlockStyleHandle(): string - { - return "{$this->getAssetsPrefix()}-block-style"; - } - - /** - * Get block frontend JavaScript handle. - * - * @return string - */ - public function getBlockFrontentScriptHandle(): string - { - return "{$this->getAssetsPrefix()}-block-frontend-scripts"; - } - - /** - * Get block frontend Stylesheet handle. + * @param string $hook Hook name. * - * @return string + * @return boolean */ - public function getBlockFrontentStyleHandle(): string + public function isEnqueueBlockEditorScriptUsed(string $hook): bool { - return "{$this->getAssetsPrefix()}-block-frontend-style"; + return true; } /** * Enqueue blocks script for editor only. * + * @param string $hook Hook name. + * * @return void */ - public function enqueueBlockEditorScript(): void + public function enqueueBlockEditorScript(string $hook): void { + if (!$this->isEnqueueBlockEditorScriptUsed($hook)) { + return; + } + $handle = $this->getBlockEditorScriptsHandle(); \wp_register_script( @@ -107,13 +85,41 @@ public function enqueueBlockEditorScript(): void } } + /** + * Get block editor Stylesheet handle. + * + * @return string + */ + public function getBlockEditorStyleHandle(): string + { + return "{$this->getAssetsPrefix()}-block-editor-style"; + } + + /** + * Method that returns assets hook used to determine hook usage. + * + * @param string $hook Hook name. + * + * @return boolean + */ + public function isEnqueueBlockEditorStyleUsed(string $hook): bool + { + return true; + } + /** * Enqueue blocks style for editor only. * + * @param string $hook Hook name. + * * @return void */ - public function enqueueBlockEditorStyle(): void + public function enqueueBlockEditorStyle(string $hook): void { + if (!$this->isEnqueueBlockEditorStyleUsed($hook)) { + return; + } + $handle = $this->getBlockEditorStyleHandle(); \wp_register_style( @@ -127,13 +133,41 @@ public function enqueueBlockEditorStyle(): void \wp_enqueue_style($handle); } + /** + * Get block Stylesheet handle. + * + * @return string + */ + public function getBlockStyleHandle(): string + { + return "{$this->getAssetsPrefix()}-block-style"; + } + + /** + * Method that returns assets hook used to determine hook usage. + * + * @param string $hook Hook name. + * + * @return boolean + */ + public function isEnqueueBlockStyleUsed(string $hook): bool + { + return true; + } + /** * Enqueue blocks style for editor and frontend. * + * @param string $hook Hook name. + * * @return void */ - public function enqueueBlockStyle(): void + public function enqueueBlockStyle(string $hook): void { + if (!$this->isEnqueueBlockStyleUsed($hook)) { + return; + } + $handle = $this->getBlockStyleHandle(); \wp_register_style( @@ -147,13 +181,41 @@ public function enqueueBlockStyle(): void \wp_enqueue_style($handle); } + /** + * Get block frontend JavaScript handle. + * + * @return string + */ + public function getBlockFrontentScriptHandle(): string + { + return "{$this->getAssetsPrefix()}-block-frontend-scripts"; + } + + /** + * Method that returns assets hook used to determine hook usage. + * + * @param string $hook Hook name. + * + * @return boolean + */ + public function isEnqueueBlockFrontendScriptUsed(string $hook): bool + { + return true; + } + /** * Enqueue blocks script for frontend only. * + * @param string $hook Hook name. + * * @return void */ - public function enqueueBlockFrontendScript(): void + public function enqueueBlockFrontendScript(string $hook): void { + if (!$this->isEnqueueBlockFrontendScriptUsed($hook)) { + return; + } + $handle = $this->getBlockFrontentScriptHandle(); \wp_register_script( @@ -172,13 +234,41 @@ public function enqueueBlockFrontendScript(): void } } + /** + * Get block frontend Stylesheet handle. + * + * @return string + */ + public function getBlockFrontentStyleHandle(): string + { + return "{$this->getAssetsPrefix()}-block-frontend-style"; + } + + /** + * Method that returns assets hook used to determine hook usage. + * + * @param string $hook Hook name. + * + * @return boolean + */ + public function isEnqueueBlockFrontendStyleUsed(string $hook): bool + { + return true; + } + /** * Enqueue blocks style for frontend only. * + * @param string $hook Hook name. + * * @return void */ - public function enqueueBlockFrontendStyle(): void + public function enqueueBlockFrontendStyle(string $hook): void { + if (!$this->isEnqueueBlockFrontendStyleUsed($hook)) { + return; + } + $handle = $this->getBlockFrontentStyleHandle(); \wp_register_style( diff --git a/src/Enqueue/Theme/AbstractEnqueueTheme.php b/src/Enqueue/Theme/AbstractEnqueueTheme.php index 9b30f0b88..6b9d22b2d 100644 --- a/src/Enqueue/Theme/AbstractEnqueueTheme.php +++ b/src/Enqueue/Theme/AbstractEnqueueTheme.php @@ -48,13 +48,31 @@ public function getThemeScriptHandle(): string return "{$this->getAssetsPrefix()}-scripts"; } + /** + * Method that returns assets hook used to determine hook usage. + * + * @param string $hook Hook name. + * + * @return boolean + */ + public function isEnqueueStylesUsed(string $hook): bool + { + return true; + } + /** * Register the Stylesheets for the front end of the theme. * + * @param string $hook Hook name. + * * @return void */ - public function enqueueStyles(): void + public function enqueueStyles(string $hook): void { + if (!$this->isEnqueueStylesUsed($hook)) { + return; + } + $handle = $this->getThemeStyleHandle(); \wp_register_style( diff --git a/tests/Unit/Enqueue/Blocks/EnqueueBlockExampleTest.php b/tests/Unit/Enqueue/Blocks/EnqueueBlockExampleTest.php index cd5c634cb..da4f69713 100644 --- a/tests/Unit/Enqueue/Blocks/EnqueueBlockExampleTest.php +++ b/tests/Unit/Enqueue/Blocks/EnqueueBlockExampleTest.php @@ -80,6 +80,8 @@ protected function getLocalizations(): array $manifest->setAssetsManifestRaw(); $this->blockEnqueue = new EnqueueBlockExampleTest($manifest); + + $this->hookSuffix = 'test'; }); /** @@ -90,6 +92,7 @@ protected function getLocalizations(): array $this->projectName, $this->projectVersion, $this->blockEnqueue, + $this->hookSuffix ); putenv('REGISTER_STYLE'); @@ -131,7 +134,7 @@ protected function getLocalizations(): array }); test('enqueueBlockEditorScript method will enqueue scripts for block editor', function () { - $this->blockEnqueue->enqueueBlockEditorScript(); + $this->blockEnqueue->enqueueBlockEditorScript($this->hookSuffix); $this->assertSame(\getenv('REGISTER_SCRIPT'), "{$this->projectName}-block-editor-scripts", 'Method enqueueStyles() failed to register style'); $this->assertSame(\getenv('ENQUEUE_SCRIPT'), "{$this->projectName}-block-editor-scripts", 'Method enqueueScripts() failed to enqueue style'); @@ -139,21 +142,21 @@ protected function getLocalizations(): array }); test('enqueueBlockEditorStyle method will enqueue styles for block editor', function () { - $this->blockEnqueue->enqueueBlockEditorStyle(); + $this->blockEnqueue->enqueueBlockEditorStyle($this->hookSuffix); $this->assertSame(\getenv('REGISTER_STYLE'), "{$this->projectName}-block-editor-style", 'Method enqueueStyles() failed to register style'); $this->assertSame(\getenv('ENQUEUE_STYLE'), "{$this->projectName}-block-editor-style", 'Method enqueueStyles() failed to enqueue style'); }); test('enqueueBlockStyle method will enqueue styles for a block', function () { - $this->blockEnqueue->enqueueBlockStyle(); + $this->blockEnqueue->enqueueBlockStyle($this->hookSuffix); $this->assertSame(\getenv('REGISTER_STYLE'), "{$this->projectName}-block-style", 'Method enqueueStyles() failed to register style'); $this->assertSame(\getenv('ENQUEUE_STYLE'), "{$this->projectName}-block-style", 'Method enqueueStyles() failed to enqueue style'); }); test('enqueueBlockFrontendScript method will enqueue scripts for a block', function () { - $this->blockEnqueue->enqueueBlockFrontendScript(); + $this->blockEnqueue->enqueueBlockFrontendScript($this->hookSuffix); $this->assertSame(\getenv('REGISTER_SCRIPT'), "{$this->projectName}-block-frontend-scripts", 'Method enqueueStyles() failed to register style'); $this->assertSame(\getenv('ENQUEUE_SCRIPT'), "{$this->projectName}-block-frontend-scripts", 'Method enqueueScripts() failed to enqueue style'); @@ -161,7 +164,7 @@ protected function getLocalizations(): array }); test('enqueueBlockFrontendStyle method will enqueue styles for a block', function () { - $this->blockEnqueue->enqueueBlockFrontendStyle(); + $this->blockEnqueue->enqueueBlockFrontendStyle($this->hookSuffix); $this->assertSame(\getenv('REGISTER_STYLE'), "{$this->projectName}-block-frontend-style", 'Method enqueueStyles() failed to register style'); $this->assertSame(\getenv('ENQUEUE_STYLE'), "{$this->projectName}-block-frontend-style", 'Method enqueueScripts() failed to enqueue style'); diff --git a/tests/Unit/Enqueue/Theme/EnqueueThemeExampleTest.php b/tests/Unit/Enqueue/Theme/EnqueueThemeExampleTest.php index f0dd168ab..6ac21eb17 100644 --- a/tests/Unit/Enqueue/Theme/EnqueueThemeExampleTest.php +++ b/tests/Unit/Enqueue/Theme/EnqueueThemeExampleTest.php @@ -57,10 +57,12 @@ protected function getLocalizations(): array $manifest->setAssetsManifestRaw(); $this->themeEnqueue = new EnqueueThemeExampleTest($manifest); + + $this->hookSuffix = 'test'; }); afterEach(function() { - unset($this->themeEnqueue); + unset($this->themeEnqueue, $this->hookSuffix); putenv('REGISTER_STYLE'); putenv('ENQUEUE_STYLE'); @@ -92,14 +94,14 @@ protected function getLocalizations(): array }); test('enqueueStyles method will enqueue styles in a theme', function () { - $this->themeEnqueue->enqueueStyles(); + $this->themeEnqueue->enqueueStyles($this->hookSuffix); $this->assertSame(\getenv('REGISTER_STYLE'), 'MyProject-theme-styles', 'Method enqueueStyles() failed to register style'); $this->assertSame(\getenv('ENQUEUE_STYLE'), 'MyProject-theme-styles', 'Method enqueueStyles() failed to enqueue style'); }); test('enqueueScripts method will enqueue scripts in a theme', function () { - $this->themeEnqueue->enqueueScripts(); + $this->themeEnqueue->enqueueScripts($this->hookSuffix); $this->assertSame(\getenv('REGISTER_SCRIPT'), 'MyProject-scripts', 'Method enqueueStyles() failed to register style'); $this->assertSame(\getenv('ENQUEUE_SCRIPT'), 'MyProject-scripts', 'Method enqueueScripts() failed to enqueue style'); $this->assertSame(\getenv('SIDEAFFECT'), 'localize', 'Method wp_localize_script() failed'); From 7089c1576f1defde04587e6a3995f3f295168135 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Ru=C5=BEevi=C4=87?= Date: Mon, 30 Oct 2023 11:11:37 +0100 Subject: [PATCH 22/24] Update src/Misc/VersionCli.php Co-authored-by: Ivan Ramljak <22823970+piqusy@users.noreply.github.com> --- src/Misc/VersionCli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Misc/VersionCli.php b/src/Misc/VersionCli.php index 74e21cca0..26b4e7bfb 100644 --- a/src/Misc/VersionCli.php +++ b/src/Misc/VersionCli.php @@ -64,7 +64,7 @@ public function getDoc(): array [ 'type' => 'assoc', 'name' => 'version', - 'description' => 'Set new verion number.', + 'description' => 'Set new version number.', 'optional' => true, 'default' => $this->getDefaultArg('version'), ], From f74cdb09a748cbefec9f493fb63e9075fd54d233 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Ruz=CC=8Cevic=CC=81?= Date: Mon, 30 Oct 2023 11:13:26 +0100 Subject: [PATCH 23/24] adding is used method to every enqueu hook --- src/Blocks/AbstractBlocksCli.php | 1 - tests/BaseTest.php | 1 - 2 files changed, 2 deletions(-) diff --git a/src/Blocks/AbstractBlocksCli.php b/src/Blocks/AbstractBlocksCli.php index 98bf18099..233e7cc91 100644 --- a/src/Blocks/AbstractBlocksCli.php +++ b/src/Blocks/AbstractBlocksCli.php @@ -101,7 +101,6 @@ protected function moveItems(array $args, string $source, string $destination, s } } - if (!$itemExists) { self::cliError( \sprintf( diff --git a/tests/BaseTest.php b/tests/BaseTest.php index 1de552add..4308b3bcb 100644 --- a/tests/BaseTest.php +++ b/tests/BaseTest.php @@ -9,7 +9,6 @@ use Mockery\MockInterface; use RecursiveDirectoryIterator; use RecursiveIteratorIterator; -use WP_Theme; use Yoast\WPTestUtils\BrainMonkey\TestCase; class BaseTest extends TestCase From 5f976a7a90b8d54ee51db3b98f9ea0b973c5cfc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Ruz=CC=8Cevic=CC=81?= Date: Tue, 31 Oct 2023 08:08:18 +0100 Subject: [PATCH 24/24] adding PR fixes --- src/Helpers/AttributesTrait.php | 4 ++-- tests/Unit/Helpers/AttributesTraitTest.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Helpers/AttributesTrait.php b/src/Helpers/AttributesTrait.php index 9b6af7993..820717c59 100644 --- a/src/Helpers/AttributesTrait.php +++ b/src/Helpers/AttributesTrait.php @@ -51,9 +51,9 @@ public static function checkAttr(string $key, array $attributes, array $manifest if ($manifestKey === null) { if (isset($manifest['blockName']) || \array_key_exists('blockName', $manifest)) { - throw new Exception("{$key} key does not exist in the {$manifest['blockName']} block manifest.{$tipOutput} Please check your implementation."); + throw new Exception("{$key} key does not exist in the {$manifest['blockName']} block manifest. Please check your implementation.{$tipOutput} "); } else { - throw new Exception("{$key} key does not exist in the {$manifest['componentName']} component manifest.{$tipOutput} Please check your implementation."); + throw new Exception("{$key} key does not exist in the {$manifest['componentName']} component manifest. Please check your implementation.{$tipOutput} "); } } diff --git a/tests/Unit/Helpers/AttributesTraitTest.php b/tests/Unit/Helpers/AttributesTraitTest.php index 3430a38d4..371f9c432 100644 --- a/tests/Unit/Helpers/AttributesTraitTest.php +++ b/tests/Unit/Helpers/AttributesTraitTest.php @@ -33,7 +33,7 @@ $attributes['buttonText'] = 'left'; Components::checkAttr('buttonAlign', $attributes, $manifest); -})->throws(Exception::class, 'buttonAlign key does not exist in the button block manifest. If you are using additional components, check if you used the correct block/component prefix in your attribute name. Please check your implementation.'); +})->throws(Exception::class, 'buttonAlign key does not exist in the button block manifest. Please check your implementation. If you are using additional components, check if you used the correct block/component prefix in your attribute name.'); test('Asserts that checkAttr works in case attribute is boolean', function () {