diff --git a/.github/workflows/integrate.yml b/.github/workflows/integrate.yml index 0667510b5..de8c9efe3 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,10 +63,8 @@ jobs: strategy: fail-fast: false matrix: - php-version: - - "7.4" + php-version: ["7.4", "8.0", "8.1", "8.2"] dependencies: - - "lowest" - "highest" runs-on: "ubuntu-latest" steps: @@ -77,14 +75,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 +115,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 +144,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 +168,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..ca63db773 100644 --- a/composer.json +++ b/composer.json @@ -24,24 +24,24 @@ "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/invoker": "^2.3.4", + "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", + "szepeviktor/phpstan-wordpress": "^1.3", + "wp-cli/wp-cli": "^2.9", "yoast/wp-test-utils": "^1.0" }, "autoload": { 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..758015e47 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -13,7 +13,6 @@ 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\.$/' + 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..4a5df703f 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. @@ -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/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/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/AbstractBlocksCli.php b/src/Blocks/AbstractBlocksCli.php index a930773bd..233e7cc91 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) ) @@ -67,32 +67,41 @@ 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); } $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 +113,6 @@ protected function moveItems(array $args, string $source, string $destination, s ); } - $source = $sourceItems[$item]; - $fullSource = Components::joinPaths([$source, $item]); $fullDestination = Components::joinPaths([$destination, $item]); @@ -224,17 +231,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/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/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/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; } /** 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 deleted file mode 100644 index f3081a5a5..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', - 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 e38b0ad03..3b61d30fd 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. * @@ -277,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. @@ -326,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); @@ -369,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}"); } } @@ -645,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 * @@ -794,7 +835,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 022af1663..be37505d9 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; @@ -21,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; @@ -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; @@ -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,11 @@ class Cli * @var class-string[] */ public const RUN_COMMANDS = [ - RegenerateWebPMediaCli::class, - UseWebPMediaCli::class, ExportCli::class, ImportCli::class, + RegenerateWebPMediaCli::class, + UseWebPMediaCli::class, + VersionCli::class, PluginManageCli::class, ]; @@ -147,14 +150,13 @@ 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, 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, ]; /** 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 { 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/Db/DbExport.php b/src/Db/DbExport.php index 2ca2d93a8..96435465f 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); @@ -48,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 a273689b1..662b5c8e1 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']; @@ -106,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/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/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']); } /** diff --git a/src/Helpers/AttributesTrait.php b/src/Helpers/AttributesTrait.php index 39ccbf035..820717c59 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. Please check your implementation.{$tipOutput} "); } 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. Please check your implementation.{$tipOutput} "); } } diff --git a/src/Helpers/Components.php b/src/Helpers/Components.php index 6289d70dd..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', @@ -149,8 +147,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 +242,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(); @@ -357,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"; @@ -422,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]); @@ -477,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 9983de458..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 => [], @@ -156,7 +154,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/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 "), ]; } 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/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/Misc/VersionCli.php b/src/Misc/VersionCli.php new file mode 100644 index 000000000..26b4e7bfb --- /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 version 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/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/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/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); } 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 { diff --git a/tests/BaseTest.php b/tests/BaseTest.php index c40b96ffb..4308b3bcb 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,36 @@ protected function set_up() Functions\when('is_wp_version_compatible')->justReturn(true); 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(); + + 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/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/Blocks/BlocksExampleTest.php b/tests/Unit/Blocks/BlocksExampleTest.php index c8a29fea0..8850c5c73 100644 --- a/tests/Unit/Blocks/BlocksExampleTest.php +++ b/tests/Unit/Blocks/BlocksExampleTest.php @@ -42,49 +42,7 @@ 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 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; @@ -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 = [ 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/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/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/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/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/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'); diff --git a/tests/Unit/Exception/ComponentExceptionTest.php b/tests/Unit/Exception/ComponentExceptionTest.php index 0e1f18b9e..a83417a90 100644 --- a/tests/Unit/Exception/ComponentExceptionTest.php +++ b/tests/Unit/Exception/ComponentExceptionTest.php @@ -9,32 +9,60 @@ function ($argument) { $exceptionObject = ComponentException::throwNotStringOrArray($argument); $type = \gettype($argument); + $message = "{$argument} variable is not a string or array but rather {$type}"; - $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!"); + expect($exceptionObject)->toBeObject() + ->toBeInstanceOf(ComponentException::class) + ->toHaveProperty('message') + ->and($message) + ->toEqual($exceptionObject->getMessage()); +}) +->with('exceptionArguments'); - }) - ->with('exceptionArguments'); +test('Checks if the throwNotStringOrArray method functions correctly with objects.', +function () { - test('Checks if the throwNotStringOrArray method functions correctly with objects.', - function () { + $object = new stdClass(); + $exceptionObject = ComponentException::throwNotStringOrArray($object); - $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!"); - - }); + 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()); +}); + +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/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()); }); 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/Helpers/AttributesTraitTest.php b/tests/Unit/Helpers/AttributesTraitTest.php index a7d48f0ea..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. 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 () { 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'); 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" + } +} 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 @@ -