diff --git a/src/Init/theme/index.php b/src/Init/theme/index.php new file mode 100644 index 000000000..afa6ae3d7 --- /dev/null +++ b/src/Init/theme/index.php @@ -0,0 +1,19 @@ + + + Ruleset for the Eightshift Boilerplate. + + + + */tests/* + */vendor/* + */vendor-prefixed/* + */public/* + */node_modules/* + + + + + + + + . + + + + + + + + + /src/CompiledContainer\.php + + + + + + + + + diff --git a/src/Init/theme/phpstan.neon.dist b/src/Init/theme/phpstan.neon.dist new file mode 100644 index 000000000..57ecad7cb --- /dev/null +++ b/src/Init/theme/phpstan.neon.dist @@ -0,0 +1,17 @@ +includes: + - vendor/szepeviktor/phpstan-wordpress/extension.neon +parameters: + level: 6 + inferPrivatePropertyTypeFromConstructor: true + treatPhpDocTypesAsCertain: false + bootstrapFiles: + - vendor-prefixed/autoload.php + paths: + - src/ + ignoreErrors: + # Block templates + - '#^Variable \$attributes might not be defined\.#' + - '#^Variable \$innerBlockContent might not be defined\.#' + - '#^Variable \$this might not be defined\.#' + - '#^Variable \$templatePath might not be defined\.#' + checkGenericClassInNonGenericObjectType: false diff --git a/src/Init/theme/postcss.config.js b/src/Init/theme/postcss.config.js new file mode 100644 index 000000000..943e6fcd1 --- /dev/null +++ b/src/Init/theme/postcss.config.js @@ -0,0 +1,7 @@ +const autoprefixer = require('autoprefixer'); + +module.exports = { + plugins: [ + autoprefixer, + ], +}; diff --git a/src/Init/theme/screenshot.png b/src/Init/theme/screenshot.png new file mode 100644 index 000000000..0938147b4 Binary files /dev/null and b/src/Init/theme/screenshot.png differ diff --git a/src/Init/theme/single.php b/src/Init/theme/single.php new file mode 100644 index 000000000..82018a316 --- /dev/null +++ b/src/Init/theme/single.php @@ -0,0 +1,19 @@ + { + + const projectConfig = { + config: { + projectDir: __dirname, // Current project directory absolute path. + projectUrl: '%g_site_url%', // Used for providing browsersync functionality. + projectPath: 'wp-content/themes/%g_textdomain%', // Project path relative to project root. + }, + }; + + // Generate webpack config for this project using options object. + return require('./node_modules/@eightshift/frontend-libs/webpack')(argv.mode, projectConfig); +}; diff --git a/src/Login/LoginCli.php b/src/Login/LoginCli.php index 28dbcfd08..8919f45f8 100644 --- a/src/Login/LoginCli.php +++ b/src/Login/LoginCli.php @@ -12,7 +12,7 @@ use EightshiftLibs\Cli\AbstractCli; use EightshiftLibs\Cli\ParentGroups\CliCreate; -use EightshiftLibs\Helpers\Components; +use EightshiftLibs\Helpers\Helpers; /** * Class LoginCli @@ -69,6 +69,8 @@ public function getDoc(): array /* @phpstan-ignore-next-line */ public function __invoke(array $args, array $assocArgs) { + $assocArgs = $this->prepareArgs($assocArgs); + $this->getIntroText($assocArgs); $className = $this->getClassShortName(); @@ -76,8 +78,7 @@ public function __invoke(array $args, array $assocArgs) // Read the template contents, and replace the placeholders with provided variables. $this->getExampleTemplate(__DIR__, $className) ->renameClassName($className) - ->renameNamespace($assocArgs) - ->renameUse($assocArgs) - ->outputWrite(Components::getProjectPaths('srcDestination', 'Login'), "{$className}.php", $assocArgs); + ->renameGlobals($assocArgs) + ->outputWrite(Helpers::getProjectPaths('srcDestination', 'Login'), "{$className}.php", $assocArgs); } } diff --git a/src/Login/LoginExample.php b/src/Login/LoginExample.php index a750ac48d..567e0bddc 100644 --- a/src/Login/LoginExample.php +++ b/src/Login/LoginExample.php @@ -3,14 +3,14 @@ /** * The login page specific functionality. * - * @package EightshiftBoilerplate\Login + * @package %g_namespace%\Login */ declare(strict_types=1); -namespace EightshiftBoilerplate\Login; +namespace %g_namespace%\Login; -use EightshiftLibs\Services\ServiceInterface; +use %g_use_libs%\Services\ServiceInterface; /** * Class Login diff --git a/src/Main/AbstractMain.php b/src/Main/AbstractMain.php index 4f965fda9..199c17084 100644 --- a/src/Main/AbstractMain.php +++ b/src/Main/AbstractMain.php @@ -187,7 +187,7 @@ private function getDiContainer(array $services): Container $builder = new ContainerBuilder(); - if (\defined('WP_ENVIRONMENT_TYPE') && \WP_ENVIRONMENT_TYPE !== 'development') { + if ((\defined('WP_ENVIRONMENT_TYPE') && \WP_ENVIRONMENT_TYPE !== 'development') || !\defined('WP_CLI')) { $file = \explode('\\', $this->namespace); $builder->enableCompilation(__DIR__ . '/Cache', "{$file[0]}CompiledContainer"); diff --git a/src/Main/MainCli.php b/src/Main/MainCli.php index 772aa7141..9d924c372 100644 --- a/src/Main/MainCli.php +++ b/src/Main/MainCli.php @@ -12,7 +12,7 @@ use EightshiftLibs\Cli\AbstractCli; use EightshiftLibs\Cli\ParentGroups\CliCreate; -use EightshiftLibs\Helpers\Components; +use EightshiftLibs\Helpers\Helpers; /** * Class MainCli @@ -70,6 +70,8 @@ public function getDoc(): array /* @phpstan-ignore-next-line */ public function __invoke(array $args, array $assocArgs) { + $assocArgs = $this->prepareArgs($assocArgs); + $this->getIntroText($assocArgs); $className = $this->getClassShortName(); @@ -77,8 +79,7 @@ public function __invoke(array $args, array $assocArgs) // Read the template contents, and replace the placeholders with provided variables. $this->getExampleTemplate(__DIR__, $className) ->renameClassName($className) - ->renameNamespace($assocArgs) - ->renameUse($assocArgs) - ->outputWrite(Components::getProjectPaths('srcDestination', 'Main'), "{$className}.php", $assocArgs); + ->renameGlobals($assocArgs) + ->outputWrite(Helpers::getProjectPaths('srcDestination', 'Main'), "{$className}.php", $assocArgs); } } diff --git a/src/Main/MainExample.php b/src/Main/MainExample.php index 31468f26d..920a8c61d 100644 --- a/src/Main/MainExample.php +++ b/src/Main/MainExample.php @@ -6,14 +6,14 @@ * A class definition that includes attributes and functions used across both the * theme-facing side of the site and the admin area. * - * @package EightshiftBoilerplate\Main + * @package %g_namespace%\Main */ declare(strict_types=1); -namespace EightshiftBoilerplate\Main; +namespace %g_namespace%\Main; -use EightshiftLibs\Main\AbstractMain; +use %g_use_libs%\Main\AbstractMain; /** * The main start class. diff --git a/src/Media/MediaCli.php b/src/Media/MediaCli.php index 2a008c3c0..c4b0fca88 100644 --- a/src/Media/MediaCli.php +++ b/src/Media/MediaCli.php @@ -12,7 +12,7 @@ use EightshiftLibs\Cli\AbstractCli; use EightshiftLibs\Cli\ParentGroups\CliCreate; -use EightshiftLibs\Helpers\Components; +use EightshiftLibs\Helpers\Helpers; /** * Class MediaCli @@ -69,6 +69,8 @@ public function getDoc(): array /* @phpstan-ignore-next-line */ public function __invoke(array $args, array $assocArgs) { + $assocArgs = $this->prepareArgs($assocArgs); + $this->getIntroText($assocArgs); $className = $this->getClassShortName(); @@ -76,8 +78,7 @@ public function __invoke(array $args, array $assocArgs) // Read the template contents, and replace the placeholders with provided variables. $this->getExampleTemplate(__DIR__, $className) ->renameClassName($className) - ->renameNamespace($assocArgs) - ->renameUse($assocArgs) - ->outputWrite(Components::getProjectPaths('srcDestination', 'Media'), "{$className}.php", $assocArgs); + ->renameGlobals($assocArgs) + ->outputWrite(Helpers::getProjectPaths('srcDestination', 'Media'), "{$className}.php", $assocArgs); } } diff --git a/src/Media/MediaExample.php b/src/Media/MediaExample.php index 43eae11c8..aa7d505a8 100644 --- a/src/Media/MediaExample.php +++ b/src/Media/MediaExample.php @@ -3,14 +3,14 @@ /** * The Media specific functionality. * - * @package EightshiftBoilerplate\Media + * @package %g_namespace%\Media */ declare(strict_types=1); -namespace EightshiftBoilerplate\Media; +namespace %g_namespace%\Media; -use EightshiftLibs\Media\AbstractMedia; +use %g_use_libs%\Media\AbstractMedia; /** * Class MediaExample diff --git a/src/Media/RegenerateWebPMediaCli.php b/src/Media/RegenerateWebPMediaCli.php index 534ddcebb..db1ede09f 100644 --- a/src/Media/RegenerateWebPMediaCli.php +++ b/src/Media/RegenerateWebPMediaCli.php @@ -143,6 +143,8 @@ public function getDoc(): array /* @phpstan-ignore-next-line */ public function __invoke(array $args, array $assocArgs) { + $assocArgs = $this->prepareArgs($assocArgs); + $this->getIntroText($assocArgs); $quality = $this->getArg($assocArgs, 'quality'); diff --git a/src/Media/UseWebPMediaCli.php b/src/Media/UseWebPMediaCli.php index 5ffee6ee3..33fd7a99e 100644 --- a/src/Media/UseWebPMediaCli.php +++ b/src/Media/UseWebPMediaCli.php @@ -76,6 +76,8 @@ public function getDoc(): array /* @phpstan-ignore-next-line */ public function __invoke(array $args, array $assocArgs) { + $assocArgs = $this->prepareArgs($assocArgs); + $this->getIntroText($assocArgs); if (\get_option(self::USE_WEBP_MEDIA_OPTION_NAME)) { diff --git a/src/Menu/AbstractMenu.php b/src/Menu/AbstractMenu.php index e8d859a39..591915801 100644 --- a/src/Menu/AbstractMenu.php +++ b/src/Menu/AbstractMenu.php @@ -38,50 +38,4 @@ public function getMenuPositions(): array { return []; } - - /** - * This method returns an instance of the bemMenuWalker class with the following arguments - * - * @param string $location This must be the same as what is set in wp-admin/settings/menus - * for menu location and registered in registerMenuPositions function. - * @param string $cssClassPrefix This string will prefix all of the menu's classes, BEM syntax friendly. - * @param string $parentClass This string will add class to only top level list element. - * @param string $cssClassModifiers Provide either a string or array of values to apply extra classes - * to the
    but not the . - * @param bool $outputMenu Echo the menu. - * - * @return string|false|void Menu output if $outputMenu is false, false if there are no items or no menu was found. - */ - public static function bemMenu( - string $location = 'main_menu', - string $cssClassPrefix = 'main-menu', - string $parentClass = '', - $cssClassModifiers = '', - bool $outputMenu = true - ) { - // Check to see if any CSS modifiers were supplied. - $modifiers = ''; - - if (!empty($cssClassModifiers)) { - if (\is_array($cssClassModifiers)) { - $modifiers = \implode(' ', $cssClassModifiers); - } elseif (\is_string($cssClassModifiers)) { - $modifiers = $cssClassModifiers; - } - } - - $args = [ - 'theme_location' => $location, - 'container' => false, - 'items_wrap' => '
      %3$s
    ', - 'echo' => $outputMenu, - 'walker' => new BemMenuWalker($cssClassPrefix), - ]; - - if (!\has_nav_menu($location)) { - return ''; - } - - return \wp_nav_menu($args); // @phpstan-ignore-line - } } diff --git a/src/Menu/BemMenuWalker.php b/src/Menu/BemMenuWalker.php deleted file mode 100644 index 3e3f6341e..000000000 --- a/src/Menu/BemMenuWalker.php +++ /dev/null @@ -1,231 +0,0 @@ -cssClassPrefix = $cssClassPrefix; - - // Define menu item names appropriately. - $this->itemCssClassSuffixes = [ - 'item' => '__item', - 'parent_item' => '__item--parent', - 'active_item' => '__item--active', - 'parent_of_active_item' => '__item--parent--active', - 'ancestor_of_active_item' => '__item--ancestor--active', - 'sub_menu' => '__sub-menu', - 'sub_menu_item' => '__sub-menu__item', - 'link' => '__link', - ]; - } - - /** - * Display element for walker - * - * @param object $element Data object. - * @param array> $children_elements List of elements to continue traversing (passed by reference). - * @param int $max_depth Max depth to traverse. - * @param int $depth Depth of current element. - * @param Object[] $args An array of arguments. - * @param string $output Used to append additional content (passed by reference). - * - * @return void Parent Display element - *@see \Walker::display_element() - * - */ - public function display_element( // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps, PEAR.Functions.ValidDefaultValue.NotAtEnd - $element, - &$children_elements, - $max_depth, // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps, PEAR.Functions.ValidDefaultValue.NotAtEnd - $depth, - $args, // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps, PEAR.Functions.ValidDefaultValue.NotAtEnd - &$output - ) { - $id_field = $this->db_fields['id']; - - if (isset($args[0]-> has_children)) { - $args[0]->has_children = !empty($children_elements[$element->$id_field]); - } - - parent::display_element($element, $children_elements, $max_depth, $depth, $args, $output); - } - - /** - * Start level - * - * @see \Walker_Nav_Menu::start_lvl() - * - * @param string $output Used to append additional content (passed by reference). - * @param int $depth Depth of menu item. Used for padding. - * @param \stdClass|null $args An object of wp_nav_menu() arguments. - * - * @return void - */ - public function start_lvl( // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps, PEAR.Functions.ValidDefaultValue.NotAtEnd - &$output, - $depth = 1, - $args = null - ) { - $real_depth = $depth + 1; - - $indent = str_repeat("\t", $real_depth); - - $prefix = $this->cssClassPrefix; - $suffix = $this->itemCssClassSuffixes; - - $classes = [ - $prefix . $suffix['sub_menu'], - $prefix . $suffix['sub_menu'] . '--' . $real_depth, - ]; - - $classNames = \implode(' ', $classes); - - // Add a ul wrapper to sub nav. - $output .= "\n" . $indent . '
      ' . "\n"; - } - - /** - * Add main/sub classes to li's and links. - * - * @param string $output Used to append additional content (passed by reference). - * @param \WP_Post $item Menu item data object. - * @param int $depth Depth of menu item. Used for padding. - * @param \stdClass|null $args An object of wp_nav_menu() arguments. - * @param int $id Current item ID. - * - * @return void - * @see \Walker_Nav_Menu::start_el() - * - */ - public function start_el( // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps, PEAR.Functions.ValidDefaultValue.NotAtEnd - &$output, - $item, - $depth = 0, - $args = null, - $id = 0 - ) { - $indent = ($depth > 0 ? str_repeat(' ', $depth) : ''); // code indent. - - $prefix = $this->cssClassPrefix; - $suffix = $this->itemCssClassSuffixes; - - $parent_class = $prefix . $suffix['parent_item']; - - $itemClasses = []; - - if (!empty($item->classes)) { - $userClasses = \array_map( - function ($className) use ($prefix) { - if (\strpos($className, 'js-') !== false) { - $output = $className; - } else { - $output = $prefix . '__item--' . $className; - } - return $output; - }, - $item->classes - ); - - // Item classes. - $itemClasses = [ - 'item_class' => 0 === $depth ? $prefix . $suffix['item'] : '', - 'parent_class' => isset($args->has_children) && $args->has_children ? $parent_class : '', - 'active_page_class' => \in_array( - 'current-menu-item', - $item->classes, - true - ) ? $prefix . $suffix['active_item'] : '', - 'active_parent_class' => \in_array( - 'current-menu-parent', - $item->classes, - true - ) ? $prefix . $suffix['parent_of_active_item'] : '', - 'active_ancestor_class' => \in_array( - 'current-page-ancestor', - $item->classes, - true - ) ? $prefix . $suffix['ancestor_of_active_item'] : '', - 'depth_class' => $depth >= 1 ? $prefix . $suffix['sub_menu_item'] . ' ' . $prefix . $suffix['sub_menu'] . '--' . $depth . '__item' : '', - 'item_id_class' => property_exists($item, 'object_id') ? $prefix . '__item--' . $item->object_id : '', - 'user_class' => !empty($userClasses) ? \implode(' ', $userClasses) : '', - ]; - } - - // Convert array to string excluding any empty values. - $itemClasses = \apply_filters('walker_nav_menu_item_classes', $itemClasses, $item, $depth, $args); - $class_string = !empty($itemClasses) ? \implode(' ', \array_filter($itemClasses)) : ''; - - // Add the classes to the wrapping
    • . - $output .= $indent . '
    • '; - - // Link classes. - $link_classes = [ - 'item_link' => 0 === $depth ? $prefix . $suffix['link'] : '', - 'depth_class' => $depth >= 1 ? $prefix . $suffix['sub_menu'] . $suffix['link'] . ' ' . $prefix . $suffix['sub_menu'] . '--' . $depth . $suffix['link'] : '', - ]; - - $link_class_string = \implode(' ', \array_filter($link_classes)); - - $link_class_output = 'class="' . $link_class_string . ' "'; - - $link_text_classes = [ - 'item_link' => 0 === $depth ? $prefix . $suffix['link'] . '-text' : '', - 'depth_class' => $depth >= 1 ? $prefix . $suffix['sub_menu'] . $suffix['link'] . '-text ' . $prefix . $suffix['sub_menu'] . '--' . $depth . $suffix['link'] . '-text' : '', - ]; - - $link_text_class_string = \implode(' ', \array_filter($link_text_classes)); - $link_text_class_output = 'class="' . $link_text_class_string . '"'; - - // link attributes. - $attributes = !empty($item->attr_title) ? ' title="' . esc_attr($item->attr_title) . '"' : ''; - $attributes .= !empty($item->target) ? ' target="' . esc_attr($item->target) . '"' : ''; - $attributes .= !empty($item->xfn) ? ' rel="' . esc_attr($item->xfn) . '"' : ''; - $attributes .= !empty($item->url) ? ' href="' . esc_attr($item->url) . '"' : ''; - - // Create link markup. - $item_output = !empty($args->before) ? $args->before : ''; - $item_output .= ''; - $item_output .= !empty($args->link_before) ? $args->link_before : ''; - $item_output .= !empty($item->title) ? apply_filters('the_title', $item->title, $item->ID) : ''; - $item_output .= !empty($args->link_after) ? $args->link_after : ''; - $item_output .= !empty($args->after) ? $args->after : ''; - $item_output .= ''; - - $output .= apply_filters('walker_nav_menu_link_element', $item_output, $item, $depth, $args); - } -} diff --git a/src/Menu/MenuCli.php b/src/Menu/MenuCli.php index cb9304c77..197f6beb3 100644 --- a/src/Menu/MenuCli.php +++ b/src/Menu/MenuCli.php @@ -12,7 +12,7 @@ use EightshiftLibs\Cli\AbstractCli; use EightshiftLibs\Cli\ParentGroups\CliCreate; -use EightshiftLibs\Helpers\Components; +use EightshiftLibs\Helpers\Helpers; /** * Class MenuCli @@ -69,6 +69,8 @@ public function getDoc(): array /* @phpstan-ignore-next-line */ public function __invoke(array $args, array $assocArgs) { + $assocArgs = $this->prepareArgs($assocArgs); + $this->getIntroText($assocArgs); $className = $this->getClassShortName(); @@ -76,9 +78,7 @@ public function __invoke(array $args, array $assocArgs) // Read the template contents, and replace the placeholders with provided variables. $this->getExampleTemplate(__DIR__, $className) ->renameClassName($className) - ->renameNamespace($assocArgs) - ->renameUse($assocArgs) - ->renameTextDomain($assocArgs) - ->outputWrite(Components::getProjectPaths('srcDestination', 'Menu'), "{$className}.php", $assocArgs); + ->renameGlobals($assocArgs) + ->outputWrite(Helpers::getProjectPaths('srcDestination', 'Menu'), "{$className}.php", $assocArgs); } } diff --git a/src/Menu/MenuExample.php b/src/Menu/MenuExample.php index 46de344ca..813ea685c 100644 --- a/src/Menu/MenuExample.php +++ b/src/Menu/MenuExample.php @@ -3,14 +3,14 @@ /** * The Menu specific functionality. * - * @package EightshiftBoilerplate\Menu + * @package %g_namespace%\Menu */ declare(strict_types=1); -namespace EightshiftBoilerplate\Menu; +namespace %g_namespace%\Menu; -use EightshiftLibs\Menu\AbstractMenu; +use %g_use_libs%\Menu\AbstractMenu; /** * Class MenuExample @@ -35,7 +35,7 @@ public function register(): void public function getMenuPositions(): array { return [ - 'header_main_nav' => \esc_html__('Main Menu', 'eightshift-libs'), + 'header_main_nav' => \esc_html__('Main Menu', '%g_textdomain%'), ]; } } diff --git a/src/Misc/VersionCli.php b/src/Misc/VersionCli.php index 26b4e7bfb..07d30ef9f 100644 --- a/src/Misc/VersionCli.php +++ b/src/Misc/VersionCli.php @@ -12,7 +12,7 @@ use EightshiftLibs\Cli\AbstractCli; use EightshiftLibs\Cli\ParentGroups\CliRun; -use EightshiftLibs\Helpers\Components; +use EightshiftLibs\Helpers\Helpers; /** * Class VersionCli @@ -90,32 +90,34 @@ public function getDoc(): array /* @phpstan-ignore-next-line */ public function __invoke(array $args, array $assocArgs) { + $assocArgs = $this->prepareArgs($assocArgs); + $this->getIntroText($assocArgs); // Get Props. $version = $this->getArg($assocArgs, 'version'); - $assocArgs['skip_existing'] = 'true'; + $assocArgs[AbstractCli::ARG_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'); + $path = Helpers::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))) { + if (\file_exists(Helpers::getProjectPaths('cliOutput', $file))) { $this->getExampleTemplate($path, $file, true) ->renameVersionString($version) - ->outputWrite(Components::getProjectPaths('cliOutput'), $file, $assocArgs); + ->renameGlobals($assocArgs) + ->outputWrite(Helpers::getProjectPaths('cliOutput'), $file, $assocArgs); } } } diff --git a/src/ModifyAdminAppearance/ModifyAdminAppearanceCli.php b/src/ModifyAdminAppearance/ModifyAdminAppearanceCli.php index 903b3f57f..68350e688 100644 --- a/src/ModifyAdminAppearance/ModifyAdminAppearanceCli.php +++ b/src/ModifyAdminAppearance/ModifyAdminAppearanceCli.php @@ -12,7 +12,7 @@ use EightshiftLibs\Cli\AbstractCli; use EightshiftLibs\Cli\ParentGroups\CliCreate; -use EightshiftLibs\Helpers\Components; +use EightshiftLibs\Helpers\Helpers; /** * Class ModifyAdminAppearanceCli @@ -69,6 +69,8 @@ public function getDoc(): array /* @phpstan-ignore-next-line */ public function __invoke(array $args, array $assocArgs) { + $assocArgs = $this->prepareArgs($assocArgs); + $this->getIntroText($assocArgs); $className = $this->getClassShortName(); @@ -76,8 +78,7 @@ public function __invoke(array $args, array $assocArgs) // Read the template contents, and replace the placeholders with provided variables. $this->getExampleTemplate(__DIR__, $className) ->renameClassName($className) - ->renameNamespace($assocArgs) - ->renameUse($assocArgs) - ->outputWrite(Components::getProjectPaths('srcDestination', 'ModifyAdminAppearance'), "{$className}.php", $assocArgs); + ->renameGlobals($assocArgs) + ->outputWrite(Helpers::getProjectPaths('srcDestination', 'ModifyAdminAppearance'), "{$className}.php", $assocArgs); } } diff --git a/src/ModifyAdminAppearance/ModifyAdminAppearanceExample.php b/src/ModifyAdminAppearance/ModifyAdminAppearanceExample.php index a717a2ecd..5dab5957e 100644 --- a/src/ModifyAdminAppearance/ModifyAdminAppearanceExample.php +++ b/src/ModifyAdminAppearance/ModifyAdminAppearanceExample.php @@ -3,14 +3,14 @@ /** * Modify WordPress admin behavior * - * @package EightshiftBoilerplate\ModifyAdminAppearance + * @package %g_namespace%\ModifyAdminAppearance */ declare(strict_types=1); -namespace EightshiftBoilerplate\ModifyAdminAppearance; +namespace %g_namespace%\ModifyAdminAppearance; -use EightshiftLibs\Services\ServiceInterface; +use %g_use_libs%\Services\ServiceInterface; /** * Class that modifies some administrator appearance diff --git a/src/Readme/ReadmeCli.php b/src/Readme/ReadmeCli.php index 72bd7f53b..5abde6588 100644 --- a/src/Readme/ReadmeCli.php +++ b/src/Readme/ReadmeCli.php @@ -12,7 +12,7 @@ use EightshiftLibs\Cli\AbstractCli; use EightshiftLibs\Cli\ParentGroups\CliCreate; -use EightshiftLibs\Helpers\Components; +use EightshiftLibs\Helpers\Helpers; /** * Class ReadmeCli @@ -47,7 +47,7 @@ public function getCommandName(): string public function getDefaultArgs(): array { return [ - 'path' => Components::getProjectPaths('projectRoot'), + 'path' => Helpers::getProjectPaths('projectRoot'), ]; } @@ -91,6 +91,8 @@ public function getDoc(): array /* @phpstan-ignore-next-line */ public function __invoke(array $args, array $assocArgs) { + $assocArgs = $this->prepareArgs($assocArgs); + $this->getIntroText($assocArgs); // Get Props. @@ -98,6 +100,7 @@ public function __invoke(array $args, array $assocArgs) // Read the template contents, and replace the placeholders with provided variables. $this->getExampleTemplate(__DIR__, 'README.md') + ->renameGlobals($assocArgs) ->outputWrite($path, 'README.md', $assocArgs); } } diff --git a/src/Rest/Fields/FieldCli.php b/src/Rest/Fields/FieldCli.php index 30a5c4241..920baa7fc 100644 --- a/src/Rest/Fields/FieldCli.php +++ b/src/Rest/Fields/FieldCli.php @@ -12,7 +12,7 @@ use EightshiftLibs\Cli\AbstractCli; use EightshiftLibs\Cli\ParentGroups\CliCreate; -use EightshiftLibs\Helpers\Components; +use EightshiftLibs\Helpers\Helpers; /** * Class FieldCli @@ -97,6 +97,8 @@ public function getDoc(): array /* @phpstan-ignore-next-line */ public function __invoke(array $args, array $assocArgs) { + $assocArgs = $this->prepareArgs($assocArgs); + $this->getIntroText($assocArgs); // Get Props. @@ -110,10 +112,9 @@ public function __invoke(array $args, array $assocArgs) // Read the template contents, and replace the placeholders with provided variables. $this->getExampleTemplate(__DIR__, $this->getClassShortName()) ->renameClassNameWithPrefix($this->getClassShortName(), $className) - ->renameNamespace($assocArgs) - ->renameUse($assocArgs) + ->renameGlobals($assocArgs) ->searchReplaceString($this->getArgTemplate('object_type'), $objectType) ->searchReplaceString($this->getArgTemplate('field_name'), $fieldName) - ->outputWrite(Components::getProjectPaths('srcDestination', 'Rest' . \DIRECTORY_SEPARATOR . 'Fields'), "{$className}.php", $assocArgs); + ->outputWrite(Helpers::getProjectPaths('srcDestination', 'Rest' . \DIRECTORY_SEPARATOR . 'Fields'), "{$className}.php", $assocArgs); } } diff --git a/src/Rest/Fields/FieldExample.php b/src/Rest/Fields/FieldExample.php index 3d4c057a1..767dd62cf 100644 --- a/src/Rest/Fields/FieldExample.php +++ b/src/Rest/Fields/FieldExample.php @@ -3,15 +3,15 @@ /** * The class register field for example endpoint * - * @package EightshiftBoilerplate\Rest\Fields + * @package %g_namespace%\Rest\Fields */ declare(strict_types=1); -namespace EightshiftBoilerplate\Rest\Fields; +namespace %g_namespace%\Rest\Fields; -use EightshiftLibs\Rest\Fields\AbstractField; -use EightshiftLibs\Rest\CallableFieldInterface; +use %g_use_libs%\Rest\Fields\AbstractField; +use %g_use_libs%\Rest\CallableFieldInterface; /** * Class FieldExample diff --git a/src/Rest/Routes/LoadMore/LoadMoreRouteCli.php b/src/Rest/Routes/LoadMore/LoadMoreRouteCli.php index 57fb99c51..24c3c46fb 100644 --- a/src/Rest/Routes/LoadMore/LoadMoreRouteCli.php +++ b/src/Rest/Routes/LoadMore/LoadMoreRouteCli.php @@ -12,7 +12,7 @@ use EightshiftLibs\Cli\AbstractCli; use EightshiftLibs\Cli\ParentGroups\CliCreate; -use EightshiftLibs\Helpers\Components; +use EightshiftLibs\Helpers\Helpers; /** * Class LoadMoreRouteCli @@ -69,6 +69,8 @@ public function getDoc(): array /* @phpstan-ignore-next-line */ public function __invoke(array $args, array $assocArgs) { + $assocArgs = $this->prepareArgs($assocArgs); + $sep = \DIRECTORY_SEPARATOR; $this->getIntroText($assocArgs); @@ -77,9 +79,7 @@ public function __invoke(array $args, array $assocArgs) // Read the template contents, and replace the placeholders with provided variables. $this->getExampleTemplate(__DIR__, $className) ->renameClassName($className) - ->renameNamespace($assocArgs) - ->renameUse($assocArgs) - ->renameTextDomain($assocArgs) - ->outputWrite(Components::getProjectPaths('srcDestination', "Rest{$sep}Routes{$sep}LoadMore"), "{$className}.php", $assocArgs); + ->renameGlobals($assocArgs) + ->outputWrite(Helpers::getProjectPaths('srcDestination', "Rest{$sep}Routes{$sep}LoadMore"), "{$className}.php", $assocArgs); } } diff --git a/src/Rest/Routes/LoadMore/LoadMoreRouteExample.php b/src/Rest/Routes/LoadMore/LoadMoreRouteExample.php index a978c0ac2..da79b8867 100644 --- a/src/Rest/Routes/LoadMore/LoadMoreRouteExample.php +++ b/src/Rest/Routes/LoadMore/LoadMoreRouteExample.php @@ -3,17 +3,17 @@ /** * The class register load more route. * - * @package EightshiftBoilerplate\Rest\Routes\LoadMore + * @package %g_namespace%\Rest\Routes\LoadMore */ declare(strict_types=1); -namespace EightshiftBoilerplate\Rest\Routes\LoadMore; +namespace %g_namespace%\Rest\Routes\LoadMore; -use EightshiftBoilerplate\Config\Config; -use EightshiftLibs\Helpers\Components; -use EightshiftLibs\Rest\CallableRouteInterface; -use EightshiftLibs\Rest\Routes\AbstractRoute; +use %g_namespace%\Config\Config; +use %g_use_libs%\Helpers\Helpers; +use %g_use_libs%\Rest\CallableRouteInterface; +use %g_use_libs%\Rest\Routes\AbstractRoute; use WP_Error; use WP_Query; use WP_REST_Request; @@ -33,7 +33,7 @@ final class LoadMoreRouteExample extends AbstractRoute implements CallableRouteI /** * Method that returns project Route namespace. * - * @return string Project namespace EightshiftBoilerplateVendor\for REST route. + * @return string Project namespace for REST route. */ protected function getNamespace(): string { @@ -86,13 +86,14 @@ public function getMappedData(string $type, array $response): string { switch ($type) { case 'featured-content': - return Components::renderPartial( - 'block', - $type, + return Helpers::render( 'cards', [ 'items' => $response, - ] + ], + 'blocks', + false, + "{$type}/partials" ); default: return ''; diff --git a/src/Rest/Routes/RouteCli.php b/src/Rest/Routes/RouteCli.php index 19c9beac4..39d4973bb 100644 --- a/src/Rest/Routes/RouteCli.php +++ b/src/Rest/Routes/RouteCli.php @@ -12,7 +12,7 @@ use EightshiftLibs\Cli\AbstractCli; use EightshiftLibs\Cli\ParentGroups\CliCreate; -use EightshiftLibs\Helpers\Components; +use EightshiftLibs\Helpers\Helpers; use WP_CLI; /** @@ -118,6 +118,8 @@ public function getDoc(): array /* @phpstan-ignore-next-line */ public function __invoke(array $args, array $assocArgs) { + $assocArgs = $this->prepareArgs($assocArgs); + $this->getIntroText($assocArgs); // Get Props. @@ -138,10 +140,9 @@ public function __invoke(array $args, array $assocArgs) // Read the template contents, and replace the placeholders with provided variables. $this->getExampleTemplate(__DIR__, $this->getClassShortName()) ->renameClassNameWithPrefix($this->getClassShortName(), $className) - ->renameNamespace($assocArgs) - ->renameUse($assocArgs) + ->renameGlobals($assocArgs) ->searchReplaceString($this->getArgTemplate('endpoint_slug'), $endpointSlug) ->searchReplaceString("'{$this->getArgTemplate('method')}'", static::VERB_ENUM[$method]) - ->outputWrite(Components::getProjectPaths('srcDestination', 'Rest' . \DIRECTORY_SEPARATOR . 'Routes'), "{$className}.php", $assocArgs); + ->outputWrite(Helpers::getProjectPaths('srcDestination', 'Rest' . \DIRECTORY_SEPARATOR . 'Routes'), "{$className}.php", $assocArgs); } } diff --git a/src/Rest/Routes/RouteExample.php b/src/Rest/Routes/RouteExample.php index 22ab3dbc9..fa8a4b25c 100644 --- a/src/Rest/Routes/RouteExample.php +++ b/src/Rest/Routes/RouteExample.php @@ -3,16 +3,16 @@ /** * The class register route for $className endpoint * - * @package EightshiftBoilerplate\Rest\Routes + * @package %g_namespace%\Rest\Routes */ declare(strict_types=1); -namespace EightshiftBoilerplate\Rest\Routes; +namespace %g_namespace%\Rest\Routes; -use EightshiftBoilerplate\Config\Config; -use EightshiftLibs\Rest\Routes\AbstractRoute; -use EightshiftLibs\Rest\CallableRouteInterface; +use %g_namespace%\Config\Config; +use %g_use_libs%\Rest\Routes\AbstractRoute; +use %g_use_libs%\Rest\CallableRouteInterface; use WP_REST_Request; /** diff --git a/src/Services/ServiceExample.php b/src/Services/ServiceExample.php index 387ff9ac8..c624cb606 100644 --- a/src/Services/ServiceExample.php +++ b/src/Services/ServiceExample.php @@ -3,14 +3,14 @@ /** * The file that is an ServiceExample class. * - * @package EightshiftBoilerplate\Services; + * @package %g_namespace%\Services; */ declare(strict_types=1); -namespace EightshiftBoilerplate\Services; +namespace %g_namespace%\Services; -use EightshiftLibs\Services\ServiceInterface; +use %g_use_libs%\Services\ServiceInterface; /** * ServiceExample class. diff --git a/src/Services/ServiceExampleCli.php b/src/Services/ServiceExampleCli.php index 7feb4daf0..c215d8028 100644 --- a/src/Services/ServiceExampleCli.php +++ b/src/Services/ServiceExampleCli.php @@ -12,7 +12,7 @@ use EightshiftLibs\Cli\AbstractCli; use EightshiftLibs\Cli\ParentGroups\CliCreate; -use EightshiftLibs\Helpers\Components; +use EightshiftLibs\Helpers\Helpers; /** * Class ServiceExampleCli @@ -54,7 +54,7 @@ public function getDefaultArgs(): array $sep = \DIRECTORY_SEPARATOR; return [ - 'folder' => "TestFolder{$sep}TMP", + 'folder' => "TestFolder{$sep}Tmp", 'file_name' => 'TestTest', ]; } @@ -103,6 +103,8 @@ public function getDoc(): array /* @phpstan-ignore-next-line */ public function __invoke(array $args, array $assocArgs) { + $assocArgs = $this->prepareArgs($assocArgs); + $this->getIntroText($assocArgs); // Get Props. @@ -127,9 +129,8 @@ function ($item) { // Read the template contents, and replace the placeholders with provided variables. $this->getExampleTemplate(__DIR__, static::TEMPLATE) ->searchReplaceString($className, $classNameNew) - ->renameNamespace($assocArgs) - ->renameUse($assocArgs) + ->renameGlobals($assocArgs) ->searchReplaceString('\\Services;', "{$newNamespace};") - ->outputWrite(Components::getProjectPaths('srcDestination', $folder), "{$classNameNew}.php", $assocArgs); + ->outputWrite(Helpers::getProjectPaths('srcDestination', $folder), "{$classNameNew}.php", $assocArgs); } } diff --git a/src/Setup/PluginManageCli.php b/src/Setup/PluginManageCli.php deleted file mode 100644 index 4349e4cae..000000000 --- a/src/Setup/PluginManageCli.php +++ /dev/null @@ -1,526 +0,0 @@ - - */ - private array $cliOptions = [ - 'return' => true, - 'parse' => 'json', - 'launch' => false, - 'exit_error' => true, - ]; - - /** - * Get WPCLI command parent name - * - * @return string - */ - public function getCommandParentName(): string - { - return CliRun::COMMAND_NAME; - } - - /** - * Get WPCLI command name - * - * @return string - */ - public function getCommandName(): string - { - return 'plugin-manage'; - } - - /** - * Define default arguments. - * - * By default, only the 'core' plugins (from wordpress.org) - * will be installed if the command is run without any arguments - * - * @return array - */ - public function getDefaultArgs(): array - { - return [ - 'delete-plugins' => 'false', - 'install-core' => 'false', - 'install-github' => 'false', - 'install-paid' => 'false', - ]; - } - - /** - * Get WPCLI command doc - * - * @return array - */ - public function getDoc(): array - { - return [ - 'shortdesc' => 'Install or update the WordPress plugins based on the setup.json file.', - 'synopsis' => [ - [ - 'type' => 'flag', - 'name' => 'delete-plugins', - 'description' => 'If you want to delete plugins that are not in the setup.json list.', - 'optional' => true, - ], - [ - 'type' => 'flag', - 'name' => 'install-core', - 'description' => 'If you want to install only the wordpress.org plugins.', - 'optional' => true, - ], - [ - 'type' => 'flag', - 'name' => 'install-github', - 'description' => 'If you want to install only the plugins from github.org.', - 'optional' => true, - ], - [ - 'type' => 'flag', - 'name' => 'install-paid', - 'description' => << true, - ], - ], - 'longdesc' => $this->prepareLongDesc(" - ## USAGE - This command will install, delete or update the plugins based on the setup.json file. - - In order to install the premium plugins you will need to have an env.json file which - is usually stored in a secret vault. That file should looks something like this: - - { - \"advanced-custom-fields-pro\": \"url==&t=VERSION\", - \"wp-rocket\": \"url\", - } - - If the URL contains the VERSION string, that version will be replaced with the version - defined in the setup.json file. Otherwise the latest version available from the URL will be downloaded. - - ## EXAMPLES - # Install/update all the plugins, delete unused plugins: - $ wp boilerplate {$this->getCommandParentName()} {$this->getCommandName()} - # Install/update only the wp.org plugins: - $ wp boilerplate {$this->getCommandParentName()} {$this->getCommandName()} --install-core' - - # Install/update only the paid plugins: - $ wp boilerplate {$this->getCommandParentName()} {$this->getCommandName()} --install-paid' - - # Delete plugins not in the setup.json list: - $ wp boilerplate {$this->getCommandParentName()} {$this->getCommandName()} --delete-plugins' - "), - ]; - } - - /* @phpstan-ignore-next-line */ - public function __invoke(array $args, array $assocArgs) - { - $setup = []; - - try { - $setup = $this->getSetupFile(); - } catch (InvalidPath $exception) { - self::cliError($exception->getMessage()); - } - - /** - * Check associated arguments. Based on which one is present - * toggle the behavior of the CLI command. - */ - if (isset($assocArgs['install-core'])) { - $this->installWpOrgPlugins($setup); - return; - } - - if (isset($assocArgs['install-github'])) { - $this->installGitHubPlugins($setup); - return; - } - - if (isset($assocArgs['install-paid'])) { - $this->installPaidPlugins($setup); - return; - } - - if (isset($assocArgs['delete-plugins'])) { - $this->deletePlugins($setup); - return; - } - - $this->manageAllPlugins($setup); - } - - /** - * Install plugins from wp.org - * - * @param array $setup setup.json array. - * - * @return void - */ - private function installWpOrgPlugins(array $setup) - { - $coreSetupPlugins = $setup['plugins']['core'] ?? []; - - if (empty($coreSetupPlugins)) { - WP_CLI::warning('There are no wordpress.org plugins to install.'); - return; - } - - // We only need a list of plugin names, so we'll filter the above return value. - $installedPlugins = \array_map(function ($pluginElement) { - return $pluginElement['name'] ?? ''; - }, $this->getCurrentlyInstalledPlugins()); - - $pluginsToAdd = \array_diff(\array_keys($coreSetupPlugins), $installedPlugins); - - foreach ($pluginsToAdd as $pluginToAdd) { - WP_CLI::runcommand("plugin install {$pluginToAdd} --force", $this->cliOptions); - WP_CLI::success("Plugin {$pluginToAdd} installed"); - } - } - - /** - * Install plugins from GitHub - * - * @param array $setup setup.json array. - * - * @return void - */ - private function installGitHubPlugins(array $setup) - { - $ghSetupPlugins = $setup['plugins']['github'] ?? []; - - if (empty($ghSetupPlugins)) { - WP_CLI::warning('There are no GitHub plugins to install.'); - return; - } - - // We only need a list of plugin names, so we'll filter the above return value. - $installedPlugins = \array_map(function ($pluginElement) { - return $pluginElement['name'] ?? ''; - }, $this->getCurrentlyInstalledPlugins()); - - list($ghPlugins, $ghPluginsRepo) = $this->getGitHubPluginsInfo($ghSetupPlugins); - - $gitHubPlugins = \array_keys($ghPlugins); // Get just the names of the plugins. - - $pluginsToAdd = \array_diff($gitHubPlugins, $installedPlugins); - - foreach ($pluginsToAdd as $pluginToAdd) { - if (isset(\array_flip($gitHubPlugins)[$pluginToAdd])) { - $repoName = $ghPluginsRepo[$pluginToAdd]; - $version = $ghPlugins[$pluginToAdd]; - - $this->installGHPlugin($repoName, $version); - } - - WP_CLI::success("Plugin {$pluginToAdd} installed"); - } - } - - /** - * Install paid plugins - * - * Depends on the existence of env.json file. - * - * @param array $setup setup.json array. - * - * @return void - */ - private function installPaidPlugins(array $setup) - { - $paidSetupPlugins = $setup['plugins']['paid'] ?? []; - - if (empty($paidSetupPlugins)) { - WP_CLI::warning('There are no paid plugins to install.'); - return; - } - - // We only need a list of plugin names, so we'll filter the above return value. - $installedPlugins = \array_map(function ($pluginElement) { - return $pluginElement['name'] ?? ''; - }, $this->getCurrentlyInstalledPlugins()); - - $paidPlugins = \array_keys($paidSetupPlugins); // Get just the names of the plugins. - - $pluginsToAdd = \array_diff($paidPlugins, $installedPlugins); - - foreach ($pluginsToAdd as $pluginToAdd) { - if (isset(\array_flip($paidPlugins)[$pluginToAdd])) { - $version = $paidSetupPlugins[$pluginToAdd]; - - try { - $this->installPaidPlugin($pluginToAdd, $version); - } catch (InvalidPath $exception) { - self::cliError($exception->getMessage()); - } - } - - WP_CLI::success("Plugin {$pluginToAdd} installed"); - } - } - - /** - * Install or updates all plugins - * - * @param array $setup setup.json array. - * - * @return void - */ - private function manageAllPlugins(array $setup) - { - - // Delete unused plugins. - $this->deletePlugins($setup); - - // Install all the other plugins. - $this->installWpOrgPlugins($setup); - $this->installGitHubPlugins($setup); - $this->installPaidPlugins($setup); - - // Check plugin versions and update if needed. - $this->updatePlugins($setup); - } - - /** - * Helper used to install the plugin from GitHub - * - * Will install the plugin, and rename the folder, so it's not hashed. - * - * @param string $name Plugin slug. - * @param string $version Plugin version number. - * - * @return void - */ - private function installGHPlugin(string $name, string $version): void - { - WP_CLI::runcommand("plugin install \"https://github.com/{$name}/releases/download/{$version}/release.zip\" --force"); - } - - /** - * Helper to install paid plugins - * - * If the URL of the paid plugin has a version placeholder - * will replace the placeholder with the version set in the setup.json. - * - * @param string $name Plugin slug. - * @param string $version Plugin version. - * - * @return void - * - * @throws InvalidPath Exception in case the env.json file is missing. - */ - private function installPaidPlugin(string $name, string $version): void - { - // Check if env.json exist. - $envFile = Components::getProjectPaths('projectRoot') . 'env.json'; - - // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison -- in tests sometimes the env var is 'true' string, sometimes it's '1'. Loose comparison fixes this issue. - if (\getenv('ES_TEST') == true) { - $envFile = Components::getProjectPaths('testsData') . 'env.json'; - } - - if (!\file_exists($envFile)) { - throw InvalidPath::missingFileException($envFile); - } - - $envData = \json_decode((string)\file_get_contents($envFile), true); - - $plugin = $envData[$name]; - - if (\strpos($plugin, 'VERSION') !== false) { - $pluginUrl = \str_replace('VERSION', $version, $plugin); - } else { - $pluginUrl = $plugin; - } - - // Install plugin. - WP_CLI::runcommand("plugin install \"{$pluginUrl}\" --force"); - } - - /** - * Get the array of the decoded setup.json file - * - * @return array setup.json file in array form. - * - * @throws InvalidPath Throws exception in case the setup.json file is missing. - */ - private function getSetupFile(): array - { - $setupFile = Components::getProjectPaths('projectRoot') . 'setup.json'; - - // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison -- in tests sometimes the env var is 'true' string, sometimes it's '1'. Loose comparison fixes this issue. - if (\getenv('ES_TEST') == true) { - $setupFile = \dirname(__FILE__) . '/setup.json'; - } - - if (!\file_exists($setupFile)) { - throw InvalidPath::missingFileException($setupFile); - } - - return (array)\json_decode((string)\file_get_contents($setupFile), true); - } - - /** - * Wrapper for wp plugin list WP-CLI command - * - * @param string $fields Comma separated list of fields to return. Default is name. - * - * @return array> - */ - private function getCurrentlyInstalledPlugins(string $fields = 'name'): array - { - return WP_CLI::runcommand("plugin list --fields={$fields} --format=json", $this->cliOptions); - } - - /** - * Return the information about the GH plugins - * - * @param array $ghSetupPlugins List of plugins located on GitHub. - * - * @return array> - */ - private function getGitHubPluginsInfo(array $ghSetupPlugins): array - { - $ghPlugins = []; - $ghPluginsRepo = []; - - if (!empty($ghSetupPlugins)) { - /** - * We need to replace the package notifier from GH, - * because wp plugin list returns just the plugin name. - * But we also need to have some pointer about the package. - */ - foreach ($ghSetupPlugins as $ghPluginName => $ghPluginVersion) { - $cleanedUpName = \str_replace('/', '', \strstr($ghPluginName, '/')); - - $ghPlugins[$cleanedUpName] = $ghPluginVersion; - $ghPluginsRepo[$cleanedUpName] = $ghPluginName; - } - } - - return [$ghPlugins, $ghPluginsRepo]; - } - - /** - * Delete plugins that are located locally, but not in the setup.json - * - * @param array $setup setup.json file in array form. - * - * @return void - */ - private function deletePlugins(array $setup) - { - $coreSetupPlugins = $setup['plugins']['core'] ?? []; - $ghSetupPlugins = $setup['plugins']['github'] ?? []; - $paidSetupPlugins = $setup['plugins']['paid'] ?? []; - $folderSetupPlugins = $setup['plugins']['folder'] ?? []; - - // We only need a list of plugin names, so we'll filter the above return value. - $installedPlugins = \array_map(function ($pluginElement) { - return $pluginElement['name'] ?? ''; - }, $this->getCurrentlyInstalledPlugins()); - - list($ghPlugins) = $this->getGitHubPluginsInfo($ghSetupPlugins); - - $gitHubPlugins = \array_keys($ghPlugins); // Get just the names of the plugins. - $paidPlugins = \array_keys($paidSetupPlugins); // Get just the names of the plugins. - $folderPlugins = \array_keys($folderSetupPlugins); // Get just the names of the plugins. - - $setupPluginList = \array_merge( - \array_keys($coreSetupPlugins), - $gitHubPlugins, - $paidPlugins, - $folderPlugins - ); - - $pluginsToRemove = \array_diff($installedPlugins, $setupPluginList); - - WP_CLI::log('Remove plugins'); - - foreach ($pluginsToRemove as $pluginToRemove) { - WP_CLI::runcommand("plugin delete {$pluginToRemove}", $this->cliOptions); - WP_CLI::log("Plugin {$pluginToRemove} removed"); - } - } - - /** - * Update plugins - * - * @param array $setup setup.json array. - * - * @return void - */ - private function updatePlugins(array $setup) - { - $currentlyInstalledPlugins = $this->getCurrentlyInstalledPlugins('name,version'); - - $currentVersions = []; - - foreach ($currentlyInstalledPlugins as $pluginDetails) { - $currentVersions[$pluginDetails['name']] = $pluginDetails['version']; - } - - $coreSetupPlugins = $setup['plugins']['core'] ?? []; - $ghSetupPlugins = $setup['plugins']['github'] ?? []; - $paidSetupPlugins = $setup['plugins']['paid'] ?? []; - $folderSetupPlugins = $setup['plugins']['folder'] ?? []; - - list($ghPlugins, $ghPluginsRepo) = $this->getGitHubPluginsInfo($ghSetupPlugins); - - $setupPluginVersions = \array_merge($coreSetupPlugins, $ghPlugins, $paidSetupPlugins, $folderSetupPlugins); - - // Compare versions of the two arrays key for key. - foreach ($setupPluginVersions as $pluginName => $setupPluginVersion) { - // Update if the current version of the plugin is greater or less than the setup version. - if ($currentVersions[$pluginName] === $setupPluginVersion) { - continue; - } - - // Check if plugin is from GH or not. - if (isset($ghPlugins[$pluginName])) { - // The only way to update is to reinstall. - $repoName = $ghPluginsRepo[$pluginName]; - - $this->installGHPlugin($repoName, $setupPluginVersion); - } elseif (isset($paidSetupPlugins[$pluginName])) { - try { - $this->installPaidPlugin($pluginName, $setupPluginVersion); - } catch (InvalidPath $exception) { - self::cliError($exception->getMessage()); - } - } else { - WP_CLI::runcommand("plugin update {$pluginName} --version={$setupPluginVersion}"); - } - - WP_CLI::success("Plugin {$pluginName} updated"); - } - } -} diff --git a/src/Setup/SetupCli.php b/src/Setup/SetupCli.php index b839799e3..12cf2de6b 100644 --- a/src/Setup/SetupCli.php +++ b/src/Setup/SetupCli.php @@ -12,7 +12,7 @@ use EightshiftLibs\Cli\AbstractCli; use EightshiftLibs\Cli\ParentGroups\CliCreate; -use EightshiftLibs\Helpers\Components; +use EightshiftLibs\Helpers\Helpers; /** * Class SetupCli @@ -47,7 +47,7 @@ public function getCommandName(): string public function getDefaultArgs(): array { return [ - 'path' => Components::getProjectPaths('projectRoot'), + 'path' => Helpers::getProjectPaths('projectRoot'), 'file_name' => 'setup.json', 'source_path' => __DIR__, ]; @@ -101,6 +101,8 @@ public function getDoc(): array /* @phpstan-ignore-next-line */ public function __invoke(array $args, array $assocArgs) { + $assocArgs = $this->prepareArgs($assocArgs); + $this->getIntroText($assocArgs); // Get Props. @@ -110,6 +112,7 @@ public function __invoke(array $args, array $assocArgs) // Get setup.json example file, and create the one in the project. $this->getExampleTemplate($sourcePath, $fileName) + ->renameGlobals($assocArgs) ->outputWrite($path, $fileName, $assocArgs); } } diff --git a/src/ThemeOptions/ThemeOptionsCli.php b/src/ThemeOptions/ThemeOptionsCli.php index a7f1e36bd..e15b8ee2f 100644 --- a/src/ThemeOptions/ThemeOptionsCli.php +++ b/src/ThemeOptions/ThemeOptionsCli.php @@ -12,7 +12,7 @@ use EightshiftLibs\Cli\AbstractCli; use EightshiftLibs\Cli\ParentGroups\CliCreate; -use EightshiftLibs\Helpers\Components; +use EightshiftLibs\Helpers\Helpers; /** * Class ThemeOptionsCli @@ -73,6 +73,8 @@ public function getDoc(): array /* @phpstan-ignore-next-line */ public function __invoke(array $args, array $assocArgs) { + $assocArgs = $this->prepareArgs($assocArgs); + $this->getIntroText($assocArgs); $className = $this->getClassShortName(); @@ -80,9 +82,7 @@ public function __invoke(array $args, array $assocArgs) // Read the template contents, and replace the placeholders with provided variables. $this->getExampleTemplate(__DIR__, $className) ->renameClassName($className) - ->renameNamespace($assocArgs) - ->renameUse($assocArgs) - ->renameTextDomain($assocArgs) - ->outputWrite(Components::getProjectPaths('srcDestination', 'ThemeOptions'), "{$className}.php", $assocArgs); + ->renameGlobals($assocArgs) + ->outputWrite(Helpers::getProjectPaths('srcDestination', 'ThemeOptions'), "{$className}.php", $assocArgs); } } diff --git a/src/ThemeOptions/ThemeOptionsExample.php b/src/ThemeOptions/ThemeOptionsExample.php index beb10c7bd..dea5f9971 100644 --- a/src/ThemeOptions/ThemeOptionsExample.php +++ b/src/ThemeOptions/ThemeOptionsExample.php @@ -3,14 +3,14 @@ /** * Class that adds ThemeOptionsExample capability. * - * @package EightshiftBoilerplate\ThemeOptions + * @package %g_namespace%\ThemeOptions */ declare(strict_types=1); -namespace EightshiftBoilerplate\ThemeOptions; +namespace %g_namespace%\ThemeOptions; -use EightshiftLibs\Services\ServiceInterface; +use %g_use_libs%\Services\ServiceInterface; /** * Class ThemeOptionsExample @@ -53,8 +53,8 @@ public function createThemeOptionsPage(): void if (\function_exists('acf_add_options_page')) { \acf_add_options_page( [ - 'page_title' => \esc_html__('General Settings', 'eightshift-libs'), - 'menu_title' => \esc_html__('Theme Options', 'eightshift-libs'), + 'page_title' => \esc_html__('General Settings', '%g_textdomain%'), + 'menu_title' => \esc_html__('Theme Options', '%g_textdomain%'), 'menu_slug' => static::THEME_OPTIONS_SLUG, 'capability' => static::THEME_OPTIONS_CAPABILITY, 'redirect' => false, @@ -76,7 +76,7 @@ public function registerThemeOptions(): void \acf_add_local_field_group( [ 'key' => 'group_5fcab51c7138c', - 'title' => \esc_html__('Theme Options', 'eightshift-libs'), + 'title' => \esc_html__('Theme Options', '%g_textdomain%'), 'fields' => [], 'location' => [ [ diff --git a/src/View/EscapedViewCli.php b/src/View/EscapedViewCli.php index 8c582f72d..4dc6f6775 100644 --- a/src/View/EscapedViewCli.php +++ b/src/View/EscapedViewCli.php @@ -12,7 +12,7 @@ use EightshiftLibs\Cli\AbstractCli; use EightshiftLibs\Cli\ParentGroups\CliCreate; -use EightshiftLibs\Helpers\Components; +use EightshiftLibs\Helpers\Helpers; /** * Class EscapedViewCli @@ -69,6 +69,8 @@ public function getDoc(): array /* @phpstan-ignore-next-line */ public function __invoke(array $args, array $assocArgs) { + $assocArgs = $this->prepareArgs($assocArgs); + $this->getIntroText($assocArgs); $className = $this->getClassShortName(); @@ -76,8 +78,7 @@ public function __invoke(array $args, array $assocArgs) // Read the template contents, and replace the placeholders with provided variables. $this->getExampleTemplate(__DIR__, $className) ->renameClassName($className) - ->renameNamespace($assocArgs) - ->renameUse($assocArgs) - ->outputWrite(Components::getProjectPaths('srcDestination', 'View'), "{$className}.php", $assocArgs); + ->renameGlobals($assocArgs) + ->outputWrite(Helpers::getProjectPaths('srcDestination', 'View'), "{$className}.php", $assocArgs); } } diff --git a/src/View/EscapedViewExample.php b/src/View/EscapedViewExample.php index 690a87ff5..7082cebaf 100644 --- a/src/View/EscapedViewExample.php +++ b/src/View/EscapedViewExample.php @@ -3,13 +3,13 @@ /** * The EscapedViewExample specific functionality. * - * @package EightshiftBoilerplate\View + * @package %g_namespace%\View */ -namespace EightshiftBoilerplate\View; +namespace %g_namespace%\View; -use EightshiftLibs\Services\ServiceInterface; -use EightshiftLibs\View\AbstractEscapedView; +use %g_use_libs%\Services\ServiceInterface; +use %g_use_libs%\View\AbstractEscapedView; /** * Class EscapedViewExample diff --git a/src/WpCli/WpCli.php b/src/WpCli/WpCli.php index 8fbaa4784..e88facf85 100644 --- a/src/WpCli/WpCli.php +++ b/src/WpCli/WpCli.php @@ -12,7 +12,7 @@ use EightshiftLibs\Cli\AbstractCli; use EightshiftLibs\Cli\ParentGroups\CliCreate; -use EightshiftLibs\Helpers\Components; +use EightshiftLibs\Helpers\Helpers; /** * Class WpCli @@ -92,6 +92,8 @@ public function getDoc(): array /* @phpstan-ignore-next-line */ public function __invoke(array $args, array $assocArgs) { + $assocArgs = $this->prepareArgs($assocArgs); + $this->getIntroText($assocArgs); // Get Props. @@ -104,9 +106,8 @@ public function __invoke(array $args, array $assocArgs) // Read the template contents, and replace the placeholders with provided variables. $this->getExampleTemplate(__DIR__, $this->getClassShortName(true)) ->renameClassNameWithPrefix($this->getClassShortName(true), $className) - ->renameNamespace($assocArgs) - ->renameUse($assocArgs) + ->renameGlobals($assocArgs) ->searchReplaceString($this->getArgTemplate('command_name'), $commandName) - ->outputWrite(Components::getProjectPaths('srcDestination', 'WpCli'), "{$className}.php", $assocArgs); + ->outputWrite(Helpers::getProjectPaths('srcDestination', 'WpCli'), "{$className}.php", $assocArgs); } } diff --git a/src/WpCli/WpCliExample.php b/src/WpCli/WpCliExample.php index d7978d5a9..c62bd5ec1 100644 --- a/src/WpCli/WpCliExample.php +++ b/src/WpCli/WpCliExample.php @@ -8,10 +8,10 @@ declare(strict_types=1); -namespace EightshiftBoilerplate\WpCli; +namespace %g_namespace%\WpCli; -use EightshiftBoilerplate\Config\Config; -use EightshiftLibs\Services\ServiceCliInterface; +use %g_namespace%\Config\Config; +use %g_use_libs%\Services\ServiceCliInterface; use WP_CLI; /** diff --git a/tests/BaseTest.php b/tests/BaseTest.php deleted file mode 100644 index 4308b3bcb..000000000 --- a/tests/BaseTest.php +++ /dev/null @@ -1,278 +0,0 @@ -stubTranslationFunctions(); - $this->stubEscapeFunctions(); - - // Mock the template dir location. - Functions\when('get_template_directory')->justReturn(\dirname(__FILE__) . \DIRECTORY_SEPARATOR . 'data'); - - // Mock the template dir location. - Functions\when('get_stylesheet_directory')->justReturn(\dirname(__FILE__) . \DIRECTORY_SEPARATOR); - - // Mock escaping function. - Functions\when('wp_kses_post')->returnArg(); - - // Mock escaping function. - Functions\when('esc_html__')->returnArg(); - - // Mock rand function. - Functions\when('wp_rand')->justReturn(1154790670); - - // Mock json success and error handlers. - Functions\when('wp_send_json_success')->alias(function ($data = null, $statusCode = null, $options = 0) { - $response = ['success' => true]; - - if (isset($data)) { - $response['data'] = $data; - } - - echo json_encode($response, $options); - }); - - Functions\when('wp_send_json_error')->alias(function ($data = null, $statusCode = null, $options = 0) { - $response = ['success' => false]; - - if (isset($data)) { - $response['data'] = $data; - } - - echo json_encode($response, $options); - }); - - // Mock rest response handler. - Functions\when('rest_ensure_response')->returnArg(); - - // Mock site_url function. - Functions\when('site_url')->justReturn('https://example.com'); - - // Mock wp_get_attachment_metadata function. - Functions\when('wp_get_attachment_metadata')->justReturn(attachemntMetaDataMock()); - - // Mock get_post_meta function. - Functions\when('get_post_meta')->justReturn(''); - - // Mock wp_delete_file function. - Functions\when('wp_delete_file')->justReturn(''); - - // Mock ACF add options page function - Functions\when('acf_add_options_page')->justReturn(true); - - // Mock ACF add options subpage function - Functions\when('acf_add_options_sub_page')->justReturn(true); - - // Mock ACF add local field group function - Functions\when('acf_add_local_field_group')->justReturn(true); - - // Mock current_user_can function. - Functions\when('current_user_can')->returnArg(); - - // Mock get_field function. - Functions\when('get_field')->returnArg(); - - // Mock wp_parse_url function. - Functions\when('wp_parse_url')->justReturn([ - 'scheme' => 'https', - 'host' => 'developer.wordpress.org', - 'path' => '/reference/functions/wp_parse_url/', - ]); - - $this->wpCliMock = mock('alias:WP_CLI'); - - $this->wpCliMock - ->shouldReceive('success') - ->andReturnUsing(function ($message) { - putenv("ES_CLI_SUCCESS_HAPPENED={$message}"); - }); - - $this->wpCliMock - ->shouldReceive('error') - ->andReturnUsing(function ($errorMessage) { - putenv("ES_CLI_ERROR_HAPPENED={$errorMessage}"); - throw new Exception($errorMessage); - }); - - $this->wpCliMock - ->shouldReceive('log') - ->andReturnUsing(function ($message) { - putenv("ES_CLI_LOG_HAPPENED={$message}"); - }); - - $this->wpCliMock - ->shouldReceive('add_command') - ->andReturnUsing(function ($message) { - putenv("ES_CLI_ADD_COMMAND_HAPPENED={$message}"); - }); - - $this->wpCliMock - ->shouldReceive('colorize') - ->andReturnUsing(function ($message) { - return $message; - }); - - // Mock attachment function. - Functions\when('get_attached_file')->justReturn('test.jpg'); - - // Mock attachment function. - Functions\when('wp_check_filetype')->justReturn([ - 'ext' => 'jpg', - 'type' => 'image/jpeg', - ]); - - if (!defined('DAY_IN_SECONDS')) { - define('DAY_IN_SECONDS', 3600); - } - - Functions\when('is_admin')->justReturn(false); - - Functions\when('trailingslashit')->alias(function (string $string) { - return rtrim($string, '/\\'); - }); - - 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() - { - parent::tear_down(); - - $this->deleteCliOutput(); - - for ($i = 1; $i <= 10; $i++) { - putenv("ES_SIDEAFFECT_{$i}"); - } - - putenv('ES_CLI_SUCCESS_HAPPENED'); - putenv('ES_CLI_ERROR_HAPPENED'); - putenv('ES_CLI_LOG_HAPPENED'); - putenv('ES_CLI_RUNCOMMAND_HAPPENED'); - - global $esBlocks; - $esBlocks = null; - - unset($this->wpCliMock); - } - - /** - * Used for cleaning out the cliOutput created after every CLI test - * - * @param string $dir Directory to remove. - * - * @return void - */ - private function deleteCliOutput(string $dir = ''): void - { - $sep = \DIRECTORY_SEPARATOR; - if (!$dir) { - $dir = \dirname(__FILE__, 2) . "{$sep}cliOutput"; - } - - if (!\is_dir($dir)) { - return; - } - - $iterator = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS); - $files = new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::CHILD_FIRST); - - foreach ($files as $file) { - if ($file->isDir()) { - rmdir($file->getRealPath()); - } else { - unlink($file->getRealPath()); - } - } - - rmdir($dir); - } -} diff --git a/tests/Datasets/Arguments.php b/tests/Datasets/Arguments.php deleted file mode 100644 index 5060d4999..000000000 --- a/tests/Datasets/Arguments.php +++ /dev/null @@ -1,248 +0,0 @@ - 'bar', 'other-key' => 'foo']], - [['key' => 'key']] -]); - -dataset('classesArray', [ - [['medium', 'large']], - [['small']], - [['key' => 'bold--all']], -]); - -// Rest/Fields arguments -dataset('correctFieldNameArguments', [ - [['field_name' => 'SomeField', 'object_type' => 'post']], - [['field_name' => 'some field', 'object_type' => 'post']], - [['field_name' => 'some-field', 'object_type' => 'post']], - [['field_name' => 'some_field', 'object_type' => 'post']], - [['field_name' => 'Some Field', 'object_type' => 'page']], - [['field_name' => 'Some Field', 'object_type' => 'custom-post-type']], -]); - -dataset('errorFieldNameArguments', [ - [['field_name' => 'SomeField']], - [['object_type' => 'post']], -]); - -// Rest/Routes arguments -dataset('correctRouteArguments', [ - [['endpoint_slug' => 'some-test', 'method' => 'post']], - [['endpoint_slug' => 'some-test', 'method' => 'get']], - [['endpoint_slug' => 'some-test', 'method' => 'put']], - [['endpoint_slug' => 'some-test', 'method' => 'patch']], - [['endpoint_slug' => 'some-test', 'method' => 'delete']], - [['endpoint_slug' => 'someTest', 'method' => 'post']], - [['endpoint_slug' => 'some_test', 'method' => 'post']], - [['endpoint_slug' => 'some_Test_1', 'method' => 'post']], -]); - -dataset('errorRouteArguments', [ - [['endpoint_slug' => 'some-test']], - [['method' => 'post']], -]); - -dataset('invalidRouteArguments', [ - [['endpoint_slug' => 'some-test', 'method' => 'asdad']], - [['endpoint_slug' => '', 'method' => 'post']], -]); - -dataset('inputSlugs', [ - 'someName', - 'some-Name', - 'some name', - 'longer slug goes here', - 'mixed_Case_goes here-as well', - 'UPPER-CASE', -]); - -// Exceptions -dataset('exceptionArguments', [ - 7, - null, - true -]); - -dataset('postsDifferentLength', [ - [[// 1043 words, 3 blocks 7022 chars - 6 min read - [[ - // Block 427 words, 2854 chars - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras viverra pulvinar enim, in mattis ante facilisis eu. Ut viverra, erat ut accumsan facilisis, sem risus elementum est, quis egestas tortor mauris nec sem. Pellentesque faucibus sapien quis erat iaculis, non scelerisque velit cursus. Nunc porttitor, neque non tristique scelerisque, leo odio luctus tellus, at dapibus massa magna vitae turpis. Nulla quis auctor justo, eget convallis metus. Donec eu ultricies urna. Nam vulputate nisi sapien, convallis efficitur diam eleifend sed. Nunc pellentesque lacus sit amet elit finibus maximus. Praesent varius ut nisi vitae consequat. Ut luctus efficitur blandit. Vestibulum nulla nisi, laoreet ac dapibus eu, ornare non sapien. Curabitur et ultricies nulla. Nullam sed condimentum risus. Nulla sit amet odio augue. Vivamus quis tellus risus. Nulla posuere enim ut nunc suscipit tempor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin laoreet lorem nec massa egestas bibendum. Nulla pharetra ut ligula ut efficitur. Proin quis massa in orci semper iaculis. Fusce ligula mauris, molestie sit amet dui non, aliquam consectetur quam. Donec ac rhoncus massa. Nullam at aliquam sem. Etiam sit amet scelerisque est, ac tincidunt tortor. Fusce quis erat vitae ante tristique facilisis et ut nunc. Aliquam mi metus, vehicula eget justo ac, sollicitudin tristique neque. Fusce euismod tristique iaculis. Phasellus malesuada erat nec ante dignissim, id iaculis lectus rutrum. Nunc vulputate pharetra ligula, sed fermentum nulla malesuada ut. Donec molestie varius erat id faucibus. Integer purus risus, scelerisque vitae justo et, egestas lacinia diam. In hac habitasse platea dictumst. Duis turpis purus, imperdiet id est eu, malesuada vehicula mauris. Sed metus odio, tempus ultrices finibus et, lobortis ac orci. Etiam sodales purus massa, id dignissim ante volutpat eu. Nam aliquam nulla arcu, non malesuada diam finibus at. Donec suscipit, felis eu lobortis lobortis, justo ex accumsan leo, et varius ex urna faucibus tellus. Vivamus pretium turpis a volutpat lacinia. Phasellus at turpis at ipsum varius eleifend. Vivamus maximus facilisis erat. Aliquam placerat, urna nec sollicitudin tempus, sapien magna gravida augue, in auctor nulla mi nec massa. Nam eu sollicitudin velit. Pellentesque in sem ac nisl elementum elementum hendrerit a tellus. Nam et massa convallis, gravida lorem nec, porttitor augue. Nam id sagittis odio. Sed id magna eu enim euismod congue id non augue. Ut dui tellus, iaculis non aliquet eu, auctor a massa. Cras volutpat eros eget ligula placerat vulputate. Proin pulvinar sollicitudin nisl, a imperdiet diam lobortis sagittis. Etiam ultricies tempor dui et convallis. Aliquam varius sem dui, vel euismod nulla viverra imperdiet. Sed eget mauris at metus consequat ullamcorper.', - // Block 200 words, 1377 chars - 'Nunc lobortis turpis urna, ac consectetur metus eleifend id. Sed ac sapien ac dolor facilisis fringilla. Suspendisse dictum mollis tortor ac finibus. Curabitur dapibus dignissim est, vel vehicula turpis vulputate vel. Cras tristique quam lectus, id pretium odio consectetur et. Cras posuere purus sit amet sapien tincidunt, sit amet ultrices nunc auctor. Nunc porta orci nisl, eu mattis tellus accumsan vitae. Mauris id risus felis. Aliquam et enim ipsum. Phasellus vel viverra nisl, vel tempor quam. Quisque ultricies suscipit sapien sit amet pharetra. Sed in massa consectetur, ullamcorper est vel, maximus eros. Etiam sit amet imperdiet lacus. Maecenas finibus laoreet malesuada. Phasellus ipsum nisl, sollicitudin sed magna quis, blandit vehicula lacus. Nam viverra ac mauris consectetur maximus. Phasellus hendrerit venenatis risus, sit amet convallis orci. Pellentesque vitae varius turpis, consectetur semper quam. In rutrum lectus massa, sit amet ultrices diam gravida vel. Quisque venenatis, sem a faucibus tempus, est dolor fringilla eros, eget mollis nibh nunc vel turpis. Quisque malesuada blandit leo, vel pharetra nisi. Praesent ante ipsum, fermentum eu pulvinar nec, efficitur eget nulla. Suspendisse justo elit, rhoncus eget sollicitudin eu, lacinia vel lorem. Donec euismod ante urna, ac pretium erat imperdiet vel. Cras consectetur bibendum enim id imperdiet.', - // Block 416 words, 2791 chars - 'Donec dolor magna, pellentesque sed augue eu, vehicula viverra purus. Phasellus eu maximus lectus, eget posuere eros. Vestibulum hendrerit euismod ornare. Nam vel cursus nulla. Aliquam faucibus pharetra enim, eget vulputate mi fermentum eget. Proin luctus orci a ex feugiat dapibus. Nam ut lobortis risus. Fusce ac iaculis ante, vitae pulvinar ex. Cras placerat felis ornare elit gravida suscipit. Aenean in vestibulum nulla. Praesent eu ex euismod, porta velit ac, aliquam dolor. Pellentesque in purus varius, semper nibh quis, auctor mi. Vivamus nec risus et orci rutrum maximus at eget nulla. Etiam molestie, arcu et porttitor posuere, urna orci ultrices libero, at tincidunt arcu odio eget sem. Phasellus sit amet pretium eros. Etiam quis libero a ex sollicitudin maximus. Duis non nulla ante. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur bibendum lacus quis purus dictum, imperdiet gravida dolor cursus. Suspendisse tempor neque et hendrerit vestibulum. Mauris risus odio, eleifend vitae imperdiet quis, dignissim in nisl. Proin ultricies eget nibh a tempor. Mauris vitae magna augue. Donec suscipit convallis ante, quis vehicula lorem mollis at. Etiam id augue sodales, pharetra lacus sit amet, venenatis justo. Mauris ornare semper nulla ut dictum. Vivamus fringilla justo sed semper viverra. Suspendisse dictum arcu ut dui faucibus condimentum. In at quam maximus, egestas urna et, eleifend diam. Aliquam pulvinar arcu ut semper rutrum. Praesent diam libero, placerat nec tristique ut, hendrerit sed nisi. In ac neque a felis commodo pellentesque. Nunc interdum nisl nec pharetra sollicitudin. Vivamus dictum, libero vitae mollis laoreet, diam metus euismod odio, nec imperdiet augue velit vitae leo. Aliquam risus leo, aliquet in nisi nec, vulputate congue ligula. Suspendisse pulvinar libero eu sodales aliquet. Nullam finibus porttitor consequat. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus dapibus sem at elementum rutrum. Nam mattis eu est vel tincidunt. Donec hendrerit massa ligula, at tempor diam facilisis et. Mauris sed porttitor risus. Nunc id purus est. Donec posuere aliquet ex, non tincidunt erat varius ornare. Donec varius, justo quis volutpat varius, justo mauris rutrum eros, at commodo magna dui et neque. Vestibulum libero tellus, mattis vel tellus nec, lobortis vehicula lectus. Sed euismod ex eu feugiat scelerisque. Aliquam ac augue in dolor faucibus pretium in sodales urna. Mauris vitae euismod neque, et finibus tortor. Integer tristique pellentesque nunc a egestas. Aenean accumsan, nisl convallis convallis aliquet, velit elit vestibulum neque, ac ultrices lacus libero ac augue. Proin in vulputate justo, eget feugiat nibh. Nulla sit amet commodo dui.', - ]], - ]], - [[ // 735 words, 2 blocks, 5008 chars - 4 min read - [[ - 'Nunc lobortis turpis urna, ac consectetur metus eleifend id. Sed ac sapien ac dolor facilisis fringilla. Suspendisse dictum mollis tortor ac finibus. Curabitur dapibus dignissim est, vel vehicula turpis vulputate vel. Cras tristique quam lectus, id pretium odio consectetur et. Cras posuere purus sit amet sapien tincidunt, sit amet ultrices nunc auctor. Nunc porta orci nisl, eu mattis tellus accumsan vitae. Mauris id risus felis. Aliquam et enim ipsum. Phasellus vel viverra nisl, vel tempor quam. Quisque ultricies suscipit sapien sit amet pharetra. Sed in massa consectetur, ullamcorper est vel, maximus eros. Etiam sit amet imperdiet lacus. Maecenas finibus laoreet malesuada. Phasellus ipsum nisl, sollicitudin sed magna quis, blandit vehicula lacus. Nam viverra ac mauris consectetur maximus. Phasellus hendrerit venenatis risus, sit amet convallis orci. Pellentesque vitae varius turpis, consectetur semper quam. In rutrum lectus massa, sit amet ultrices diam gravida vel. Quisque venenatis, sem a faucibus tempus, est dolor fringilla eros, eget mollis nibh nunc vel turpis. Quisque malesuada blandit leo, vel pharetra nisi. Praesent ante ipsum, fermentum eu pulvinar nec, efficitur eget nulla. Suspendisse justo elit, rhoncus eget sollicitudin eu, lacinia vel lorem. Donec euismod ante urna, ac pretium erat imperdiet vel. Cras consectetur bibendum enim id imperdiet.', - // Block 535 words, 3631 chars - 'Duis dictum accumsan massa, at fermentum quam lacinia id. Morbi dapibus gravida felis nec eleifend. Pellentesque sit amet tellus molestie turpis cursus feugiat in nec eros. Vivamus ornare elementum metus eget sagittis. Mauris purus odio, cursus in tortor in, rhoncus vulputate augue. Mauris imperdiet nec mauris eu lobortis. Nulla aliquam ex id lorem vehicula, a congue risus luctus. Cras vestibulum elit et sapien commodo, eget ultrices ligula commodo. Curabitur tristique ac sapien nec luctus. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla a elit rhoncus est laoreet fermentum vitae vel nisi. Duis mi lorem, bibendum sed nunc sed, tincidunt tristique sem. Nunc sagittis lobortis imperdiet. Nam aliquam magna quam, ut convallis lorem porta quis. Vestibulum at facilisis tellus. Aenean vulputate erat quis sapien rhoncus dictum sed eget odio. Vestibulum ullamcorper faucibus sem, a ornare lectus. Nulla volutpat sapien id dapibus scelerisque. Aenean vel enim urna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nullam laoreet finibus quam, sed porttitor arcu porta in. Fusce tempor fringilla urna, vitae sagittis sapien convallis sed. Mauris tincidunt sollicitudin lectus, consectetur auctor libero egestas sed. In commodo leo id semper tempus. Etiam tempus nunc vitae velit varius mattis. Quisque pharetra leo a arcu vulputate, non sollicitudin elit vulputate. Pellentesque egestas ligula velit, id hendrerit eros interdum nec. Fusce eget aliquet ligula. Nam vel ipsum a mauris vehicula commodo ac eu sem. Curabitur enim metus, euismod nec justo sed, malesuada blandit ex. Fusce sit amet consequat ligula. Aliquam magna purus, consectetur non nibh eget, condimentum vehicula nisl. Curabitur malesuada sit amet lacus eu pellentesque. Maecenas lobortis velit eget nisi volutpat, vel ultricies purus efficitur. Donec mattis, eros a mattis pretium, metus turpis laoreet neque, at cursus ex nibh pretium velit. Donec sit amet fringilla lorem, quis fringilla mi. Integer maximus lacus non risus aliquam sollicitudin. Etiam a gravida augue. Phasellus tincidunt consectetur felis sed tincidunt. Morbi diam risus, elementum ut cursus non, porttitor eu ex. Fusce rhoncus risus id est tincidunt, et commodo quam finibus. Mauris ligula tellus, aliquam sed vulputate vel, commodo at sapien. Aenean tempus sodales interdum. Praesent eget justo at odio venenatis tristique. Donec ac cursus lorem. Donec fermentum sodales dui, non maximus tellus. Nam et nisl nec diam eleifend volutpat. Etiam ligula eros, elementum vel enim nec, varius faucibus tellus. Cras tempor turpis dui, at viverra nibh pellentesque eu. Fusce magna diam, pharetra eu pretium non, condimentum non risus. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam tristique ultrices condimentum. Aliquam sed venenatis sem. Nulla euismod lobortis augue, nec dignissim mauris varius vel. Fusce in tincidunt mauris. Etiam feugiat lorem rutrum, auctor urna non, finibus mi. Sed malesuada malesuada metus et porta. Vivamus pulvinar non tortor non porttitor. Suspendisse potenti. Ut tincidunt lorem eget vulputate egestas. Sed maximus maximus nisi id accumsan. Donec et risus a metus ultricies ultricies id nec arcu. Nullam fermentum lorem quis odio posuere, vel finibus tortor interdum. Ut vehicula ante eget dolor malesuada, sed pulvinar leo porttitor. Vivamus et nulla non quam maximus rhoncus ut id sem. Aenean suscipit facilisis dapibus. Cras auctor enim eget augue elementum, et tristique lacus dapibus. Phasellus mollis iaculis purus quis semper.', - ]], - ]], - [[ // 1686 words, 4 blocks, 11430 chars - 9 min read - [[ - 'Nunc lobortis turpis urna, ac consectetur metus eleifend id. Sed ac sapien ac dolor facilisis fringilla. Suspendisse dictum mollis tortor ac finibus. Curabitur dapibus dignissim est, vel vehicula turpis vulputate vel. Cras tristique quam lectus, id pretium odio consectetur et. Cras posuere purus sit amet sapien tincidunt, sit amet ultrices nunc auctor. Nunc porta orci nisl, eu mattis tellus accumsan vitae. Mauris id risus felis. Aliquam et enim ipsum. Phasellus vel viverra nisl, vel tempor quam. Quisque ultricies suscipit sapien sit amet pharetra. Sed in massa consectetur, ullamcorper est vel, maximus eros. Etiam sit amet imperdiet lacus. Maecenas finibus laoreet malesuada. Phasellus ipsum nisl, sollicitudin sed magna quis, blandit vehicula lacus. Nam viverra ac mauris consectetur maximus. Phasellus hendrerit venenatis risus, sit amet convallis orci. Pellentesque vitae varius turpis, consectetur semper quam. In rutrum lectus massa, sit amet ultrices diam gravida vel. Quisque venenatis, sem a faucibus tempus, est dolor fringilla eros, eget mollis nibh nunc vel turpis. Quisque malesuada blandit leo, vel pharetra nisi. Praesent ante ipsum, fermentum eu pulvinar nec, efficitur eget nulla. Suspendisse justo elit, rhoncus eget sollicitudin eu, lacinia vel lorem. Donec euismod ante urna, ac pretium erat imperdiet vel. Cras consectetur bibendum enim id imperdiet.', - 'Donec dolor magna, pellentesque sed augue eu, vehicula viverra purus. Phasellus eu maximus lectus, eget posuere eros. Vestibulum hendrerit euismod ornare. Nam vel cursus nulla. Aliquam faucibus pharetra enim, eget vulputate mi fermentum eget. Proin luctus orci a ex feugiat dapibus. Nam ut lobortis risus. Fusce ac iaculis ante, vitae pulvinar ex. Cras placerat felis ornare elit gravida suscipit. Aenean in vestibulum nulla. Praesent eu ex euismod, porta velit ac, aliquam dolor. Pellentesque in purus varius, semper nibh quis, auctor mi. Vivamus nec risus et orci rutrum maximus at eget nulla. Etiam molestie, arcu et porttitor posuere, urna orci ultrices libero, at tincidunt arcu odio eget sem. Phasellus sit amet pretium eros. Etiam quis libero a ex sollicitudin maximus. Duis non nulla ante. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur bibendum lacus quis purus dictum, imperdiet gravida dolor cursus. Suspendisse tempor neque et hendrerit vestibulum. Mauris risus odio, eleifend vitae imperdiet quis, dignissim in nisl. Proin ultricies eget nibh a tempor. Mauris vitae magna augue. Donec suscipit convallis ante, quis vehicula lorem mollis at. Etiam id augue sodales, pharetra lacus sit amet, venenatis justo. Mauris ornare semper nulla ut dictum. Vivamus fringilla justo sed semper viverra. Suspendisse dictum arcu ut dui faucibus condimentum. In at quam maximus, egestas urna et, eleifend diam. Aliquam pulvinar arcu ut semper rutrum. Praesent diam libero, placerat nec tristique ut, hendrerit sed nisi. In ac neque a felis commodo pellentesque. Nunc interdum nisl nec pharetra sollicitudin. Vivamus dictum, libero vitae mollis laoreet, diam metus euismod odio, nec imperdiet augue velit vitae leo. Aliquam risus leo, aliquet in nisi nec, vulputate congue ligula. Suspendisse pulvinar libero eu sodales aliquet. Nullam finibus porttitor consequat. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus dapibus sem at elementum rutrum. Nam mattis eu est vel tincidunt. Donec hendrerit massa ligula, at tempor diam facilisis et. Mauris sed porttitor risus. Nunc id purus est. Donec posuere aliquet ex, non tincidunt erat varius ornare. Donec varius, justo quis volutpat varius, justo mauris rutrum eros, at commodo magna dui et neque. Vestibulum libero tellus, mattis vel tellus nec, lobortis vehicula lectus. Sed euismod ex eu feugiat scelerisque. Aliquam ac augue in dolor faucibus pretium in sodales urna. Mauris vitae euismod neque, et finibus tortor. Integer tristique pellentesque nunc a egestas. Aenean accumsan, nisl convallis convallis aliquet, velit elit vestibulum neque, ac ultrices lacus libero ac augue. Proin in vulputate justo, eget feugiat nibh. Nulla sit amet commodo dui.', - 'Duis dictum accumsan massa, at fermentum quam lacinia id. Morbi dapibus gravida felis nec eleifend. Pellentesque sit amet tellus molestie turpis cursus feugiat in nec eros. Vivamus ornare elementum metus eget sagittis. Mauris purus odio, cursus in tortor in, rhoncus vulputate augue. Mauris imperdiet nec mauris eu lobortis. Nulla aliquam ex id lorem vehicula, a congue risus luctus. Cras vestibulum elit et sapien commodo, eget ultrices ligula commodo. Curabitur tristique ac sapien nec luctus. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla a elit rhoncus est laoreet fermentum vitae vel nisi. Duis mi lorem, bibendum sed nunc sed, tincidunt tristique sem. Nunc sagittis lobortis imperdiet. Nam aliquam magna quam, ut convallis lorem porta quis. Vestibulum at facilisis tellus. Aenean vulputate erat quis sapien rhoncus dictum sed eget odio. Vestibulum ullamcorper faucibus sem, a ornare lectus. Nulla volutpat sapien id dapibus scelerisque. Aenean vel enim urna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nullam laoreet finibus quam, sed porttitor arcu porta in. Fusce tempor fringilla urna, vitae sagittis sapien convallis sed. Mauris tincidunt sollicitudin lectus, consectetur auctor libero egestas sed. In commodo leo id semper tempus. Etiam tempus nunc vitae velit varius mattis. Quisque pharetra leo a arcu vulputate, non sollicitudin elit vulputate. Pellentesque egestas ligula velit, id hendrerit eros interdum nec. Fusce eget aliquet ligula. Nam vel ipsum a mauris vehicula commodo ac eu sem. Curabitur enim metus, euismod nec justo sed, malesuada blandit ex. Fusce sit amet consequat ligula. Aliquam magna purus, consectetur non nibh eget, condimentum vehicula nisl. Curabitur malesuada sit amet lacus eu pellentesque. Maecenas lobortis velit eget nisi volutpat, vel ultricies purus efficitur. Donec mattis, eros a mattis pretium, metus turpis laoreet neque, at cursus ex nibh pretium velit. Donec sit amet fringilla lorem, quis fringilla mi. Integer maximus lacus non risus aliquam sollicitudin. Etiam a gravida augue. Phasellus tincidunt consectetur felis sed tincidunt. Morbi diam risus, elementum ut cursus non, porttitor eu ex. Fusce rhoncus risus id est tincidunt, et commodo quam finibus. Mauris ligula tellus, aliquam sed vulputate vel, commodo at sapien. Aenean tempus sodales interdum. Praesent eget justo at odio venenatis tristique. Donec ac cursus lorem. Donec fermentum sodales dui, non maximus tellus. Nam et nisl nec diam eleifend volutpat. Etiam ligula eros, elementum vel enim nec, varius faucibus tellus. Cras tempor turpis dui, at viverra nibh pellentesque eu. Fusce magna diam, pharetra eu pretium non, condimentum non risus. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam tristique ultrices condimentum. Aliquam sed venenatis sem. Nulla euismod lobortis augue, nec dignissim mauris varius vel. Fusce in tincidunt mauris. Etiam feugiat lorem rutrum, auctor urna non, finibus mi. Sed malesuada malesuada metus et porta. Vivamus pulvinar non tortor non porttitor. Suspendisse potenti. Ut tincidunt lorem eget vulputate egestas. Sed maximus maximus nisi id accumsan. Donec et risus a metus ultricies ultricies id nec arcu. Nullam fermentum lorem quis odio posuere, vel finibus tortor interdum. Ut vehicula ante eget dolor malesuada, sed pulvinar leo porttitor. Vivamus et nulla non quam maximus rhoncus ut id sem. Aenean suscipit facilisis dapibus. Cras auctor enim eget augue elementum, et tristique lacus dapibus. Phasellus mollis iaculis purus quis semper.', - 'Duis dictum accumsan massa, at fermentum quam lacinia id. Morbi dapibus gravida felis nec eleifend. Pellentesque sit amet tellus molestie turpis cursus feugiat in nec eros. Vivamus ornare elementum metus eget sagittis. Mauris purus odio, cursus in tortor in, rhoncus vulputate augue. Mauris imperdiet nec mauris eu lobortis. Nulla aliquam ex id lorem vehicula, a congue risus luctus. Cras vestibulum elit et sapien commodo, eget ultrices ligula commodo. Curabitur tristique ac sapien nec luctus. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla a elit rhoncus est laoreet fermentum vitae vel nisi. Duis mi lorem, bibendum sed nunc sed, tincidunt tristique sem. Nunc sagittis lobortis imperdiet. Nam aliquam magna quam, ut convallis lorem porta quis. Vestibulum at facilisis tellus. Aenean vulputate erat quis sapien rhoncus dictum sed eget odio. Vestibulum ullamcorper faucibus sem, a ornare lectus. Nulla volutpat sapien id dapibus scelerisque. Aenean vel enim urna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nullam laoreet finibus quam, sed porttitor arcu porta in. Fusce tempor fringilla urna, vitae sagittis sapien convallis sed. Mauris tincidunt sollicitudin lectus, consectetur auctor libero egestas sed. In commodo leo id semper tempus. Etiam tempus nunc vitae velit varius mattis. Quisque pharetra leo a arcu vulputate, non sollicitudin elit vulputate. Pellentesque egestas ligula velit, id hendrerit eros interdum nec. Fusce eget aliquet ligula. Nam vel ipsum a mauris vehicula commodo ac eu sem. Curabitur enim metus, euismod nec justo sed, malesuada blandit ex. Fusce sit amet consequat ligula. Aliquam magna purus, consectetur non nibh eget, condimentum vehicula nisl. Curabitur malesuada sit amet lacus eu pellentesque. Maecenas lobortis velit eget nisi volutpat, vel ultricies purus efficitur. Donec mattis, eros a mattis pretium, metus turpis laoreet neque, at cursus ex nibh pretium velit. Donec sit amet fringilla lorem, quis fringilla mi. Integer maximus lacus non risus aliquam sollicitudin. Etiam a gravida augue. Phasellus tincidunt consectetur felis sed tincidunt. Morbi diam risus, elementum ut cursus non, porttitor eu ex. Fusce rhoncus risus id est tincidunt, et commodo quam finibus. Mauris ligula tellus, aliquam sed vulputate vel, commodo at sapien. Aenean tempus sodales interdum. Praesent eget justo at odio venenatis tristique. Donec ac cursus lorem. Donec fermentum sodales dui, non maximus tellus. Nam et nisl nec diam eleifend volutpat. Etiam ligula eros, elementum vel enim nec, varius faucibus tellus. Cras tempor turpis dui, at viverra nibh pellentesque eu. Fusce magna diam, pharetra eu pretium non, condimentum non risus. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam tristique ultrices condimentum. Aliquam sed venenatis sem. Nulla euismod lobortis augue, nec dignissim mauris varius vel. Fusce in tincidunt mauris. Etiam feugiat lorem rutrum, auctor urna non, finibus mi. Sed malesuada malesuada metus et porta. Vivamus pulvinar non tortor non porttitor. Suspendisse potenti. Ut tincidunt lorem eget vulputate egestas. Sed maximus maximus nisi id accumsan. Donec et risus a metus ultricies ultricies id nec arcu. Nullam fermentum lorem quis odio posuere, vel finibus tortor interdum. Ut vehicula ante eget dolor malesuada, sed pulvinar leo porttitor. Vivamus et nulla non quam maximus rhoncus ut id sem. Aenean suscipit facilisis dapibus. Cras auctor enim eget augue elementum, et tristique lacus dapibus. Phasellus mollis iaculis purus quis semper.', - ]] - ]], - [[ // 427 words, 1 block, 2854 chars - 3 min read - [[ - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras viverra pulvinar enim, in mattis ante facilisis eu. Ut viverra, erat ut accumsan facilisis, sem risus elementum est, quis egestas tortor mauris nec sem. Pellentesque faucibus sapien quis erat iaculis, non scelerisque velit cursus. Nunc porttitor, neque non tristique scelerisque, leo odio luctus tellus, at dapibus massa magna vitae turpis. Nulla quis auctor justo, eget convallis metus. Donec eu ultricies urna. Nam vulputate nisi sapien, convallis efficitur diam eleifend sed. Nunc pellentesque lacus sit amet elit finibus maximus. Praesent varius ut nisi vitae consequat. Ut luctus efficitur blandit. Vestibulum nulla nisi, laoreet ac dapibus eu, ornare non sapien. Curabitur et ultricies nulla. Nullam sed condimentum risus. Nulla sit amet odio augue. Vivamus quis tellus risus. Nulla posuere enim ut nunc suscipit tempor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin laoreet lorem nec massa egestas bibendum. Nulla pharetra ut ligula ut efficitur. Proin quis massa in orci semper iaculis. Fusce ligula mauris, molestie sit amet dui non, aliquam consectetur quam. Donec ac rhoncus massa. Nullam at aliquam sem. Etiam sit amet scelerisque est, ac tincidunt tortor. Fusce quis erat vitae ante tristique facilisis et ut nunc. Aliquam mi metus, vehicula eget justo ac, sollicitudin tristique neque. Fusce euismod tristique iaculis. Phasellus malesuada erat nec ante dignissim, id iaculis lectus rutrum. Nunc vulputate pharetra ligula, sed fermentum nulla malesuada ut. Donec molestie varius erat id faucibus. Integer purus risus, scelerisque vitae justo et, egestas lacinia diam. In hac habitasse platea dictumst. Duis turpis purus, imperdiet id est eu, malesuada vehicula mauris. Sed metus odio, tempus ultrices finibus et, lobortis ac orci. Etiam sodales purus massa, id dignissim ante volutpat eu. Nam aliquam nulla arcu, non malesuada diam finibus at. Donec suscipit, felis eu lobortis lobortis, justo ex accumsan leo, et varius ex urna faucibus tellus. Vivamus pretium turpis a volutpat lacinia. Phasellus at turpis at ipsum varius eleifend. Vivamus maximus facilisis erat. Aliquam placerat, urna nec sollicitudin tempus, sapien magna gravida augue, in auctor nulla mi nec massa. Nam eu sollicitudin velit. Pellentesque in sem ac nisl elementum elementum hendrerit a tellus. Nam et massa convallis, gravida lorem nec, porttitor augue. Nam id sagittis odio. Sed id magna eu enim euismod congue id non augue. Ut dui tellus, iaculis non aliquet eu, auctor a massa. Cras volutpat eros eget ligula placerat vulputate. Proin pulvinar sollicitudin nisl, a imperdiet diam lobortis sagittis. Etiam ultricies tempor dui et convallis. Aliquam varius sem dui, vel euismod nulla viverra imperdiet. Sed eget mauris at metus consequat ullamcorper.', - ]] - ]] -]); - -dataset('arrayIsListWrong', [[ - ['a', 'b', 'c'], - ['1', '2', '3'], - [], - '', - false, - ['1' => 'a', '0' => 'b', '2' => 'c'], -]]); - -dataset('arrayIsListCorrect', [[ - ['a' => 'a', 'b' => 'b', 'c' => 'c'], - ['a' => 'a', '1' => 'b', '2' => 'c'], - ['0' => 'a', '1' => 'b', '2' => 'c'], -]]); - -dataset('camelToKebabCaseCheckCorrect', [ - ['simpleTest', 'simple-test'], - ['easy', 'easy'], - ['HTML', 'html'], - ['simpleXML', 'simple-xml'], - ['PDFLoad', 'pdf-load'], - ['startMIDDLELast', 'start-middle-last'], - ['AString', 'a-string'], - ['Some4Numbers234', 'some4-numbers234'], - ['TEST123String', 'test123-string'], - ['hello_world', 'hello-world'], - ['hello__world', 'hello-world'], - ['_hello_world_', '-hello-world-'], - ['hello_World', 'hello-world'], - ['HelloWorld', 'hello-world'], - ['helloWorldFoo', 'hello-world-foo'], - ['hello-world', 'hello-world'], - ['myHTMLFiLe', 'my-html-fi-le'], - ['aBaBaB', 'a-ba-ba-b'], - ['BaBaBa', 'ba-ba-ba'], - ['libC', 'lib-c'], - ['Some Title', 'some-title'], - ['Some title', 'some-title'], - ['some title', 'some-title'], - ['some title longer', 'some-title-longer'], -]); - -dataset('camelToKebabCaseCheckWrong', [ - ['simpleTest', 'simpleTest'], - ['HTML', 'HTML'], - ['simpleXML', 'simpleXML'], - ['PDFLoad', 'PDFLoad'], - ['startMIDDLELast', 'startMIDDLELast'], - ['AString', 'AString'], - ['Some4Numbers234', 'Some4Numbers234'], - ['TEST123String', 'TEST123String'], - ['hello_world', 'hello_world'], - ['hello__world', 'hello__world'], - ['_hello_world_', '_hello_world_'], - ['hello_World', 'hello_World'], - ['HelloWorld', 'HelloWorld'], - ['helloWorldFoo', 'helloWorldFoo'], - ['myHTMLFiLe', 'myHTMLFiLe'], - ['aBaBaB', 'aBaBaB'], - ['BaBaBa', 'BaBaBa'], - ['libC', 'libC'], -]); - -dataset('kebabToCamelCaseCheckCorrect', [ - ['simple-test', 'simpleTest'], - ['easy', 'easy'], - ['simple-xml', 'simpleXml'], - ['pdf-load', 'pdfLoad'], - ['start-middle-last', 'startMiddleLast'], - ['a-string', 'aString'], - ['some4-numbers234', 'some4Numbers234'], - ['test123-string', 'test123String'], - ['test123 456', 'test123 456'], - ['hello-world', 'helloWorld'], - ['-hello-world-', 'helloWorld'], - ['hello-world', 'helloWorld'], - ['hello-world', 'helloWorld'], - ['hello-world-foo', 'helloWorldFoo'], - ['my-html-fi-le', 'myHtmlFiLe'], - ['a-ba-ba-b', 'aBaBaB'], - ['ba-ba-ba', 'baBaBa'], - ['lib-c', 'libC'], -]); - -dataset('kebabToCamelCaseCheckWrong', [ - ['simple-test', 'simpletest'], - ['HTML', 'HTML'], - ['simple-xml', 'simpleXML'], - ['pdf-load', 'PDFLoad'], - ['start-MIDDLE-last', 'startMIDDLElast'], - ['a-string', 'AString'], - ['some4-numbers234', 'Some4Numbers234'], - ['test123-string', 'Test123String'], - ['-hello-world-', 'HelloWorld'], - ['hello-world-foo', 'HelloWorldFoo'], - ['hello-world', 'HelloWorld'], - ['my-html-fi-le', 'MyHtmlFiLe'], - ['a-ba-ba-b', 'ABaBaB'], - ['ba-ba-ba', 'BaBaBa'], - ['lib-c', 'libc'], -]); - -dataset('getGithubPluginNameCorrect', [ - ['some-plugin-name', 'some-plugin-name'], - ['infinum/some-plugin-name', 'some-plugin-name'], - ['simple', 'simple'], - ['infinum/simple', 'simple'], - ['infinum/something-else/simple', 'simple'], -]); - -dataset('getGithubPluginNameWrong', [ - ['infinum/some-plugin-name', 'infinum/some-plugin-name'], - ['infinum/something-else/simple', 'infinum/something-else'], - ['infinum/something-else/simple', 'something-else/simple'], -]); - -dataset('hexToRgbValid', [ - ['#FFF', '255 255 255'], - ['#000000', '0 0 0'], - ['#123456', '18 52 86'], -]); - -dataset('hexToRgbInvalid', [ - ['', '0 0 0'], - ['#', '0 0 0'], - ['#1234', '0 0 0'], - ['#mnopqr', '0 0 0'], - ['#ESHIFT', '0 0 0'], -]); diff --git a/tests/Datasets/Autowiring/Blocks/components/test-component/test-component.php b/tests/Datasets/Autowiring/Blocks/components/test-component/test-component.php deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/Datasets/Autowiring/Deep/Deeper/ServiceNoDependenciesDeep.php b/tests/Datasets/Autowiring/Deep/Deeper/ServiceNoDependenciesDeep.php deleted file mode 100644 index af7b85fdc..000000000 --- a/tests/Datasets/Autowiring/Deep/Deeper/ServiceNoDependenciesDeep.php +++ /dev/null @@ -1,19 +0,0 @@ -classLvl2Dependency = $classLvl2Dependency; - } -} diff --git a/tests/Datasets/Autowiring/Dependencies/ClassLvl2Dependency.php b/tests/Datasets/Autowiring/Dependencies/ClassLvl2Dependency.php deleted file mode 100644 index 6b81ce2d2..000000000 --- a/tests/Datasets/Autowiring/Dependencies/ClassLvl2Dependency.php +++ /dev/null @@ -1,12 +0,0 @@ -classLvl3Dependency = $classLvl3Dependency; - } -} diff --git a/tests/Datasets/Autowiring/Dependencies/ClassLvl3Dependency.php b/tests/Datasets/Autowiring/Dependencies/ClassLvl3Dependency.php deleted file mode 100644 index bd0aa5452..000000000 --- a/tests/Datasets/Autowiring/Dependencies/ClassLvl3Dependency.php +++ /dev/null @@ -1,12 +0,0 @@ -classLvl4Dependency = $classLvl4Dependency; - } -} diff --git a/tests/Datasets/Autowiring/Dependencies/ClassLvl4Dependency.php b/tests/Datasets/Autowiring/Dependencies/ClassLvl4Dependency.php deleted file mode 100644 index 4495eefc2..000000000 --- a/tests/Datasets/Autowiring/Dependencies/ClassLvl4Dependency.php +++ /dev/null @@ -1,12 +0,0 @@ -classLvl5Dependency = $classLvl5Dependency; - } -} diff --git a/tests/Datasets/Autowiring/Dependencies/ClassLvl5Dependency.php b/tests/Datasets/Autowiring/Dependencies/ClassLvl5Dependency.php deleted file mode 100644 index 9a6603dff..000000000 --- a/tests/Datasets/Autowiring/Dependencies/ClassLvl5Dependency.php +++ /dev/null @@ -1,12 +0,0 @@ -classLvl6Dependency = $classLvl6Dependency; - } -} diff --git a/tests/Datasets/Autowiring/Dependencies/ClassLvl6Dependency.php b/tests/Datasets/Autowiring/Dependencies/ClassLvl6Dependency.php deleted file mode 100644 index 92273cab4..000000000 --- a/tests/Datasets/Autowiring/Dependencies/ClassLvl6Dependency.php +++ /dev/null @@ -1,12 +0,0 @@ -classLvl7Dependency = $classLvl7Dependency; - } -} diff --git a/tests/Datasets/Autowiring/Dependencies/ClassLvl7Dependency.php b/tests/Datasets/Autowiring/Dependencies/ClassLvl7Dependency.php deleted file mode 100644 index e257bd4f5..000000000 --- a/tests/Datasets/Autowiring/Dependencies/ClassLvl7Dependency.php +++ /dev/null @@ -1,9 +0,0 @@ -classDepWithNoDependencies = $classDepWithNoDependencies; - } -} diff --git a/tests/Datasets/Autowiring/Dependencies/InterfaceDependency.php b/tests/Datasets/Autowiring/Dependencies/InterfaceDependency.php deleted file mode 100644 index 0d0e2b838..000000000 --- a/tests/Datasets/Autowiring/Dependencies/InterfaceDependency.php +++ /dev/null @@ -1,9 +0,0 @@ -classDepWithNoDependencies = $classDepWithNoDependencies; - } - - /** - * Registers service. - * - * @return void - */ - public function register(): void - { - } -} diff --git a/tests/Datasets/Autowiring/Services/ServiceWithDeepClassDep.php b/tests/Datasets/Autowiring/Services/ServiceWithDeepClassDep.php deleted file mode 100644 index 133e53584..000000000 --- a/tests/Datasets/Autowiring/Services/ServiceWithDeepClassDep.php +++ /dev/null @@ -1,25 +0,0 @@ -classWithDependency = $classWithDependency; - } - - /** - * Registers service. - * - * @return void - */ - public function register(): void - { - } -} diff --git a/tests/Datasets/Autowiring/Services/ServiceWithDeepDependencyTree.php b/tests/Datasets/Autowiring/Services/ServiceWithDeepDependencyTree.php deleted file mode 100644 index 6062d1d38..000000000 --- a/tests/Datasets/Autowiring/Services/ServiceWithDeepDependencyTree.php +++ /dev/null @@ -1,25 +0,0 @@ -classLvl1Dependency = $classLvl1Dependency; - } - - /** - * Registers service. - * - * @return void - */ - public function register(): void - { - } -} diff --git a/tests/Datasets/Autowiring/Services/ServiceWithInterfaceDep.php b/tests/Datasets/Autowiring/Services/ServiceWithInterfaceDep.php deleted file mode 100644 index 29ee7cf36..000000000 --- a/tests/Datasets/Autowiring/Services/ServiceWithInterfaceDep.php +++ /dev/null @@ -1,24 +0,0 @@ -classImplementingInterfaceDependency = $classImplementingInterfaceDependency; - } - - /** - * Registers service. - * - * @return void - */ - public function register(): void - { - } -} diff --git a/tests/Datasets/Autowiring/Services/ServiceWithInterfaceDepMoreThanOneClassFound.php b/tests/Datasets/Autowiring/Services/ServiceWithInterfaceDepMoreThanOneClassFound.php deleted file mode 100644 index 5cee5d315..000000000 --- a/tests/Datasets/Autowiring/Services/ServiceWithInterfaceDepMoreThanOneClassFound.php +++ /dev/null @@ -1,24 +0,0 @@ -someClass = $someClass; - } - - /** - * Registers service. - * - * @return void - */ - public function register(): void - { - } -} diff --git a/tests/Datasets/Autowiring/Services/ServiceWithInterfaceDepWrongName.php b/tests/Datasets/Autowiring/Services/ServiceWithInterfaceDepWrongName.php deleted file mode 100644 index 7ab71019a..000000000 --- a/tests/Datasets/Autowiring/Services/ServiceWithInterfaceDepWrongName.php +++ /dev/null @@ -1,24 +0,0 @@ -incorrectVariableName = $incorrectVariableName; - } - - /** - * Registers service. - * - * @return void - */ - public function register(): void - { - } -} diff --git a/tests/Datasets/Autowiring/Services/ServiceWithMultipleDeps.php b/tests/Datasets/Autowiring/Services/ServiceWithMultipleDeps.php deleted file mode 100644 index 5e63254af..000000000 --- a/tests/Datasets/Autowiring/Services/ServiceWithMultipleDeps.php +++ /dev/null @@ -1,26 +0,0 @@ -classImplementingInterfaceDependency = $classImplementingInterfaceDependency; - $this->classDepWithNoDependencies = $classDepWithNoDependencies; - } - - /** - * Registers service. - * - * @return void - */ - public function register(): void - { - } -} diff --git a/tests/Datasets/Autowiring/Services/ServiceWithPrimitiveDep.php b/tests/Datasets/Autowiring/Services/ServiceWithPrimitiveDep.php deleted file mode 100644 index 50bb68dfc..000000000 --- a/tests/Datasets/Autowiring/Services/ServiceWithPrimitiveDep.php +++ /dev/null @@ -1,23 +0,0 @@ -something = $something; - } - - /** - * Registers service. - * - * @return void - */ - public function register(): void - { - } -} diff --git a/tests/Datasets/Autowiring/Services/ServiceWithPrimitiveDepHasDefault.php b/tests/Datasets/Autowiring/Services/ServiceWithPrimitiveDepHasDefault.php deleted file mode 100644 index 17ef3fc61..000000000 --- a/tests/Datasets/Autowiring/Services/ServiceWithPrimitiveDepHasDefault.php +++ /dev/null @@ -1,23 +0,0 @@ -something = $something; - } - - /** - * Registers service. - * - * @return void - */ - public function register(): void - { - } -} diff --git a/tests/Datasets/Mock.php b/tests/Datasets/Mock.php deleted file mode 100644 index e0cb59df1..000000000 --- a/tests/Datasets/Mock.php +++ /dev/null @@ -1,31 +0,0 @@ - 1180, - 'height' => 1860, - 'file' => '2022/05/test.png', - 'sizes' => [ - 'thumbnail' => [ - 'file' => 'test-150x150.png', - 'width' => 150, - 'height' => 150, - 'mime-type' => 'image/png', - ], - ], - ]; -} - -function attachemntMetaDataBrokenMock() { - return [ - 'width' => 1180, - 'height' => 1860, - 'sizes' => [ - 'thumbnail' => [ - 'width' => 150, - 'height' => 150, - 'mime-type' => 'image/png', - ], - ], - ]; -} diff --git a/tests/Helpers.php b/tests/Helpers.php deleted file mode 100644 index 7940256a2..000000000 --- a/tests/Helpers.php +++ /dev/null @@ -1,32 +0,0 @@ -__invoke([], []); - - (new BlocksExample())->getBlocksDataFullRaw(); -} - -/** - * Mock Mockery interface. - * - * @param string $class Class to mock. - * - * @return MockInterface - */ -function mock(string $classname): MockInterface -{ - return Mockery::mock($classname); -} diff --git a/tests/Pest.php b/tests/Pest.php deleted file mode 100644 index 9e203ff91..000000000 --- a/tests/Pest.php +++ /dev/null @@ -1,7 +0,0 @@ -group('unit')->in('Unit'); - -uses(BaseTest::class)->in('Unit'); diff --git a/tests/Unit/AdminMenus/AdminMenuCliTest.php b/tests/Unit/AdminMenus/AdminMenuCliTest.php deleted file mode 100644 index 241e44e71..000000000 --- a/tests/Unit/AdminMenus/AdminMenuCliTest.php +++ /dev/null @@ -1,124 +0,0 @@ -mock = new AdminMenuCli('boilerplate'); -}); - -afterEach(function () { - unset($this->mock); -}); - -//---------------------------------------------------------------------------------// - -test('getCommandParentName will return correct value', function () { - expect($this->mock->getCommandParentName()) - ->toBeString() - ->toEqual(CliCreate::COMMAND_NAME); -}); - -//---------------------------------------------------------------------------------// - -test('getCommandName will return correct value', function () { - expect($this->mock->getCommandName()) - ->toBeString() - ->toEqual('admin-menu'); -}); - -//---------------------------------------------------------------------------------// - -test('getDefaultArgs will return correct array', function () { - expect($this->mock->getDefaultArgs()) - ->toBeArray() - ->toMatchArray([ - 'title' => 'Admin Title', - 'menu_title' => 'Admin Menu Title', - 'capability' => 'edit_posts', - 'menu_slug' => 'example-menu-slug', - 'menu_icon' => 'dashicons-admin-generic', - 'menu_position' => 100, - ]); -}); - -//---------------------------------------------------------------------------------// - -test('getDoc will return correct array', function () { - $docs = $this->mock->getDoc(); - - expect($docs) - ->toBeArray() - ->toHaveKeys(['shortdesc', 'synopsis', 'longdesc']) - ->and(count($docs['synopsis']))->toEqual(6) - ->and($docs['synopsis'][0]['name'])->toEqual('title') - ->and($docs['synopsis'][1]['name'])->toEqual('menu_title') - ->and($docs['synopsis'][2]['name'])->toEqual('capability') - ->and($docs['synopsis'][3]['name'])->toEqual('menu_slug') - ->and($docs['synopsis'][4]['name'])->toEqual('menu_icon') - ->and($docs['synopsis'][5]['name'])->toEqual('menu_position'); -}); - -//---------------------------------------------------------------------------------// - -test('__invoke will will correctly copy example class with default args', function () { - $mock = $this->mock; - $mock([], $this->mock->getDefaultArgs([])); - - $sep = \DIRECTORY_SEPARATOR; - $output = \file_get_contents(Components::getProjectPaths('srcDestination', "AdminMenus{$sep}ExampleMenuSlugAdminMenu.php")); - - expect($output) - ->toContain( - 'class ExampleMenuSlugAdminMenu', - 'Admin Title', - 'Admin Menu Title', - 'edit_posts', - 'example-menu-slug', - 'dashicons-admin-generic', - ) - ->not->toContain( - 'class AdminMenuExample', - '%title%', - '%menu_title%', - '%capability%', - '%menu_slug%', - '%menu_icon%', - ); -}); - -test('__invoke will will correctly copy example class with custom args', function () { - $mock = $this->mock; - $mock([], [ - 'title' => 'Admin Title Test', - 'menu_title' => 'Admin Menu Title Test', - 'capability' => 'edit_posts_test', - 'menu_slug' => 'example-menu-slug-test', - 'menu_icon' => 'dashicons-admin-generic-test', - 'menu_position' => 200, - ]); - - $sep = \DIRECTORY_SEPARATOR; - $output = \file_get_contents(Components::getProjectPaths('srcDestination', "AdminMenus{$sep}ExampleMenuSlugTestAdminMenu.php")); - - expect($output) - ->toContain( - 'class ExampleMenuSlugTestAdminMenu', - 'Admin Title Test', - 'Admin Menu Title Test', - 'edit_posts_test', - 'example-menu-slug-test', - 'dashicons-admin-generic-test', - ) - ->not->toContain( - 'class AdminMenuExample', - '%title%', - '%menu_title%', - '%capability%', - '%menu_slug%', - '%menu_icon%', - ); -}); diff --git a/tests/Unit/AdminMenus/AdminMenuExampleTest.php b/tests/Unit/AdminMenus/AdminMenuExampleTest.php deleted file mode 100644 index d7a223e35..000000000 --- a/tests/Unit/AdminMenus/AdminMenuExampleTest.php +++ /dev/null @@ -1,78 +0,0 @@ -mock = new AdminMenuExample(); -}); - -afterEach(function () { - unset($this->mock); -}); - -//---------------------------------------------------------------------------------// - -test('register will load all hooks', function () { - - $this->mock->register(); - - expect(has_action('admin_menu', 'EightshiftBoilerplate\AdminMenus\AdminMenuExample->callback()')) - ->toBe(10); -}); - -//---------------------------------------------------------------------------------// - -test('callback will load correct method', function () { - - $action = 'add_menu_page'; - Functions\when($action)->justReturn(putenv("ES_SIDEAFFECT_1={$action}")); - - $this->mock->callback(); - - expect(getenv('ES_SIDEAFFECT_1'))->toEqual($action); -}); - -//---------------------------------------------------------------------------------// - -test('processAdminMenu will echo component view', function () { - $mock = new class extends AdminMenuExample { - protected function getViewComponent(): string - { - return 'themes/missing'; - } - }; - - buildTestBlocks(); - - ob_start(); - $this->mock->processAdminMenu([]); - $contents = ob_get_clean(); - - expect($contents) - ->not->toBeEmpty() - ->toBe('
      Hi!
      '); -}); - -test('processAdminMenu will echo error if component is missing', function () { - $mock = new class extends AdminMenuExample { - protected function getViewComponent(): string - { - return 'missing'; - } - }; - - buildTestBlocks(); - - ob_start(); - $mock->processAdminMenu([]); - $contents = ob_get_clean(); - - expect($contents) - ->not->toBeEmpty() - ->toContain('
      Unable to locate component by path:');
      -});
      diff --git a/tests/Unit/AdminMenus/AdminReusableBlocksMenuCliTest.php b/tests/Unit/AdminMenus/AdminReusableBlocksMenuCliTest.php
      deleted file mode 100644
      index e3cf6de9e..000000000
      --- a/tests/Unit/AdminMenus/AdminReusableBlocksMenuCliTest.php
      +++ /dev/null
      @@ -1,118 +0,0 @@
      -mock = new AdminReusableBlocksMenuCli('boilerplate');
      -});
      -
      -afterEach(function () {
      -	unset($this->mock);
      -});
      -
      -//---------------------------------------------------------------------------------//
      -
      -test('getCommandParentName will return correct value', function () {
      -	expect($this->mock->getCommandParentName())
      -		->toBeString()
      -		->toEqual(CliCreate::COMMAND_NAME);
      -});
      -
      -//---------------------------------------------------------------------------------//
      -
      -test('getCommandName will return correct value', function () {
      -	expect($this->mock->getCommandName())
      -		->toBeString()
      -		->toEqual('admin-reusable-blocks-menu');
      -});
      -
      -//---------------------------------------------------------------------------------//
      -
      -test('getDefaultArgs will return correct array', function () {
      -	expect($this->mock->getDefaultArgs())
      -		->toBeArray()
      -		->toHaveKeys([
      -			'title',
      -			'menu_title',
      -			'capability',
      -			'menu_icon',
      -			'menu_position',
      -		]);
      -});
      -
      -//---------------------------------------------------------------------------------//
      -
      -test('getDoc will return correct array', function () {
      -	$docs = $this->mock->getDoc();
      -
      -	expect($docs)
      -		->toBeArray()
      -		->toHaveKeys(['shortdesc', 'synopsis', 'longdesc'])
      -		->and(count($docs['synopsis']))->toEqual(5)
      -		->and($docs['synopsis'][0]['name'])->toEqual('title')
      -		->and($docs['synopsis'][1]['name'])->toEqual('menu_title')
      -		->and($docs['synopsis'][2]['name'])->toEqual('capability')
      -		->and($docs['synopsis'][3]['name'])->toEqual('menu_icon')
      -		->and($docs['synopsis'][4]['name'])->toEqual('menu_position');
      -});
      -
      -//---------------------------------------------------------------------------------//
      -
      -test('__invoke will will correctly copy example class with default args', function () {
      -	$mock = $this->mock;
      -	$mock([], $this->mock->getDefaultArgs([]));
      -
      -	$sep = \DIRECTORY_SEPARATOR;
      -	$output = \file_get_contents(Components::getProjectPaths('srcDestination', "AdminMenus{$sep}AdminReusableBlocksMenu.php"));
      -
      -	expect($output)
      -		->toContain(
      -			'class AdminReusableBlocksMenu',
      -			'Reusable blocks',
      -			'Reusable blocks',
      -			'edit_posts',
      -		)
      -		->not->toContain(
      -			'class AdminReusableBlocksMenuExample',
      -			'%title%',
      -			'%menu_title%',
      -			'%capability%',
      -			'%menu_icon%',
      -			'%menu_position%',
      -		);
      -});
      -
      -test('__invoke will will correctly copy example class with custom args', function () {
      -	$mock = $this->mock;
      -	$mock([], [
      -		'title' => 'Reusable Blocks Test',
      -		'menu_title' => 'Reusable Blocks Test',
      -		'capability' => 'edit_posts_test',
      -		'menu_icon' => 'dashicons-table-row-before-test',
      -		'menu_position' => 5,
      -	]);
      -
      -	$sep = \DIRECTORY_SEPARATOR;
      -	$output = \file_get_contents(Components::getProjectPaths('srcDestination', "AdminMenus{$sep}AdminReusableBlocksMenu.php"));
      -
      -	expect($output)
      -		->toContain(
      -			'class AdminReusableBlocksMenu',
      -			'Reusable Blocks Test',
      -			'Reusable Blocks Test',
      -			'edit_posts_test',
      -			'dashicons-table-row-before-test',
      -		)
      -		->not->toContain(
      -			'class AdminReusableBlocksMenuExample',
      -			'%title%',
      -			'%menu_title%',
      -			'%capability%',
      -			'%menu_icon%',
      -			'%menu_position%',
      -		);
      -});
      diff --git a/tests/Unit/AdminMenus/AdminReusableBlocksMenuExampleTest.php b/tests/Unit/AdminMenus/AdminReusableBlocksMenuExampleTest.php
      deleted file mode 100644
      index 0c27a7c4b..000000000
      --- a/tests/Unit/AdminMenus/AdminReusableBlocksMenuExampleTest.php
      +++ /dev/null
      @@ -1,46 +0,0 @@
      -example = new AdminReusableBlocksMenuExample();
      -});
      -
      -afterEach(function () {
      -	unset($this->example);
      -});
      -
      -test('Register method will call admin_menu hook', function () {
      -	Actions\expectAdded('admin_menu')->with(\Mockery::type('Closure'));
      -
      -	$this->example->register();
      -
      -	$this->assertSame(10, has_action('admin_menu', 'function()'));
      -});
      -
      -
      -test('getMenuSlug will return the default menu slug', function() {
      -
      -	// We shouldn't do this, but the add_menu_page is called in a closure.
      -	$method = new \ReflectionMethod('EightshiftBoilerplate\\AdminMenus\\AdminReusableBlocksMenuExample', 'getMenuSlug');
      -	$method->setAccessible(true);
      -
      -	expect($method->invoke(new AdminReusableBlocksMenuExample()))
      -		->not->toBeEmpty()
      -		->toBe('edit.php?post_type=wp_block');
      -});
      -
      -
      -test('getIcon will return the default icon', function() {
      -
      -	// We shouldn't do this, but the add_menu_page is called in a closure.
      -	$method = new \ReflectionMethod('EightshiftBoilerplate\\AdminMenus\\AdminReusableBlocksMenuExample', 'getIcon');
      -	$method->setAccessible(true);
      -
      -	expect($method->invoke(new AdminReusableBlocksMenuExample()))
      -		->not->toBeEmpty()
      -		->toBe('%menu_icon%');
      -});
      diff --git a/tests/Unit/AdminMenus/AdminSubMenuCliTest.php b/tests/Unit/AdminMenus/AdminSubMenuCliTest.php
      deleted file mode 100644
      index 2ff532cdd..000000000
      --- a/tests/Unit/AdminMenus/AdminSubMenuCliTest.php
      +++ /dev/null
      @@ -1,121 +0,0 @@
      -mock = new AdminSubMenuCli('boilerplate');
      -});
      -
      -afterEach(function () {
      -	unset($this->mock);
      -});
      -
      -//---------------------------------------------------------------------------------//
      -
      -test('getCommandParentName will return correct value', function () {
      -	expect($this->mock->getCommandParentName())
      -		->toBeString()
      -		->toEqual(CliCreate::COMMAND_NAME);
      -});
      -
      -//---------------------------------------------------------------------------------//
      -
      -test('getCommandName will return correct value', function () {
      -	expect($this->mock->getCommandName())
      -		->toBeString()
      -		->toEqual('admin-sub-menu');
      -});
      -
      -//---------------------------------------------------------------------------------//
      -
      -test('getDefaultArgs will return correct array', function () {
      -	expect($this->mock->getDefaultArgs())
      -		->toBeArray()
      -		->toMatchArray([
      -			'parent_slug' => 'example-parent-slug',
      -			'title' => 'Admin Title',
      -			'menu_title' => 'Admin Sub Menu Title',
      -			'capability' => 'edit_posts',
      -			'menu_slug' => 'example-menu-slug',
      -		]);
      -});
      -
      -//---------------------------------------------------------------------------------//
      -
      -test('getDoc will return correct array', function () {
      -	$docs = $this->mock->getDoc();
      -
      -	expect($docs)
      -		->toBeArray()
      -		->toHaveKeys(['shortdesc', 'synopsis', 'longdesc'])
      -		->and(count($docs['synopsis']))->toEqual(5)
      -		->and($docs['synopsis'][0]['name'])->toEqual('parent_slug')
      -		->and($docs['synopsis'][1]['name'])->toEqual('title')
      -		->and($docs['synopsis'][2]['name'])->toEqual('menu_title')
      -		->and($docs['synopsis'][3]['name'])->toEqual('capability')
      -		->and($docs['synopsis'][4]['name'])->toEqual('menu_slug');
      -});
      -
      -//---------------------------------------------------------------------------------//
      -
      -test('__invoke will will correctly copy example class with default args', function () {
      -	$mock = $this->mock;
      -	$mock([], $this->mock->getDefaultArgs([]));
      -
      -	$sep = \DIRECTORY_SEPARATOR;
      -	$output = \file_get_contents(Components::getProjectPaths('srcDestination', "AdminMenus{$sep}ExampleMenuSlugAdminSubMenu.php"));
      -
      -	expect($output)
      -		->toContain(
      -			'class ExampleMenuSlugAdminSubMenu',
      -			'example-parent-slug',
      -			'Admin Title',
      -			'Admin Sub Menu Title',
      -			'edit_posts',
      -			'example-menu-slug',
      -		)
      -		->not->toContain(
      -			'class AdminSubMenuExample',
      -			'%parent_slug%',
      -			'%title%',
      -			'%menu_title%',
      -			'%capability%',
      -			'%menu_slug%',
      -		);
      -});
      -
      -test('__invoke will will correctly copy example class with custom args', function () {
      -	$mock = $this->mock;
      -	$mock([], [
      -		'parent_slug' => 'example-parent-slug-test',
      -		'title' => 'Admin Title Test',
      -		'menu_title' => 'Admin Sub Menu Title Test',
      -		'capability' => 'edit_posts_test',
      -		'menu_slug' => 'example-menu-slug-test',
      -	]);
      -
      -	$sep = \DIRECTORY_SEPARATOR;
      -	$output = \file_get_contents(Components::getProjectPaths('srcDestination', "AdminMenus{$sep}ExampleMenuSlugTestAdminSubMenu.php"));
      -
      -	expect($output)
      -		->toContain(
      -			'class ExampleMenuSlugTestAdminSubMenu',
      -			'example-parent-slug-test',
      -			'Admin Title Test',
      -			'Admin Sub Menu Title Test',
      -			'edit_posts_test',
      -			'example-menu-slug-test',
      -		)
      -		->not->toContain(
      -			'class AdminSubMenuExample',
      -			'%parent_slug%',
      -			'%title%',
      -			'%menu_title%',
      -			'%capability%',
      -			'%menu_slug%',
      -		);
      -});
      diff --git a/tests/Unit/AnalyticsGdpr/AnalyticsGdprCliTest.php b/tests/Unit/AnalyticsGdpr/AnalyticsGdprCliTest.php
      deleted file mode 100644
      index 9cc6f22bb..000000000
      --- a/tests/Unit/AnalyticsGdpr/AnalyticsGdprCliTest.php
      +++ /dev/null
      @@ -1,51 +0,0 @@
      -mock = new AnalyticsGdprCli('boilerplate');
      -});
      -
      -afterEach(function () {
      -	unset($this->mock);
      -});
      -
      -
      -test('Custom Analytics & GDPR Settings CLI command will correctly copy the AnalyticsGdpr class with defaults', function () {
      -	$analyticsGdpr = $this->mock;
      -	$analyticsGdpr([], []);
      -
      -	// Check the output dir if the generated method is correctly generated.
      -	$generatedMeta = file_get_contents(Components::getProjectPaths('srcDestination', 'AnalyticsGdpr/AnalyticsGdpr.php'));
      -
      -	expect($generatedMeta)
      -		->toBeString()
      -		->toContain('class AnalyticsGdpr implements ServiceInterface')
      -		->toContain('acf_add_options_page')
      -		->toContain('acf_add_local_field_group')
      -		->toContain('createAnalyticsPage')
      -		->toContain('registerAnalytics')
      -		->toContain('createGdprModalPage')
      -		->toContain('registerGdprModalSettings')
      -		->toContain('prepareGdprModalData')
      -		->not->toContain('someRandomMethod');
      -});
      -
      -test('Custom GDPR settings CLI documentation is correct', function () {
      -	$analyticsGdpr = $this->mock;
      -
      -	$documentation = $analyticsGdpr->getDoc();
      -
      -	$descKey = 'shortdesc';
      -
      -	expect($documentation)
      -		->toBeArray()
      -		->toHaveKey($descKey);
      -
      -	expect($documentation[$descKey])
      -		->toBeString()
      -		->toBe('Create project Analytics and GDPR Settings classes using ACF plugin.');
      -});
      diff --git a/tests/Unit/AnalyticsGdpr/AnalyticsGdprExampleTest.php b/tests/Unit/AnalyticsGdpr/AnalyticsGdprExampleTest.php
      deleted file mode 100644
      index e6d04ef2d..000000000
      --- a/tests/Unit/AnalyticsGdpr/AnalyticsGdprExampleTest.php
      +++ /dev/null
      @@ -1,67 +0,0 @@
      -example = new AnalyticsGdprExample();
      -});
      -
      -afterEach(function () {
      -	unset($this->example);
      -});
      -
      -test('Register method will bail out if ACF is not registered/activated', function () {
      -	expect($this->example->register())->toBeNull();
      -});
      -
      -test('Analytics and GDPR Settings actions are registered', function () {
      -	$this->example->register();
      -
      -	expect(\method_exists($this->example, 'register'))->toBeTrue();
      -	expect(has_action('acf/init', [$this->example, 'createAnalyticsPage']))->toBe(11);
      -	expect(has_action('acf/init', [$this->example, 'registerAnalytics']))->toBe(12);
      -
      -	expect(has_action('acf/init', [$this->example, 'createGdprModalPage']))->toBe(12);
      -	expect(has_action('acf/init', [$this->example, 'registerGdprModalSettings']))->toBe(13);
      -});
      -
      -test('Filter for GDPR Modal data is registered', function () {
      -	$this->example->register();
      -
      -	expect(has_filter(AnalyticsGdprExample::GET_GDPR_MODAL_DATA, 'EightshiftBoilerplate\AnalyticsGdpr\AnalyticsGdprExample->prepareGdprModalData()'))->toBe(10);
      -});
      -
      -test('Method for adding Analytics Settings as ACF Options page exists', function () {
      -	$this->example->createAnalyticsPage();
      -
      -	expect(\method_exists($this->example, 'createAnalyticsPage'))->toBeTrue();
      -});
      -
      -test('Method for adding ACF fields to Analytics Settings page exists', function () {
      -	$this->example->registerAnalytics();
      -
      -	expect(\method_exists($this->example, 'registerAnalytics'))->toBeTrue();
      -});
      -
      -
      -test('Method for adding GDPR Settings as ACF Options subpage exists', function () {
      -	$this->example->createGdprModalPage();
      -
      -	expect(\method_exists($this->example, 'createGdprModalPage'))->toBeTrue();
      -});
      -
      -test('Method for adding ACF fields to GDPR Settings page exists', function () {
      -	$this->example->registerGdprModalSettings();
      -
      -	expect(\method_exists($this->example, 'registerGdprModalSettings'))->toBeTrue();
      -});
      -
      -test('Method for preparing GDPR modal data exists and will return an array', function () {
      -	$gdprModalData = $this->example->prepareGdprModalData();
      -
      -	expect(\method_exists($this->example, 'prepareGdprModalData'))->toBeTrue();
      -
      -	expect($gdprModalData)->toBeArray();
      -});
      diff --git a/tests/Unit/BlockPatterns/BlockPatternCliTest.php b/tests/Unit/BlockPatterns/BlockPatternCliTest.php
      deleted file mode 100644
      index c7b96d0b2..000000000
      --- a/tests/Unit/BlockPatterns/BlockPatternCliTest.php
      +++ /dev/null
      @@ -1,113 +0,0 @@
      -mock = new BlockPatternCli('boilerplate');
      -});
      -
      -afterEach(function () {
      -	unset($this->mock);
      -});
      -
      -//---------------------------------------------------------------------------------//
      -
      -test('Block pattern CLI command will correctly copy the Block Pattern class with defaults', function () {
      -	$mock = $this->mock;
      -	$mock([], $this->mock->getDefaultArgs());
      -
      -	// Check the output dir if the generated method is correctly generated.
      -	$sep = \DIRECTORY_SEPARATOR;
      -
      -	$output = \file_get_contents(Components::getProjectPaths('srcDestination', "BlockPatterns{$sep}ExampleTitleBlockPattern.php"));
      -
      -	expect($output)
      -		->toContain(
      -			'class ExampleTitleBlockPattern',
      -			'example-title',
      -			'example-name',
      -			'example-description',
      -			'example-content'
      -		)
      -		->not->toContain(
      -			'class BlockPatternExample',
      -			'%title%',
      -			'%name%',
      -			'%description%',
      -			'%content%'
      -		);
      -});
      -
      -
      -test('Block pattern CLI command will correctly copy the Block pattern class with set arguments', function () {
      -	$mock = $this->mock;
      -	$mock([], [
      -		'title' => 'Your Own Thing',
      -		'name' => 'eightshift-boilerplate/your-own-thing',
      -		'description' => 'Description of the your own thing pattern',
      -		'content' => 'this-one-has-some-content',
      -	]);
      -
      -	// Check the output dir if the generated method is correctly generated.
      -	$output = \file_get_contents(Components::getProjectPaths('srcDestination', 'BlockPatterns/YourOwnThingBlockPattern.php'));
      -
      -	expect($output)
      -	->toContain(
      -		'class YourOwnThingBlockPattern',
      -		'Your Own Thing',
      -		'eightshift-boilerplate/your-own-thing',
      -		'Description of the your own thing pattern',
      -		'this-one-has-some-content'
      -	)
      -	->not->toContain(
      -		'class BlockPatternExample',
      -		'%title%',
      -		'%name%',
      -		'%description%',
      -		'%content%'
      -	);
      -});
      -
      -test('Block pattern CLI command will generate a name from title if "name" argument is not provided', function () {
      -	$mock = $this->mock;
      -	$mock([], [
      -		'title' => 'Your Own Thing',
      -		'name' => '',
      -		'description' => 'Description of the your own thing pattern',
      -		'content' => 'this-one-has-some-content',
      -	]);
      -
      -	$output = \file_get_contents(Components::getProjectPaths('srcDestination', 'BlockPatterns/YourOwnThingBlockPattern.php'));
      -
      -	expect($output)
      -	->toContain(
      -		'class YourOwnThingBlockPattern',
      -		'Your Own Thing',
      -		'eightshift-boilerplate/your-own-thing',
      -		'Description of the your own thing pattern',
      -		'this-one-has-some-content'
      -	)
      -	->not->toContain(
      -		'class BlockPatternExample',
      -		'%title%',
      -		'%name%',
      -		'%description%',
      -		'%content%'
      -	);
      -});
      -
      -test('getDoc will return correct array', function () {
      -	$docs = $this->mock->getDoc();
      -
      -	expect($docs)
      -		->toBeArray()
      -		->toHaveKeys(['shortdesc', 'synopsis', 'longdesc'])
      -		->and(count($docs['synopsis']))->toEqual(4)
      -		->and($docs['synopsis'][0]['name'])->toEqual('title')
      -		->and($docs['synopsis'][1]['name'])->toEqual('name')
      -		->and($docs['synopsis'][2]['name'])->toEqual('description')
      -		->and($docs['synopsis'][3]['name'])->toEqual('content');
      -});
      diff --git a/tests/Unit/BlockPatterns/BlockPatternExampleTest.php b/tests/Unit/BlockPatterns/BlockPatternExampleTest.php
      deleted file mode 100644
      index 4ef962fbf..000000000
      --- a/tests/Unit/BlockPatterns/BlockPatternExampleTest.php
      +++ /dev/null
      @@ -1,36 +0,0 @@
      -example = new BlockPatternExample();
      -});
      -
      -afterEach(function () {
      -	unset($this->example);
      -});
      -
      -test('Register method will call init hook', function () {
      -	$this->example->register();
      -
      -	$this->assertSame(10, has_action('init', 'EightshiftBoilerplate\BlockPatterns\BlockPatternExample->registerBlockPattern()'));
      -});
      -
      -/**
      - * This is a tricky one. Because it should be an integration test:
      - * testing if the CPT was actually registered when the action runs.
      - */
      -test('Register block pattern method will be called', function() {
      -	$action = 'block_pattern_registered';
      -	Functions\when('register_block_pattern')->justReturn(putenv("SIDEAFFECT={$action}"));
      -
      -	$this->example->registerBlockPattern();
      -
      -	$this->assertSame(\getenv('SIDEAFFECT'), $action);
      -
      -	// Cleanup.
      -	putenv('SIDEAFFECT=');
      -});
      diff --git a/tests/Unit/Blocks/BlockCliTest.php b/tests/Unit/Blocks/BlockCliTest.php
      deleted file mode 100644
      index 0776d3adf..000000000
      --- a/tests/Unit/Blocks/BlockCliTest.php
      +++ /dev/null
      @@ -1,48 +0,0 @@
      -mock = new UseBlockCli('boilerplate');
      -});
      -
      -afterEach(function () {
      -	unset($this->mock);
      -});
      -
      -test('Block CLI command will correctly copy the Block class with defaults', function () {
      -	$mock = $this->mock;
      -	$mock([], $mock->getDefaultArgs());
      -
      -	$name = $this->mock->getDefaultArgs()['name'];
      -
      -	$sep = \DIRECTORY_SEPARATOR;
      -	$output = \file_get_contents(Components::getProjectPaths('blocksDestinationCustom', "{$name}{$sep}{$name}.php"));
      -
      -	expect($output)->toContain(
      -		'Template for the Button Block view.',
      -		'@package EightshiftLibs',
      -	)
      -	->not->toContain(
      -		'@package EightshiftBoilerplate'
      -	);
      -});
      -
      -test('Block CLI documentation is correct', function () {
      -	$mock = $this->mock;
      -	expect($mock->getDoc())->toBeArray();
      -});
      -
      -test('Block CLI command will fail if block doesn\'t exist', function () {
      -	$mock = $this->mock;
      -	$mock([], array_merge(
      -		$mock->getDefaultArgs(),
      -		[
      -			'name' => 'testing'
      -		]
      -	));
      -})->throws(Exception::class, 'You can find all available items on this list:');
      diff --git a/tests/Unit/Blocks/BlockComponentCliTest.php b/tests/Unit/Blocks/BlockComponentCliTest.php
      deleted file mode 100644
      index 1ff752157..000000000
      --- a/tests/Unit/Blocks/BlockComponentCliTest.php
      +++ /dev/null
      @@ -1,44 +0,0 @@
      -mock = new UseComponentCli('boilerplate');
      -});
      -
      -afterEach(function () {
      -	unset($this->mock);
      -});
      -
      -test('Component CLI command will correctly copy the Component class with defaults', function () {
      -	$mock = $this->mock;
      -	$mock([], $this->mock->getDefaultArgs());
      -
      -	$name = $this->mock->getDefaultArgs()['name'];
      -
      -	$sep = \DIRECTORY_SEPARATOR;
      -	$output = \file_get_contents(Components::getProjectPaths('blocksDestinationComponents', "{$name}{$sep}{$name}.php"));
      -
      -	expect($output)->toContain(
      -		'Fake component',
      -	);
      -});
      -
      -test('Component CLI documentation is correct', function () {
      -	$mock = $this->mock;
      -	expect($mock->getDoc())->toBeArray();
      -});
      -
      -test('Component CLI command will fail if Component doesn\'t exist', function () {
      -	$mock = $this->mock;
      -	$mock([], array_merge(
      -		$mock->getDefaultArgs(),
      -		[
      -			'name' => 'testing'
      -		]
      -	));
      -})->throws(Exception::class, 'Requested component with the name');
      diff --git a/tests/Unit/Blocks/BlockVariationCliTest.php b/tests/Unit/Blocks/BlockVariationCliTest.php
      deleted file mode 100644
      index 0b65b4885..000000000
      --- a/tests/Unit/Blocks/BlockVariationCliTest.php
      +++ /dev/null
      @@ -1,73 +0,0 @@
      -mock = new UseVariationCli('boilerplate');
      -});
      -
      -afterEach(function () {
      -	unset($this->mock);
      -});
      -
      -//---------------------------------------------------------------------------------//
      -
      -test('getCommandParentName will return correct value', function () {
      -	expect($this->mock->getCommandParentName())
      -		->toBeString()
      -		->toEqual(CliBlocks::COMMAND_NAME);
      -});
      -
      -//---------------------------------------------------------------------------------//
      -
      -test('getCommandName will return correct value', function () {
      -	expect($this->mock->getCommandName())
      -		->toBeString()
      -		->toEqual('use-variation');
      -});
      -
      -//---------------------------------------------------------------------------------//
      -
      -test('getDefaultArgs will return correct array', function () {
      -	expect($this->mock->getDefaultArgs())
      -		->toBeArray()
      -		->toMatchArray([
      -			'name' => 'card-simple',
      -		]);
      -});
      -
      -//---------------------------------------------------------------------------------//
      -
      -test('getDoc will return correct array', function () {
      -	$docs = $this->mock->getDoc();
      -
      -	expect($docs)
      -		->toBeArray()
      -		->toHaveKeys(['shortdesc', 'synopsis', 'longdesc'])
      -		->and(count($docs['synopsis']))->toEqual(1)
      -		->and($docs['synopsis'][0]['name'])->toEqual('name');
      -});
      -
      -//---------------------------------------------------------------------------------//
      -
      -test('__invoke will correctly copy example variation with default args', function () {
      -	$mock = $this->mock;
      -	$mock([], $mock->getDefaultArgs());
      -
      -	$name = $this->mock->getDefaultArgs()['name'];
      -
      -	$sep = \DIRECTORY_SEPARATOR;
      -	$output = \file_get_contents(Components::getProjectPaths('blocksDestinationVariations', "{$name}{$sep}manifest.json"));
      -
      -	expect($output)
      -		->toContain(
      -			'card',
      -			'card-simple',
      -			'Card Simple',
      -		)
      -		->and(\getenv('ES_CLI_LOG_HAPPENED'))->toContain('Please run');
      -});
      diff --git a/tests/Unit/Blocks/BlockWrapperCliTest.php b/tests/Unit/Blocks/BlockWrapperCliTest.php
      deleted file mode 100644
      index 29249ac99..000000000
      --- a/tests/Unit/Blocks/BlockWrapperCliTest.php
      +++ /dev/null
      @@ -1,34 +0,0 @@
      -mock = new UseWrapperCli('boilerplate');
      -});
      -
      -afterEach(function () {
      -	unset($this->mock);
      -});
      -
      -test('Wrapper CLI command will correctly copy the Wrapper class with defaults', function () {
      -	$mock = $this->mock;
      -	$mock([], []);
      -
      -	$output = \file_get_contents(Components::getProjectPaths('blocksDestinationWrapper', 'wrapper.php'));
      -
      -	expect($output)->toContain('Fake wrapper');
      -});
      -
      -test('Wrapper CLI command will run under custom command name', function () {
      -	$mock = $this->mock;
      -	$result = $mock->getCommandName();
      -
      -	expect($result)->toContain('wrapper');
      -});
      -
      -test('Wrapper CLI documentation is correct', function () {
      -	expect($this->mock->getDoc())->toBeArray();
      -});
      diff --git a/tests/Unit/Blocks/BlocksAssetsCliTest.php b/tests/Unit/Blocks/BlocksAssetsCliTest.php
      deleted file mode 100644
      index ee6dacefa..000000000
      --- a/tests/Unit/Blocks/BlocksAssetsCliTest.php
      +++ /dev/null
      @@ -1,27 +0,0 @@
      -mock = new UseAssetsCli('boilerplate');
      -});
      -
      -afterEach(function () {
      -	unset($this->mock);
      -});
      -
      -test('Assets CLI command will correctly copy the Assets class with defaults', function () {
      -	$mock = $this->mock;
      -	$mock([], []);
      -
      -	$output = \file_get_contents(Components::getProjectPaths('blocksAssetsDestination', 'assets.php'));
      -
      -	expect($output)->toContain('Fake assets');
      -});
      -
      -test('Assets CLI documentation is correct', function () {
      -	expect($this->mock->getDoc())->toBeArray();
      -});
      diff --git a/tests/Unit/Blocks/BlocksCliTest.php b/tests/Unit/Blocks/BlocksCliTest.php
      deleted file mode 100644
      index 09a308ff1..000000000
      --- a/tests/Unit/Blocks/BlocksCliTest.php
      +++ /dev/null
      @@ -1,41 +0,0 @@
      -mock = new BlocksCli('boilerplate');
      -});
      -
      -afterEach(function () {
      -	unset($this->mock);
      -});
      -
      -test('Blocks CLI command will correctly copy the Blocks class with defaults', function () {
      -	$mock = $this->mock;
      -	$mock([], []);
      -
      -	$output = \file_get_contents(Components::getProjectPaths('blocksDestination', "Blocks.php"));
      -
      -	$this->assertStringContainsString('class Blocks extends AbstractBlocks', $output);
      -	$this->assertStringContainsString('@package EightshiftLibs\Blocks', $output);
      -	$this->assertStringContainsString('namespace EightshiftLibs\Blocks', $output);
      -	$this->assertStringNotContainsString('footer.php', $output);
      -});
      -
      -test('Blocks CLI command will correctly copy the Blocks class with set arguments', function () {
      -	$mock = $this->mock;
      -	$mock([], [
      -		'namespace' => 'CoolTheme',
      -	]);
      -
      -	$output = \file_get_contents(Components::getProjectPaths('blocksDestination', "Blocks.php"));
      -
      -	$this->assertStringContainsString('namespace CoolTheme\Blocks;', $output);
      -});
      -
      -test('Blocks CLI documentation is correct', function () {
      -	expect($this->mock->getDoc())->toBeArray();
      -});
      diff --git a/tests/Unit/Blocks/BlocksExampleTest.php b/tests/Unit/Blocks/BlocksExampleTest.php
      deleted file mode 100644
      index 8850c5c73..000000000
      --- a/tests/Unit/Blocks/BlocksExampleTest.php
      +++ /dev/null
      @@ -1,380 +0,0 @@
      -mock = new BlocksExample();
      -});
      -
      -afterEach(function() {
      -	unset($this->mock);
      -});
      -
      -test('Register method will call all register hooks', function () {
      -	$this->mock->register();
      -
      -	expect(has_filter('block_categories_all', 'EightshiftBoilerplate\Blocks\BlocksExample->getCustomCategory()'))->toBe(10);
      -	expect(has_action('init', 'EightshiftBoilerplate\Blocks\BlocksExample->getBlocksDataFullRaw()'))->toBe(10);
      -	expect(has_action('init', 'EightshiftBoilerplate\Blocks\BlocksExample->registerBlocks()'))->toBe(11);
      -	expect(has_action('after_setup_theme', 'EightshiftBoilerplate\Blocks\BlocksExample->addThemeSupport()'))->toBe(25);
      -	expect(has_action('after_setup_theme', 'EightshiftBoilerplate\Blocks\BlocksExample->changeEditorColorPalette()'))->toBe(11);
      -});
      -
      -test('addThemeSupport method will call add_theme_support() function with different arguments', function () {
      -
      -	Functions\when('add_theme_support')->alias(function($arg) {
      -		$envName = strtoupper($arg);
      -		$envName = \str_replace('-', '_', $envName);
      -		putenv("{$envName}=true");
      -	});
      -
      -	$this->mock->addThemeSupport();
      -
      -	expect(\getenv('ALIGN_WIDE'))->toBe('true');
      -});
      -
      -test('Asserts that getAllBlocksList is not influenced by the first parameter', function ($argument) {
      -
      -	$blockContext = mock(WP_Block_Editor_Context::class);
      -	$blockContext->post = null;
      -
      -	buildTestBlocks();
      -
      -	Components::setConfigFlags();
      -
      -	$blocks = $this->mock->getAllBlocksList($argument, $blockContext);
      -
      -	expect($blocks)
      -		->toBeArray()
      -		->not->toContain('core/paragraph')
      -		->not->toContain('test')
      -		->toContain('eightshift-boilerplate/button', 'eightshift-boilerplate/heading', 'core/block', 'core/template');
      -
      -})->with('getAllAllowedBlocksListAllTypesArguments');
      -
      -test('Asserts that getAllAllowedBlocksList will return true if post type is eightshift-forms for WP 5.8.', function () {
      -
      -	$blockContext = mock('WP_Block_Editor_Context');
      -	$blockContext->post = mock('WP_Post');
      -	$blockContext->post->post_type = 'eightshift-forms';
      -
      -	$blocks = $this->mock->getAllAllowedBlocksList([], $blockContext);
      -
      -	expect($blocks)
      -		->toBeTrue();
      -});
      -
      -test('Asserts that getAllAllowedBlocksList first argument is bool and return first argument for WP 5.8.', function () {
      -
      -	$blockContext = mock('WP_Block_Editor_Context');
      -	$blockContext->post = mock('WP_Post');
      -	$blockContext->post->post_type = 'post';
      -
      -	$blocks = $this->mock->getAllAllowedBlocksList(true, $blockContext);
      -
      -	expect($blocks)->toBeTrue();
      -
      -	$blocks = $this->mock->getAllAllowedBlocksList(false, $blockContext);
      -
      -	expect($blocks)->toBeFalse();
      -});
      -
      -test('Asserts that getAllAllowedBlocksList first argument is not bool and returns list with appended project blocks to the first argument', function () {
      -
      -	$blockContext = mock('WP_Block_Editor_Context');
      -	$blockContext->post = mock('WP_Post');
      -	$blockContext->post->post_type = 'post';
      -
      -	buildTestBlocks();
      -
      -	$blocks = $this->mock->getAllAllowedBlocksList(['test'], $blockContext);
      -
      -	expect($blocks)
      -		->toBeArray()
      -		->not->toContain('core/paragraph')
      -		->toContain('test', 'eightshift-boilerplate/button', 'core/block', 'core/template');
      -});
      -
      -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;
      -
      -	buildTestBlocks();
      -
      -	Components::setConfigFlags();
      -
      -	$blocks = $this->mock->getAllAllowedBlocksList(['test'], $blockContext);
      -
      -	expect($blocks)
      -		->toBeArray()
      -		->toContain('eightshift-boilerplate/button', 'eightshift-boilerplate/heading', 'core/block', 'core/template', 'test');
      -});
      -
      -test('Asserts that getAllAllowedBlocksList will return only projects blocks for WP 5.8.', function () {
      -	$blockContext = mock(WP_Block_Editor_Context::class);
      -	$blockContext->post = null;
      -
      -	buildTestBlocks();
      -
      -	Components::setConfigFlags();
      -
      -	$blocks = $this->mock->getAllAllowedBlocksList([], $blockContext);
      -
      -	expect($blocks)
      -		->toBeArray()
      -		->toContain('eightshift-boilerplate/button', 'eightshift-boilerplate/heading', 'core/block', 'core/template');
      -});
      -
      -test('Asserts that render component will load view template.', function () {
      -
      -	$blockManifest = [
      -		'blockName' => 'button',
      -	];
      -
      -	buildTestBlocks();
      -
      -	$block = $this->mock->render($blockManifest, '');
      -
      -	expect($block)
      -		->toBeString()
      -		->toContain('Wrapper!')
      -		->not->toContain('fake');
      -});
      -
      -test('Asserts that render will throw error if block view is missing.', function () {
      -
      -	$blockManifest = [
      -		'blockName' => 'fake',
      -	];
      -
      -	buildTestBlocks();
      -
      -	$this->mock->render($blockManifest, '');
      -})->throws(InvalidBlock::class);
      -
      -test('Asserts that render will throw error if wrapper view is missing.', function () {
      -
      -	$blockManifest = [
      -		'blockName' => 'fake',
      -	];
      -
      -	buildTestBlocks();
      -
      -	$this->mock->render($blockManifest, '');
      -
      -})->throws(InvalidBlock::class);
      -
      -test('Asserts that renderWrapperView will return a valid file.', function () {
      -
      -	buildTestBlocks();
      -
      -	$wrapperFile = Components::getProjectPaths('blocksDestinationWrapper', 'wrapper.php');
      -
      -	\ob_start();
      -	$this->mock->renderWrapperView($wrapperFile, []);
      -	$content = \ob_get_clean();
      -
      -	expect(\trim($content))
      -		->toBeString()
      -		->toBe('
      Wrapper!
      '); -}); - -test('Asserts that renderWrapperView will throw error if path is not valid.', function () { - $this->mock->renderWrapperView('fake path', []); -})->throws(InvalidBlock::class); - -test('Asserts that getCustomCategory will return categories array.', function () { - - $blockContext = mock('WP_Block_Editor_Context'); - $category = $this->mock->getCustomCategory([], $blockContext); - - expect($category)->toBeArray(); - - expect($category[0]) - ->toBeArray() - ->toContain('eightshift'); -}); - -test('Asserts that getCustomCategory will throw error if first argument is not array.', function () { - - $blockContext = mock('WP_Block_Editor_Context'); - $this->mock->getCustomCategory('', $blockContext); - -})->throws(\TypeError::class); - -test('changeEditorColorPalette method will call add_theme_support() function with if colors exist.', function () { - - Functions\when('add_theme_support')->alias(function($arg) { - $envName = strtoupper($arg); - $envName = \str_replace('-', '_', $envName); - putenv("{$envName}=true"); - }); - - buildTestBlocks(); - - $this->mock->changeEditorColorPalette(); - - expect(\getenv('EDITOR_COLOR_PALETTE'))->toBe('true'); -}); - -test('registerBlocks method will register all blocks.', function () { - - putenv('BLOCK_TYPE=false'); - - Functions\when('register_block_type')->alias(function(string $name, array $args = []) { - putenv('BLOCK_TYPE=true'); - }); - - buildTestBlocks(); - - $this->mock->registerBlocks(); - - expect(\getenv('BLOCK_TYPE'))->toBe('true'); -}); - -test('filterBlocksContent method will return an array.', function () { - - $parsedBlock = [ - 'blockName' => 'eightshift-boilerplate/jumbotron', - 'attrs' => - [ - 'jumbotronHeadingContent' => 'Some text goes here', - 'jumbotronImageUrl' => 'test.jpeg', - ], - 'innerBlocks' => - [ - 0 => - [ - 'blockName' => 'eightshift-boilerplate/description-link', - 'attrs' => - [ - 'wrapperDisable' => true, - 'descriptionLinkDescriptionLinkIntroContent' => 'Test', - 'descriptionLinkDescriptionLinkIntroSize' => 'regular', - 'descriptionLinkDescriptionLinkParagraphContent' => 'Test', - 'descriptionLinkDescriptionLinkParagraphSize' => 'tiny', - 'descriptionLinkDescriptionLinkImageUrl' => 'test.svg', - 'descriptionLinkDescriptionLinkImageAlt' => 'Check alt text', - 'descriptionLinkDescriptionLinkImageFull' => true, - 'descriptionLinkDescriptionLinkUrl' => 'https://example.com', - 'descriptionLinkDescriptionLinkIsClean' => true, - ], - 'innerBlocks' => - [], - 'innerHTML' => '', - 'innerContent' => - [], - ], - 1 => - [ - 'blockName' => 'eightshift-boilerplate/description-link', - 'attrs' => - [ - 'wrapperDisable' => true, - 'descriptionLinkDescriptionLinkIntroContent' => 'Test', - 'descriptionLinkDescriptionLinkIntroSize' => 'regular', - 'descriptionLinkDescriptionLinkParagraphContent' => 'Content', - 'descriptionLinkDescriptionLinkParagraphSize' => 'tiny', - 'descriptionLinkDescriptionLinkImageUrl' => 'test.svg', - 'descriptionLinkDescriptionLinkImageFull' => true, - 'descriptionLinkDescriptionLinkIsClean' => true, - ], - 'innerBlocks' => - [], - 'innerHTML' => '', - 'innerContent' => - [], - ], - ], - 'innerHTML' => '', - 'innerContent' => - [ - 0 => '', - 1 => null, - 2 => '', - 3 => null, - 4 => '', - 5 => null, - 6 => '', - 7 => null, - 8 => '', - ], - ]; - - $filteredBlockContent = $this->mock->filterBlocksContent($parsedBlock, []); - - expect($filteredBlockContent)->toBeArray(); -}); - -test('filterBlocksContent method will not filter out the paragraph with content.', function () { - - $parsedBlock = [ - 'blockName' => 'eightshift-boilerplate/paragraph', - 'attrs' => - [ - 'paragraphParagraphContent' => 'Some text goes here', - ], - 'innerBlocks' => - '', - 'innerHTML' => '', - 'innerContent' => - [ - 0 => '', - ], - ]; - - $filteredBlockContent = $this->mock->filterBlocksContent($parsedBlock, []); - - expect($filteredBlockContent) - ->toBeArray() - ->toHaveKey('blockName') - ->toHaveKey('attrs'); - - expect($filteredBlockContent['attrs']) - ->toBeArray() - ->toHaveKey('paragraphParagraphContent'); -}); - -test('filterBlocksContent method will filter out the paragraph without content.', function () { - - $parsedBlock = [ - 'blockName' => 'eightshift-boilerplate/paragraph', - 'attrs' => [ - 'paragraphParagraphContent' => '', - 'wrapperDisable' => true, - 'paragraphUse' => false, - ], - 'innerBlocks' => '', - 'innerHTML' => '', - 'innerContent' => [ - 0 => '', - ], - ]; - - // Set namespace data. - buildTestBlocks(); - - $filteredBlockContent = $this->mock->filterBlocksContent($parsedBlock, []); - - expect($filteredBlockContent) - ->toBeArray() - ->toHaveKey('blockName') - ->toHaveKey('attrs'); - - expect($filteredBlockContent['attrs']) - ->toBeArray() - ->toHaveKey('wrapperDisable') - ->toHaveKey('paragraphUse'); - - expect($filteredBlockContent['attrs']['wrapperDisable'])->toBeTrue(); - expect($filteredBlockContent['attrs']['paragraphUse'])->toBeFalse(); -}); diff --git a/tests/Unit/Blocks/BlocksGlobalAssetsCliTest.php b/tests/Unit/Blocks/BlocksGlobalAssetsCliTest.php deleted file mode 100644 index 5201622f2..000000000 --- a/tests/Unit/Blocks/BlocksGlobalAssetsCliTest.php +++ /dev/null @@ -1,27 +0,0 @@ -mock = new UseGlobalAssetsCli('boilerplate'); -}); - -afterEach(function () { - unset($this->mock); -}); - -test('Assets CLI command will correctly copy the Global Assets class with defaults', function () { - $mock = $this->mock; - $mock([], []); - - $output = \file_get_contents(Components::getProjectPaths('blocksGlobalAssetsDestination', 'assets.php')); - - expect($output)->toContain('Global Assets example file.'); -}); - -test('Assets CLI documentation is correct', function () { - expect($this->mock->getDoc())->toBeArray(); -}); diff --git a/tests/Unit/Blocks/BlocksManifestCliTest.php b/tests/Unit/Blocks/BlocksManifestCliTest.php deleted file mode 100644 index f07c3e1c0..000000000 --- a/tests/Unit/Blocks/BlocksManifestCliTest.php +++ /dev/null @@ -1,27 +0,0 @@ -mock = new UseManifestCli('boilerplate'); -}); - -afterEach(function () { - unset($this->mock); -}); - -test('Manifest CLI command will correctly copy the manifest.json file with defaults', function () { - $mock = $this->mock; - $mock([], []); - - $output = \file_get_contents(Components::getProjectPaths('blocksSource', 'manifest.json')); - - expect($output)->toContain('namespace'); -}); - -test('Manifest CLI documentation is correct', function () { - expect($this->mock->getDoc())->toBeArray(); -}); diff --git a/tests/Unit/Cli/AbstractCliTest.php b/tests/Unit/Cli/AbstractCliTest.php deleted file mode 100644 index 3894949ec..000000000 --- a/tests/Unit/Cli/AbstractCliTest.php +++ /dev/null @@ -1,177 +0,0 @@ -register(); - - $this->assertSame(10, has_action('cli_init', 'Tests\Unit\Cli\AbstractTest->registerCommand()')); -}); - - -test('Global CLI synopsis works', function() { - $abstractMock = new AbstractTest('test'); - - $synopsis = $abstractMock->getGlobalSynopsis(); - - $this->assertIsArray($synopsis); - $this->assertArrayHasKey('synopsis', $synopsis); - - foreach ($synopsis['synopsis'] as $descriptions) { - $this->assertArrayHasKey('type', $descriptions); - $this->assertArrayHasKey('name', $descriptions); - $this->assertArrayHasKey('description', $descriptions); - $this->assertArrayHasKey('optional', $descriptions); - } -}); - - -test('Prepare command docs fails if shortdesc doesn\'t exist', function() { - $abstractMock = new AbstractTest('test'); - - $abstractMock->prepareCommandDocs([], []); -})->throws(RuntimeException::class, 'CLI Short description is missing.'); - - -test('Prepare command docs returns correct doc', function() { - $abstractMock = new AbstractTest('test'); - - $docs = [ - 'shortdesc' => 'Some description', - 'synopsis' => [ - [ - 'type' => 'assoc', - 'name' => 'random', - 'description' => 'Random description.', - 'optional' => true, - 'default' => 'random', - ], - ], - ]; - - $preparedDocs = $abstractMock->prepareCommandDocs($docs, $abstractMock->getGlobalSynopsis()); - - $this->assertIsArray($preparedDocs); - $this->assertArrayHasKey('shortdesc', $preparedDocs); - $this->assertArrayHasKey('synopsis', $preparedDocs); - - $addedSynopsis = \array_filter($preparedDocs['synopsis'], function($descArr) { - return $descArr['name'] === 'random'; - }); - // Check if the synopsis was added to the global one. - $this->assertNotEmpty($addedSynopsis); -}); - - -test('Manually preparing arguments works', function() { - $abstractMock = new AbstractTest('test'); - - $output = $abstractMock->prepareArgsManual([ - 'color' => '#EFEFEF', - ]); - - $this->assertSame('--color=\'#EFEFEF\' ', $output); - - $outputEmpty = $abstractMock->prepareArgsManual([]); - - $this->assertEmpty($outputEmpty, 'Argument output should be empty'); -}); - - -test('Block full file list helper works', function() { - $abstractMock = new AbstractTest('test'); - - $output = $abstractMock->getFullBlocksFiles('button'); - - $this->assertIsArray($output); - - $this->assertTrue(\array_key_exists('button.php', \array_flip($output)), 'button.php is missing.'); - $this->assertTrue(\array_key_exists('button-block.js', \array_flip($output)), 'button-block.js is missing.'); - $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('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.'); -}); - -test('Preparing slug works', function($slugs) { - $abstractMock = new AbstractTest('test'); - - $output = $abstractMock->prepareSlug($slugs); - - $this->assertIsString($output); - $this->assertFalse(\strpos($output, '_'), 'Prepared string contains _'); - $this->assertFalse(\strpos($output, ' '), 'Prepared string contains empty space'); -})->with('inputSlugs'); - - -test('Register command fails if class doesn\'t exist', function() { - $abstractMock = new AbstractTest('nonexistent'); - - $abstractMock->registerCommand(); -})->throws(RuntimeException::class); - - -test('Getting vendor prefix works correctly if set', function() { - $abstractMock = new AbstractTest('nonexistent'); - - $prefix = $abstractMock->getVendorPrefix(['vendor_prefix' => 'test']); - - $this->assertIsString($prefix); - $this->assertSame('test', $prefix); -}); - - -test('Replacing use in frontend libs views works', function() { - $abstractMock = new AbstractTest('test'); - - $abstractMock->renameUseFrontendLibs([]); - - $reflection = new ReflectionClass($abstractMock); - $property = $reflection->getProperty('fileContents'); - $property->setAccessible(true); - $contents = $property->getValue($abstractMock); - - $this->assertSame('use EightshiftLibs\Service; use EightshiftLibs\Test;', $contents); -}); diff --git a/tests/Unit/Cli/CliHelpersTest.php b/tests/Unit/Cli/CliHelpersTest.php deleted file mode 100644 index af9d878b1..000000000 --- a/tests/Unit/Cli/CliHelpersTest.php +++ /dev/null @@ -1,13 +0,0 @@ -expectExceptionMessage('Some random cli error happened'); diff --git a/tests/Unit/Cli/CliTest.php b/tests/Unit/Cli/CliTest.php deleted file mode 100644 index 0fac57cc3..000000000 --- a/tests/Unit/Cli/CliTest.php +++ /dev/null @@ -1,38 +0,0 @@ -cli = new Cli(); -}); - -afterEach(function () { - unset($this->cli); -}); - -test('Cli getCommandsClasses return correct class list', function () { - $publicClasses = $this->cli->getCommandsClasses(); - - expect($publicClasses) - ->toBeArray() - ->not->toHaveKey(CliReset::class) - ->not->toHaveKey(CliRunAll::class) - ->not->toHaveKey(CliShowAll::class) - ->and(\count($publicClasses)) - ->toBeInt() - ->toBe(53); - // Public classes count. -}); - -test('Running load command works', function() { - $this->cli->load('boilerplate'); - - // We could add all 36 of the public CLI classes, but I don't think that makes sense. - $this->assertSame(10, has_action('cli_init', 'EightshiftLibs\Menu\MenuCli->registerCommand()')); -}); diff --git a/tests/Unit/Columns/Media/MediaColumnsTest.php b/tests/Unit/Columns/Media/MediaColumnsTest.php deleted file mode 100644 index dd862e057..000000000 --- a/tests/Unit/Columns/Media/MediaColumnsTest.php +++ /dev/null @@ -1,36 +0,0 @@ -register(); - - $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_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_upload_sortable_columns', 'Tests\Unit\Columns\MediaColumnMock->sortAddedColumns()'), 'manage_upload_sortable_columns filter priority was not correct'); -}); diff --git a/tests/Unit/Columns/Media/WebPMediaColumnCliTest.php b/tests/Unit/Columns/Media/WebPMediaColumnCliTest.php deleted file mode 100644 index b50a2d466..000000000 --- a/tests/Unit/Columns/Media/WebPMediaColumnCliTest.php +++ /dev/null @@ -1,42 +0,0 @@ -webPMediaColumnCliMock = new WebPMediaColumnCli('boilerplate'); -}); - -afterEach(function () { - unset($this->webPMediaColumnCliMock); -}); - -test('Check if CLI command name is correct.', function () { - $mock = $this->webPMediaColumnCliMock; - - $mock = $mock->getCommandName(); - - expect($mock) - ->toBeString() - ->toEqual('webp-media-column'); -}); - -test('Check if CLI command documentation is correct.', function () { - expect($this->webPMediaColumnCliMock->getDoc())->toBeArray(); -}); - -test('Check if CLI command will correctly copy the WebPMediaColumns class with defaults.', function () { - $mock = $this->webPMediaColumnCliMock; - - $mock([], $mock->getDefaultArgs()); - - // Check the output dir if the generated method is correctly generated. - $output = \file_get_contents(Components::getProjectPaths('srcDestination', 'Columns/Media/WebPMediaColumn.php')); - - expect($output) - ->not->toBeEmpty() - ->toContain('WebPMediaColumn extends AbstractMediaColumns') - ->toContain("COLUMN_KEY = 'webp'"); -}); diff --git a/tests/Unit/Columns/Media/WebPMediaColumnExampleTest.php b/tests/Unit/Columns/Media/WebPMediaColumnExampleTest.php deleted file mode 100644 index 6ce786300..000000000 --- a/tests/Unit/Columns/Media/WebPMediaColumnExampleTest.php +++ /dev/null @@ -1,61 +0,0 @@ -webPMediaColumnExampleMock = new WebPMediaColumnExample(); - - $this->webPMediaColumnExampleMockColumns = [ - 'image' => 'test.jpg', - 'new' => 'newNew', - ]; -}); - -afterEach(function () { - unset($this->webPMediaColumnExampleMock, $this->webPMediaColumnExampleMockColumns); -}); - -test('Check if addColumnName function will return columns with new column name.', function () { - $mock = $this->webPMediaColumnExampleMock; - $columns = $this->webPMediaColumnExampleMockColumns; - - $mock = $mock->addColumnName($columns); - - expect($mock) - ->toMatchArray( - array_merge( - $columns, - [ - WebPMediaColumnExample::COLUMN_KEY => 'WebP', - ] - ) - ); -}); - -test('Check if renderColumnContent function will return icon in the new column name.', function () { - $mock = $this->webPMediaColumnExampleMock; - - $mock = $mock->renderColumnContent(WebPMediaColumnExample::COLUMN_KEY, 1); - - expect($mock) - ->toBeString(''); -}); - -test('Check if sortAddedColumns function will return columns with new column name.', function () { - $mock = $this->webPMediaColumnExampleMock; - $columns = $this->webPMediaColumnExampleMockColumns; - - $mock = $mock->sortAddedColumns($columns); - - expect($mock) - ->toMatchArray( - array_merge( - $columns, - [ - WebPMediaColumnExample::COLUMN_KEY => 'WebP', - ] - ) - ); -}); diff --git a/tests/Unit/Columns/PostTypeColumnsTest.php b/tests/Unit/Columns/PostTypeColumnsTest.php deleted file mode 100644 index da7da359c..000000000 --- a/tests/Unit/Columns/PostTypeColumnsTest.php +++ /dev/null @@ -1,35 +0,0 @@ -register(); - $postType = $mockPostTypeColumn::POST_TYPE; - - $this->assertNotFalse(has_filter("manage_{$postType}_posts_columns", 'Tests\Unit\Columns\PostTypeColumnMock->addColumnName()'), 'Filter wasn\'t registered'); - $this->assertNotFalse(has_action("manage_{$postType}_posts_custom_column", 'Tests\Unit\Columns\PostTypeColumnMock->renderColumnContent()'), 'Action wasn\'t registered'); - $this->assertSame(10, has_filter("manage_{$postType}_posts_columns", 'Tests\Unit\Columns\PostTypeColumnMock->addColumnName()'), 'Filter priority was not correct'); - $this->assertSame(10, has_action("manage_{$postType}_posts_custom_column", 'Tests\Unit\Columns\PostTypeColumnMock->renderColumnContent()'), 'Action priority was not correct'); -}); diff --git a/tests/Unit/Columns/TaxonomyColumnsTest.php b/tests/Unit/Columns/TaxonomyColumnsTest.php deleted file mode 100644 index c261575b8..000000000 --- a/tests/Unit/Columns/TaxonomyColumnsTest.php +++ /dev/null @@ -1,36 +0,0 @@ -register(); - $taxonomy = $mockTaxonomyColumn::TAXONOMY; - - $this->assertNotFalse(has_filter("manage_edit-{$taxonomy}_columns", 'Tests\Unit\Columns\TaxonomyColumnMock->addColumnName()'), 'Manage edit filter wasn\'t registered'); - $this->assertNotFalse(has_filter("manage_{$taxonomy}_custom_column", 'Tests\Unit\Columns\TaxonomyColumnMock->renderColumnContent()'), 'Manage filter wasn\'t registered'); - $this->assertSame(10, has_filter("manage_edit-{$taxonomy}_columns", 'Tests\Unit\Columns\TaxonomyColumnMock->addColumnName()'), 'Manage edit filter priority was not correct'); - $this->assertSame(10, has_filter("manage_{$taxonomy}_custom_column", 'Tests\Unit\Columns\TaxonomyColumnMock->renderColumnContent()'), 'Manage filter priority was not correct'); -}); diff --git a/tests/Unit/Columns/UsersColumnsTest.php b/tests/Unit/Columns/UsersColumnsTest.php deleted file mode 100644 index 8c1d0f29b..000000000 --- a/tests/Unit/Columns/UsersColumnsTest.php +++ /dev/null @@ -1,36 +0,0 @@ -register(); - - $this->assertNotFalse(has_filter('manage_users_columns', 'Tests\Unit\Columns\UserColumnMock->addColumnName()'), 'manage_users_columns filter wasn\'t registered'); - $this->assertNotFalse(has_filter('manage_users_custom_column', 'Tests\Unit\Columns\UserColumnMock->renderColumnContent()'), 'manage_users_custom_column filter wasn\'t registered'); - $this->assertNotFalse(has_filter('manage_users_sortable_columns', 'Tests\Unit\Columns\UserColumnMock->sortAddedColumns()'), 'manage_users_sortable_columns filter wasn\'t registered'); - $this->assertSame(10, has_filter('manage_users_columns', 'Tests\Unit\Columns\UserColumnMock->addColumnName()'), 'manage_users_columns filter priority was not correct'); - $this->assertSame(10, has_filter('manage_users_custom_column', 'Tests\Unit\Columns\UserColumnMock->renderColumnContent()'), 'manage_users_custom_column filter priority was not correct'); - $this->assertSame(10, has_filter('manage_users_sortable_columns', 'Tests\Unit\Columns\UserColumnMock->sortAddedColumns()'), 'manage_users_sortable_columns filter priority was not correct'); -}); diff --git a/tests/Unit/Config/ConfigCliTest.php b/tests/Unit/Config/ConfigCliTest.php deleted file mode 100644 index 7cd1f5b10..000000000 --- a/tests/Unit/Config/ConfigCliTest.php +++ /dev/null @@ -1,33 +0,0 @@ -mock = new ConfigCli('boilerplate'); -}); - -afterEach(function () { - unset($this->mock); -}); - -test('Custom acf meta CLI command will correctly copy the Config class with defaults', function () { - $config = $this->mock; - $config([], $config->getDefaultArgs()); - - // Check the output dir if the generated method is correctly generated. - $generatedConfig = \file_get_contents(Components::getProjectPaths('srcDestination', 'Config/Config.php')); - - $this->assertStringContainsString('class Config extends AbstractConfigData', $generatedConfig); - $this->assertStringContainsString('getProjectName', $generatedConfig); - $this->assertStringContainsString('getProjectVersion', $generatedConfig); - $this->assertStringContainsString('getProjectRoutesNamespace', $generatedConfig); - $this->assertStringContainsString('getProjectRoutesVersion', $generatedConfig); - $this->assertStringNotContainsString('someRandomMethod', $generatedConfig); -}); - -test('Custom acf meta CLI documentation is correct', function () { - expect($this->mock->getDoc())->toBeArray(); -}); diff --git a/tests/Unit/Config/ConfigExampleTest.php b/tests/Unit/Config/ConfigExampleTest.php deleted file mode 100644 index 12029f370..000000000 --- a/tests/Unit/Config/ConfigExampleTest.php +++ /dev/null @@ -1,49 +0,0 @@ -mock = new ConfigExample(); -}); - -afterEach(function () { - unset($this->mock); -}); - -test('Is project name defined and a string', function () { - $this->assertNotEmpty($this->mock::getProjectName()); - $this->assertIsString(\gettype($this->mock::getProjectName())); -}); - -test('Is project version defined and a string', function () { - $this->assertNotEmpty($this->mock::getProjectVersion()); - $this->assertIsString(\gettype($this->mock::getProjectVersion())); -}); - -test('Is project REST namespace defined, a string and same as project name', function () { - $this->assertNotEmpty($this->mock::getProjectRoutesNamespace()); - $this->assertIsString(\gettype($this->mock::getProjectRoutesNamespace())); - $this->assertSame($this->mock::getProjectName(), $this->mock::getProjectRoutesNamespace()); -}); - -test('Is project REST route version defined and a string', function () { - $this->assertNotEmpty($this->mock::getProjectRoutesVersion()); - $this->assertIsString(\gettype($this->mock::getProjectRoutesVersion())); - $this->assertStringContainsString('v', $this->mock::getProjectRoutesVersion()); -}); - -test('Is project path defined and readable', function () { - $this->assertNotEmpty($this->mock::getProjectPath()); - $this->assertDirectoryIsReadable($this->mock::getProjectPath()); -}); - -test('Is custom project path defined and readable', function () { - $this->assertNotEmpty($this->mock::getProjectPath()); - $this->assertDirectoryIsReadable($this->mock::getProjectPath('tests')); -}); - -test('If non-existent path throws exception', function () { - $this->mock::getProjectPath('bla/'); -})->throws(\EightshiftLibs\Exception\InvalidPath::class); diff --git a/tests/Unit/ConfigProject/ConfigProjectCliTest.php b/tests/Unit/ConfigProject/ConfigProjectCliTest.php deleted file mode 100644 index 47fc98d5c..000000000 --- a/tests/Unit/ConfigProject/ConfigProjectCliTest.php +++ /dev/null @@ -1,70 +0,0 @@ -mock = new ConfigProjectCli('boilerplate'); -}); - -afterEach(function () { - unset($this->mock); -}); - -//---------------------------------------------------------------------------------// - -test('getCommandParentName will return correct value', function () { - expect($this->mock->getCommandParentName()) - ->toBeString() - ->toEqual(CliCreate::COMMAND_NAME); -}); - -//---------------------------------------------------------------------------------// - -test('getCommandName will return correct value', function () { - expect($this->mock->getCommandName()) - ->toBeString() - ->toEqual('config-project'); -}); - -//---------------------------------------------------------------------------------// - -test('getDefaultArgs will return correct array', function () { - expect($this->mock->getDefaultArgs()) - ->toBeArray() - ->toHaveKeys(['path']); -}); - -//---------------------------------------------------------------------------------// - -test('getDoc will return correct array', function () { - $docs = $this->mock->getDoc(); - - expect($docs) - ->toBeArray() - ->toHaveKeys(['shortdesc', 'synopsis', 'longdesc']) - ->and(count($docs['synopsis']))->toEqual(1) - ->and($docs['synopsis'][0]['name'])->toEqual('path'); -}); - -//---------------------------------------------------------------------------------// - -test('__invoke will will correctly copy example class with default args', function () { - $mock = $this->mock; - $mock([], [ - 'path' => Components::getProjectPaths('cliOutput'), - ]); - - $output = \file_get_contents(Components::getProjectPaths('cliOutput', "wp-config-project.php")); - - expect($output) - ->toContain( - 'WP_ENVIRONMENT_TYPE', - 'WP_POST_REVISIONS', - 'WP_DEBUG_DISPLAY', - ) - ->and(\getenv('ES_CLI_LOG_HAPPENED'))->toContain('Sets up WordPress vars and included files'); -}); diff --git a/tests/Unit/CustomMeta/CustomMetaCliTest.php b/tests/Unit/CustomMeta/CustomMetaCliTest.php deleted file mode 100644 index 8acc5259f..000000000 --- a/tests/Unit/CustomMeta/CustomMetaCliTest.php +++ /dev/null @@ -1,30 +0,0 @@ -mock = new AcfMetaCli('boilerplate'); -}); - -afterEach(function () { - unset($this->mock); -}); - -test('Custom acf meta CLI command will correctly copy the ACF meta class with defaults', function () { - $meta = $this->mock; - $meta([], $meta->getDefaultArgs()); - - // Check the output dir if the generated method is correctly generated. - $generatedMeta = \file_get_contents(Components::getProjectPaths('srcDestination', 'CustomMeta/TitleAcfMeta.php')); - - $this->assertStringContainsString('class TitleAcfMeta extends AbstractAcfMeta', $generatedMeta); - $this->assertStringContainsString('acf_add_local_field_group', $generatedMeta); -}); - - -test('Custom acf meta CLI documentation is correct', function () { - expect($this->mock->getDoc())->toBeArray(); -}); diff --git a/tests/Unit/CustomMeta/CustomMetaExampleTest.php b/tests/Unit/CustomMeta/CustomMetaExampleTest.php deleted file mode 100644 index ff57bfc2d..000000000 --- a/tests/Unit/CustomMeta/CustomMetaExampleTest.php +++ /dev/null @@ -1,29 +0,0 @@ -example = new AcfMetaExample(); -}); - -afterEach(function () { - unset($this->example); -}); - -test('Register method will bail out if ACF is not registered/activated', function () { - $this->assertNull($this->example->register()); -}); - - -test('Register method will call acf init hook', function () { - Functions\when('is_admin')->justReturn(true); - - $this->getMockBuilder(\ACF::class)->getMock(); - - $this->example->register(); - - $this->assertSame(10, has_action('acf/init', 'EightshiftBoilerplate\CustomMeta\AcfMetaExample->fields()')); -}); diff --git a/tests/Unit/CustomPostType/CustomPostTypeCliTest.php b/tests/Unit/CustomPostType/CustomPostTypeCliTest.php deleted file mode 100644 index 5d06db9e9..000000000 --- a/tests/Unit/CustomPostType/CustomPostTypeCliTest.php +++ /dev/null @@ -1,143 +0,0 @@ -mock = new PostTypeCli('boilerplate'); -}); - -afterEach(function () { - unset($this->mock); -}); - -//---------------------------------------------------------------------------------// - -test('getCommandParentName will return correct value', function () { - expect($this->mock->getCommandParentName()) - ->toBeString() - ->toEqual(CliCreate::COMMAND_NAME); -}); - -//---------------------------------------------------------------------------------// - -test('getCommandName will return correct value', function () { - expect($this->mock->getCommandName()) - ->toBeString() - ->toEqual('post-type'); -}); - -//---------------------------------------------------------------------------------// - -test('getDefaultArgs will return correct array', function () { - expect($this->mock->getDefaultArgs()) - ->toBeArray() - ->toMatchArray([ - 'label' => 'Product', - 'plural_label' => 'Products', - 'slug' => 'product', - 'rewrite_url' => 'product', - 'rest_endpoint_slug' => 'products', - 'capability' => 'post', - 'menu_position' => 20, - 'menu_icon' => 'dashicons-admin-settings', - ]); -}); - -//---------------------------------------------------------------------------------// - -test('getDoc will return correct array', function () { - $docs = $this->mock->getDoc(); - - expect($docs) - ->toBeArray() - ->toHaveKeys(['shortdesc', 'synopsis', 'longdesc']) - ->and(count($docs['synopsis']))->toEqual(8) - ->and($docs['synopsis'][0]['name'])->toEqual('label') - ->and($docs['synopsis'][1]['name'])->toEqual('plural_label') - ->and($docs['synopsis'][2]['name'])->toEqual('slug') - ->and($docs['synopsis'][3]['name'])->toEqual('rewrite_url') - ->and($docs['synopsis'][4]['name'])->toEqual('rest_endpoint_slug') - ->and($docs['synopsis'][5]['name'])->toEqual('capability') - ->and($docs['synopsis'][6]['name'])->toEqual('menu_position') - ->and($docs['synopsis'][7]['name'])->toEqual('menu_icon'); -}); - -//---------------------------------------------------------------------------------// - -test('__invoke will will correctly copy example class with default args', function () { - $mock = $this->mock; - $mock([], $this->mock->getDefaultArgs()); - - $sep = \DIRECTORY_SEPARATOR; - - $output = file_get_contents(Components::getProjectPaths('srcDestination', "CustomPostType{$sep}ProductPostType.php")); - - expect($output) - ->toContain( - 'class ProductPostType', - 'Product', - 'Products', - 'product', - 'product', - 'products', - 'post', - '20', - 'dashicons-admin-settings', - ) - ->not->toContain( - 'class PostTypeExample', - '%label%', - '%plural_label%', - '%slug%', - '%rewrite_url%', - '%rest_endpoint_slug%', - '%capability%', - '%menu_position%', - '%menu_icon%', - ); -}); - -test('__invoke will will correctly copy example class with custom args', function () { - $mock = $this->mock; - $mock([], [ - 'label' => 'Test', - 'plural_label' => 'Tests', - 'slug' => 'test', - 'rewrite_url' => 'test', - 'rest_endpoint_slug' => 'tests', - 'capability' => 'product', - 'menu_position' => 40, - 'menu_icon' => 'admin-panel', - ]); - - $sep = \DIRECTORY_SEPARATOR; - $output = file_get_contents(Components::getProjectPaths('srcDestination', "CustomPostType{$sep}TestPostType.php")); - - expect($output) - ->toContain( - 'class TestPostType', - 'Test', - 'Tests', - 'test', - 'test', - 'tests', - 'product', - '40', - 'admin-panel', - ) - ->not->toContain( - 'class PostTypeExample', - '%label%', - '%plural_label%', - '%slug%', - '%rewrite_url%', - '%rest_endpoint_slug%', - '%capability%', - '%menu_position%', - '%menu_icon%', - ); -}); diff --git a/tests/Unit/CustomPostType/CustomPostTypeExampleTest.php b/tests/Unit/CustomPostType/CustomPostTypeExampleTest.php deleted file mode 100644 index 4559d1bf7..000000000 --- a/tests/Unit/CustomPostType/CustomPostTypeExampleTest.php +++ /dev/null @@ -1,41 +0,0 @@ -example = new PostTypeExample(); -}); - -afterEach(function () { - unset($this->example); -}); - -test('Register method will call init hook', function () { - $this->example->register(); - - $this->assertSame(10, has_action('init', 'EightshiftBoilerplate\CustomPostType\PostTypeExample->postTypeRegisterCallback()')); -}); - - -/** - * This is a tricky one. Because it should be an integration test: - * testing if the CPT was actually registered when the action runs. - * - * But we can kinda test this. Since the postTypeRegisterCallback doesn't have a return (void), - * we can try to mock the register_post_type to introduce a temporary side-affect. Like creating a file, or setting an - * environment variable on the fly. That way, when we actually call the method, we know that it will be called. - */ -test('Register post type method will be called', function() { - $action = 'post_type_registered'; - Functions\when('register_post_type')->justReturn(putenv("SIDEAFFECT={$action}")); - - $this->example->postTypeRegisterCallback(); - - $this->assertSame(\getenv('SIDEAFFECT'), $action); - - // Cleanup. - putenv('SIDEAFFECT='); -}); diff --git a/tests/Unit/CustomTaxonomy/TaxonomyCliTest.php b/tests/Unit/CustomTaxonomy/TaxonomyCliTest.php deleted file mode 100644 index 681b8ae26..000000000 --- a/tests/Unit/CustomTaxonomy/TaxonomyCliTest.php +++ /dev/null @@ -1,121 +0,0 @@ -mock = new TaxonomyCli('boilerplate'); -}); - -afterEach(function () { - unset($this->mock); -}); - -//---------------------------------------------------------------------------------// - -test('getCommandParentName will return correct value', function () { - expect($this->mock->getCommandParentName()) - ->toBeString() - ->toEqual(CliCreate::COMMAND_NAME); -}); - -//---------------------------------------------------------------------------------// - -test('getCommandName will return correct value', function () { - expect($this->mock->getCommandName()) - ->toBeString() - ->toEqual('taxonomy'); -}); - -//---------------------------------------------------------------------------------// - -test('getDefaultArgs will return correct array', function () { - expect($this->mock->getDefaultArgs()) - ->toBeArray() - ->toMatchArray([ - 'label' => 'Location', - 'plural_label' => 'Locations', - 'slug' => 'location', - 'rest_endpoint_slug' => 'locations', - 'post_type_slug' => 'post', - ]); -}); - -//---------------------------------------------------------------------------------// - -test('getDoc will return correct array', function () { - $docs = $this->mock->getDoc(); - - expect($docs) - ->toBeArray() - ->toHaveKeys(['shortdesc', 'synopsis', 'longdesc']) - ->and(count($docs['synopsis']))->toEqual(5) - ->and($docs['synopsis'][0]['name'])->toEqual('label') - ->and($docs['synopsis'][1]['name'])->toEqual('plural_label') - ->and($docs['synopsis'][2]['name'])->toEqual('slug') - ->and($docs['synopsis'][3]['name'])->toEqual('rest_endpoint_slug') - ->and($docs['synopsis'][4]['name'])->toEqual('post_type_slug'); -}); - -//---------------------------------------------------------------------------------// - -test('__invoke will will correctly copy example class with default args', function () { - $mock = $this->mock; - $mock([], $this->mock->getDefaultArgs()); - - $sep = \DIRECTORY_SEPARATOR; - $output = file_get_contents(Components::getProjectPaths('srcDestination', "CustomTaxonomy{$sep}LocationTaxonomy.php")); - - expect($output) - ->toContain( - 'class LocationTaxonomy', - 'Location', - 'Locations', - 'location', - 'locations', - 'post' - ) - ->not->toContain( - 'class TaxonomyExample', - '%label%', - '%plural_label%', - '%slug%', - '%rest_endpoint_slug%', - '%post_type_slug%', - ); -}); - -test('__invoke will will correctly copy example class with custom args', function () { - $mock = $this->mock; - $mock([], [ - 'label' => 'Test', - 'plural_label' => 'Tests', - 'slug' => 'test', - 'rest_endpoint_slug' => 'tests', - 'post_type_slug' => 'product', - ]); - - $sep = \DIRECTORY_SEPARATOR; - $output = file_get_contents(Components::getProjectPaths('srcDestination', "CustomTaxonomy{$sep}TestTaxonomy.php")); - - expect($output) - ->toContain( - 'class TestTaxonomy', - 'Test', - 'Tests', - 'test', - 'tests', - 'product' - ) - ->not->toContain( - 'class TaxonomyExample', - '%label%', - '%plural_label%', - '%slug%', - '%rest_endpoint_slug%', - '%post_type_slug%', - ); -}); diff --git a/tests/Unit/CustomTaxonomy/TaxonomyExampleTest.php b/tests/Unit/CustomTaxonomy/TaxonomyExampleTest.php deleted file mode 100644 index f8c8eaeec..000000000 --- a/tests/Unit/CustomTaxonomy/TaxonomyExampleTest.php +++ /dev/null @@ -1,34 +0,0 @@ -example = new TaxonomyExample(); -}); - -afterEach(function () { - unset($this->example); -}); - -test('if taxonomy actions are registered', function () { - $this->example->register(); - - $this->assertTrue(\method_exists($this->example, 'register')); - $this->assertSame(10, has_action('init', [$this->example, 'taxonomyRegisterCallback'])); -}); - -test('if taxonomy is registered', function () { - $action = 'taxonomy_registered'; - Functions\when('register_taxonomy')->justReturn(putenv("SIDEAFFECT={$action}")); - - $this->example->taxonomyRegisterCallback(); - - $this->assertSame(\getenv('SIDEAFFECT'), $action); - - // Cleanup. - putenv('SIDEAFFECT='); -}); - diff --git a/tests/Unit/Db/DbExportTest.php b/tests/Unit/Db/DbExportTest.php deleted file mode 100644 index 17a5365aa..000000000 --- a/tests/Unit/Db/DbExportTest.php +++ /dev/null @@ -1,23 +0,0 @@ -mock = new ExportCli('boilerplate'); -}); - -afterEach(function () { - unset($this->mock); -}); - -test('Exporting DB functionality fails if --skip_db parameter is not specified', function () { - Functions\when('shell_exec')->returnArg(); - $dbExport = $this->mock; - - $dbExport([], []); - - expect(\getenv('ES_CLI_SUCCESS_HAPPENED'))->toContain('Export complete!'); -}); diff --git a/tests/Unit/Db/DbImportTest.php b/tests/Unit/Db/DbImportTest.php deleted file mode 100644 index 17b424560..000000000 --- a/tests/Unit/Db/DbImportTest.php +++ /dev/null @@ -1,154 +0,0 @@ -mock = new ImportCli('boilerplate'); -}); - -afterEach(function () { - unset($this->mock); -}); - -//---------------------------------------------------------------------------------// - -test('getCommandParentName will return correct value', function () { - expect($this->mock->getCommandParentName()) - ->toBeString() - ->toEqual(CliRun::COMMAND_NAME); -}); - -//---------------------------------------------------------------------------------// - -test('getCommandName will return correct value', function () { - expect($this->mock->getCommandName()) - ->toBeString() - ->toEqual('import'); -}); - -//---------------------------------------------------------------------------------// - -test('getDefaultArgs will return correct array', function () { - expect($this->mock->getDefaultArgs()) - ->toBeArray() - ->toHaveKeys(['from', 'to', 'setup_file']); -}); - -//---------------------------------------------------------------------------------// - -test('getDoc will return correct array', function () { - $docs = $this->mock->getDoc(); - - expect($docs) - ->toBeArray() - ->toHaveKeys(['shortdesc', 'synopsis', 'longdesc']) - ->and(count($docs['synopsis']))->toEqual(3) - ->and($docs['synopsis'][0]['name'])->toEqual('from') - ->and($docs['synopsis'][1]['name'])->toEqual('to') - ->and($docs['synopsis'][2]['name'])->toEqual('setup_file'); -}); - -//---------------------------------------------------------------------------------// - -test('__invoke will log correct msg if import is success', function () { - (new SetupCli('boilerplate'))->__invoke([], [ - 'path' => Components::getProjectPaths('cliOutput', 'setup'), - 'source_path' => Components::getProjectPaths('testsData', 'setup'), - ]); - - $mock = $this->mock; - $mock([], array_merge( - $mock->getDefaultArgs(), - [ - 'from' => 'production', - 'to' => 'develop', - 'setup_file' => Components::getProjectPaths('cliOutput', 'setup' . \DIRECTORY_SEPARATOR . 'setup.json'), - ] - )); - - expect(\getenv('ES_CLI_SUCCESS_HAPPENED'))->toEqual('Finished! Success!'); -}); - -test('__invoke will fail if --from parameter is not specified', function () { - $mock = $this->mock; - $mock([], [ - 'to' => 'develop', - ]); -})->throws(Exception::class, '--from parameter is mandatory. Please provide one url key from setup.json file.'); - -test('__invoke will fail if --to parameter is not specified', function () { - $mock = $this->mock; - $mock([], [ - 'from' => 'staging' - ]); -})->throws(Exception::class, '--to parameter is mandatory. Please provide one url key from setup.json file.'); - -test('__invoke will fail if setup.json is empty', function () { - (new SetupCli('boilerplate'))->__invoke([], [ - 'path' => Components::getProjectPaths('cliOutput', 'setup'), - 'file_name' => 'setup-empty.json', - 'source_path' => Components::getProjectPaths('testsData', 'setup'), - ]); - - $mock = $this->mock; - $mock([], [ - 'from' => 'production', - 'to' => 'develop', - 'setup_file' => Components::getProjectPaths('cliOutput', 'setup' . \DIRECTORY_SEPARATOR . 'setup-empty.json'), - ]); - -})->throws(Exception::class, 'Setup file is empty on this path: ' . Components::getProjectPaths('cliOutput', 'setup' . \DIRECTORY_SEPARATOR . 'setup-empty.json') . ''); - -test('__invoke will fail if setup.json is missing url keys', function () { - (new SetupCli('boilerplate'))->__invoke([], [ - 'path' => Components::getProjectPaths('cliOutput', 'setup'), - 'file_name' => 'setup-missing-urls.json', - 'source_path' => Components::getProjectPaths('testsData', 'setup'), - ]); - - $mock = $this->mock; - $mock([], [ - 'from' => 'production', - 'to' => 'develop', - 'setup_file' => Components::getProjectPaths('cliOutput', 'setup' . \DIRECTORY_SEPARATOR . 'setup-missing-urls.json'), - ]); - -})->throws(Exception::class, 'Urls key is missing or empty.'); - -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'), - ]); - - $mock = $this->mock; - $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.'); - -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' => '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/Admin/EnqueueAdminCliTest.php b/tests/Unit/Enqueue/Admin/EnqueueAdminCliTest.php deleted file mode 100644 index f96657f5f..000000000 --- a/tests/Unit/Enqueue/Admin/EnqueueAdminCliTest.php +++ /dev/null @@ -1,31 +0,0 @@ -mock = new EnqueueAdminCli('boilerplate'); -}); - -afterEach(function () { - unset($this->mock); -}); - -test('Custom Enqueue Admin CLI command will correctly copy the Enqueue Admin class', function () { - $admin = $this->mock; - $admin([], $admin->getDefaultArgs()); - - // Check the output dir if the generated method is correctly generated. - $generatedAdmin = \file_get_contents(Components::getProjectPaths('srcDestination', 'Enqueue/Admin/EnqueueAdmin.php')); - - $this->assertStringContainsString('class EnqueueAdmin extends AbstractEnqueueAdmin', $generatedAdmin); - $this->assertStringContainsString('admin_enqueue_scripts', $generatedAdmin); - $this->assertStringNotContainsString('wp_enqueue_scripts', $generatedAdmin); -}); - - -test('Custom Enqueue Admin CLI documentation is correct', function () { - expect($this->mock->getDoc())->toBeArray(); -}); diff --git a/tests/Unit/Enqueue/Admin/EnqueueAdminExampleTest.php b/tests/Unit/Enqueue/Admin/EnqueueAdminExampleTest.php deleted file mode 100644 index 5d473bfbd..000000000 --- a/tests/Unit/Enqueue/Admin/EnqueueAdminExampleTest.php +++ /dev/null @@ -1,191 +0,0 @@ - ['someValue'], - 'anotherKey' => ['anotherValue'] - ]; - } -}; - -beforeEach(function() { - // Setup Config mock. - mock('alias:EightshiftBoilerplate\Config\Config') - ->shouldReceive([ - 'getProjectName' => 'MyProject', - 'getProjectPath' => 'tests/data', - 'getProjectVersion' => '1.0', - ]); - - Functions\when('is_admin')->justReturn(true); - - Functions\when('wp_register_style')->alias(function($args) { - putenv("REGISTER_STYLE={$args}"); - }); - - Functions\when('get_current_screen')->alias(function() { - return new class{ - public $is_block_editor = false; // We're not in the block editor. - }; - }); - - Functions\when('wp_enqueue_style')->alias(function($args) { - putenv("ENQUEUE_STYLE={$args}"); - }); - - Functions\when('wp_register_script')->alias(function($args) { - putenv("REGISTER_SCRIPT={$args}"); - }); - - Functions\when('wp_enqueue_script')->alias(function($args) { - putenv("ENQUEUE_SCRIPT={$args}"); - }); - - $localize = 'localize'; - Functions\when('wp_localize_script')->justReturn(putenv("SIDEAFFECT={$localize}")); - - $manifest = new ManifestExample(); - // We need to 'kickstart' the manifest registration manually during tests. - $manifest->setAssetsManifestRaw(); - - $this->adminEnqueue = new EnqueueAdminExampleTest($manifest); - - $this->hookSuffix = 'test'; -}); - -afterEach(function() { - unset($this->adminEnqueue, $this->hookSuffix); - - putenv('REGISTER_STYLE'); - putenv('ENQUEUE_STYLE'); - putenv('REGISTER_SCRIPT'); - putenv('ENQUEUE_SCRIPT'); - putenv('SIDEAFFECT'); -}); - -test('Register method will call login_enqueue_scripts and admin_enqueue_scripts hook', function () { - $this->adminEnqueue->register(); - - $this->assertSame(10, has_action('login_enqueue_scripts', 'Tests\Unit\Enqueue\Admin\EnqueueAdminExampleTest->enqueueStyles()')); - $this->assertSame(50, has_action('admin_enqueue_scripts', 'Tests\Unit\Enqueue\Admin\EnqueueAdminExampleTest->enqueueStyles()')); - $this->assertSame(10, has_action('admin_enqueue_scripts', 'Tests\Unit\Enqueue\Admin\EnqueueAdminExampleTest->enqueueScripts()')); - $this->assertNotSame(10, has_action('wp_enqueue_scripts', 'Tests\Unit\Enqueue\Admin\EnqueueAdminExampleTest->enqueueStyles()')); - $this->assertNotSame(10, has_action('wp_enqueue_scripts', 'Tests\Unit\Enqueue\Admin\EnqueueAdminExampleTest->enqueueScripts()')); -}); - -test('getAssetsPrefix method will return string', function () { - $assetsPrefix = $this->adminEnqueue->getAssetsPrefix(); - - $this->assertIsString($assetsPrefix, 'getAssetsPrefix method must return a string'); -}); - -test('getAssetsVersion method will return string', function () { - $assetsVersion = $this->adminEnqueue->getAssetsVersion(); - - $this->assertIsString($assetsVersion, 'getAssetsVersion method must return a string'); -}); - -test('enqueueStyles method enqueue styles in WP Admin', function () { - - $this->adminEnqueue->enqueueStyles($this->hookSuffix); - - $this->assertSame(\getenv('REGISTER_STYLE'), 'MyProject-styles', 'Method enqueueStyles() failed to register style'); - $this->assertSame(\getenv('ENQUEUE_STYLE'), 'MyProject-styles', 'Method enqueueStyles() failed to enqueue style'); -}); - -test('enqueueScripts method enqueue scripts in WP Admin', function () { - $this->adminEnqueue->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'); -}); - -test('Localization will return empty array if not initialized', function() { - class ExampleLocalization extends AbstractAssets { - - public function getAssetsPrefix(): string - { - return 'prefix'; - } - - public function getAssetsVersion(): string - { - return '1.0.0'; - } - - public function register(): void - { - } - - public function getLocalizations(): array - { - return parent::getLocalizations(); - } - } - - $localizationExample = new ExampleLocalization(); - - $this->assertIsArray($localizationExample->getLocalizations()); - $this->assertEmpty($localizationExample->getLocalizations()); -}); - -test('getAdminStyleHandle will return string', function () { - $adminHandle = $this->adminEnqueue->getAdminStyleHandle(); - - expect($adminHandle) - ->toBeString() - ->not->toBeArray(); -}); - -test('getAdminScriptHandle will return string', function () { - $adminHandle = $this->adminEnqueue->getAdminScriptHandle(); - - expect($adminHandle) - ->toBeString() - ->not->toBeArray(); -}); - -test('getConditionUse will be false if outside of admin', function () { - Functions\when('is_admin')->justReturn(false); - - $conditionUse = $this->adminEnqueue->getConditionUse(); - - expect($conditionUse) - ->toBeFalse() - ->not->toBeNull(); -}); - -test('getConditionUse will be true if inside block editor', function () { - Functions\when('get_current_screen')->alias(function () { - return new class - { - public $is_block_editor = true; // We are in the block editor. - }; - }); - - $conditionUse = $this->adminEnqueue->getConditionUse(); - - expect($conditionUse) - ->toBeTrue() - ->not->toBeNull(); -}); diff --git a/tests/Unit/Enqueue/Blocks/EnqueueBlockCliTest.php b/tests/Unit/Enqueue/Blocks/EnqueueBlockCliTest.php deleted file mode 100644 index 482212593..000000000 --- a/tests/Unit/Enqueue/Blocks/EnqueueBlockCliTest.php +++ /dev/null @@ -1,68 +0,0 @@ -mock = new EnqueueBlocksCli('boilerplate'); -}); - -afterEach(function () { - unset($this->mock); -}); - -/** - * Making an appropriate class with all it's key strings. - */ -test('Enqueue Block CLI command will make appropriate class.', function () { - $ebc = $this->mock; - $ebc([], []); - - $generatedEBC = \file_get_contents(Components::getProjectPaths('srcDestination', 'Enqueue/Blocks/EnqueueBlocks.php')); - - expect($generatedEBC) - ->toContain('class EnqueueBlocks extends AbstractEnqueueBlocks') - ->toContain('enqueue_block_editor_assets') - ->toContain('enqueueBlockEditorScript') - ->toContain('enqueue_block_editor_assets') - ->toContain('enqueueBlockEditorStyle') - ->toContain('enqueue_block_assets') - ->toContain('enqueueBlockStyle') - ->toContain('wp_enqueue_scripts') - ->toContain('enqueueBlockFrontendScript') - ->toContain('wp_enqueue_scripts'); -}); - -/** - * Testing if correct namespace will be set. - */ -test('Enqueue Block CLI command will set correct namespace.', function () { - $ebc = $this->mock; - $ebc([],[ - 'namespace' => 'NewTheme', - ]); - - $generatedEBC = \file_get_contents(Components::getProjectPaths('srcDestination', 'Enqueue/Blocks/EnqueueBlocks.php')); - - expect($generatedEBC)->toContain('namespace NewTheme\Enqueue\Blocks;'); -}); - -/** - * Testing if correct functions will be generated. - */ -test('Enqueue Block CLI command will set correct functions.', function () { - $ebc = $this->mock; - $ebc([], []); - - $generatedEBC = \file_get_contents(Components::getProjectPaths('srcDestination', 'Enqueue/Blocks/EnqueueBlocks.php')); - - expect($generatedEBC) - ->toContain('getAssetsPrefix') - ->toContain('getAssetsVersion'); -}); - -test('Custom Enqueue Blocks CLI documentation is correct', function () { - expect($this->mock->getDoc())->toBeArray(); -}); diff --git a/tests/Unit/Enqueue/Blocks/EnqueueBlockExampleTest.php b/tests/Unit/Enqueue/Blocks/EnqueueBlockExampleTest.php deleted file mode 100644 index da4f69713..000000000 --- a/tests/Unit/Enqueue/Blocks/EnqueueBlockExampleTest.php +++ /dev/null @@ -1,211 +0,0 @@ - ['someValue'], - 'anotherKey' => ['anotherValue'] - ]; - } -}; - -/** - * Setup before each test. - */ -beforeEach(function() { - // Setting imaginary values for mock and testing. - $this->projectName = 'NewProject'; - $this->projectVersion = '3.1.23'; - - // Setting WPCLI mock. - mock('alias:WP_CLI') - ->shouldReceive('success', 'error') - ->andReturnArg(0); - - // Setting up Eightshift Boilerplate Config class mock. - $config = mock('alias:EightshiftBoilerplate\Config\Config'); - - // Mocking functions from EB Config. - $config - ->shouldReceive('getProjectName') - ->andReturn($this->projectName); - - $config - ->shouldReceive('getProjectVersion') - ->andReturn($this->projectVersion); - - $config - ->shouldReceive('getProjectPath') - ->andReturn('tests/data'); - - Functions\when('wp_register_style')->alias(function($args) { - putenv("REGISTER_STYLE={$args}"); - }); - - Functions\when('wp_enqueue_style')->alias(function($args) { - putenv("ENQUEUE_STYLE={$args}"); - }); - - Functions\when('wp_register_script')->alias(function($args) { - putenv("REGISTER_SCRIPT={$args}"); - }); - - Functions\when('wp_enqueue_script')->alias(function($args) { - putenv("ENQUEUE_SCRIPT={$args}"); - }); - - $localize = 'localize'; - Functions\when('wp_localize_script')->justReturn(putenv("SIDEAFFECT={$localize}")); - - // Creating manifest from manifest data. - $manifest = new ManifestExample(); - // We need to 'kickstart' the manifest registration manually during tests. - $manifest->setAssetsManifestRaw(); - - $this->blockEnqueue = new EnqueueBlockExampleTest($manifest); - - $this->hookSuffix = 'test'; -}); - -/** - * Cleanup after each test. - */ -afterEach(function() { - unset( - $this->projectName, - $this->projectVersion, - $this->blockEnqueue, - $this->hookSuffix - ); - - putenv('REGISTER_STYLE'); - putenv('ENQUEUE_STYLE'); - putenv('REGISTER_SCRIPT'); - putenv('ENQUEUE_SCRIPT'); - putenv('SIDEAFFECT'); -}); - -/** - * Checking if register method will register the actions. - */ -test('Enqueue Blocks\' register method will set hooks.', function () { - $this->blockEnqueue->register(); - - $this->assertSame(10, has_action('enqueue_block_editor_assets', 'Tests\Unit\Enqueue\Blocks\EnqueueBlockExampleTest->enqueueBlockEditorScript()')); - $this->assertSame(50, has_action('enqueue_block_editor_assets', 'Tests\Unit\Enqueue\Blocks\EnqueueBlockExampleTest->enqueueBlockEditorStyle()')); - $this->assertSame(50, has_action('enqueue_block_assets', 'Tests\Unit\Enqueue\Blocks\EnqueueBlockExampleTest->enqueueBlockStyle()')); - $this->assertSame(10, has_action('wp_enqueue_scripts', 'Tests\Unit\Enqueue\Blocks\EnqueueBlockExampleTest->enqueueBlockFrontendScript()')); - $this->assertSame(50, has_action('wp_enqueue_scripts', 'Tests\Unit\Enqueue\Blocks\EnqueueBlockExampleTest->enqueueBlockFrontendStyle()')); -}); - -/** - * Checking if method getAssetsPrefix works correctly. - */ -test('Enqueue Blocks will get assets prefix.', function () { - $assetsPrefix = $this->blockEnqueue->getAssetsPrefix(); - - $this->assertSame($assetsPrefix, $this->projectName); -}); - -/** - * Checking if method getAssetsVersion works correctly. - */ -test('Enqueue Blocks will get assets version.', function () { - $assetsVersion= $this->blockEnqueue->getAssetsVersion(); - - $this->assertSame($assetsVersion, $this->projectVersion); -}); - -test('enqueueBlockEditorScript method will enqueue scripts for block editor', function () { - $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'); - $this->assertSame(\getenv('SIDEAFFECT'), 'localize', "Method wp_localize_script() failed"); -}); - -test('enqueueBlockEditorStyle method will enqueue styles for block editor', function () { - $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->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->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'); - $this->assertSame(\getenv('SIDEAFFECT'), 'localize', 'Method wp_localize_script() failed'); -}); - -test('enqueueBlockFrontendStyle method will enqueue styles for a block', function () { - $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'); -}); - -test('getBlockEditorScriptsHandle will return string', function () { - $adminHandle = $this->blockEnqueue->getBlockEditorScriptsHandle(); - - expect($adminHandle) - ->toBeString() - ->not->toBeArray(); -}); - -test('getBlockEditorStyleHandle will return string', function () { - $adminHandle = $this->blockEnqueue->getBlockEditorStyleHandle(); - - expect($adminHandle) - ->toBeString() - ->not->toBeArray(); -}); - -test('getBlockFrontentScriptHandle will return string', function () { - $adminHandle = $this->blockEnqueue->getBlockFrontentScriptHandle(); - - expect($adminHandle) - ->toBeString() - ->not->toBeArray(); -}); - -test('getBlockFrontentStyleHandle will return string', function () { - $adminHandle = $this->blockEnqueue->getBlockFrontentStyleHandle(); - - expect($adminHandle) - ->toBeString() - ->not->toBeArray(); -}); - -test('getBlockStyleHandle will return string', function () { - $adminHandle = $this->blockEnqueue->getBlockStyleHandle(); - - expect($adminHandle) - ->toBeString() - ->not->toBeArray(); -}); diff --git a/tests/Unit/Enqueue/Theme/EnqueueThemeCliTest.php b/tests/Unit/Enqueue/Theme/EnqueueThemeCliTest.php deleted file mode 100644 index 8b9acfddc..000000000 --- a/tests/Unit/Enqueue/Theme/EnqueueThemeCliTest.php +++ /dev/null @@ -1,32 +0,0 @@ -mock = new EnqueueThemeCli('boilerplate'); -}); - -afterEach(function () { - unset($this->mock); -}); - -test('Custom enqueue theme CLI command will correctly copy the Enqueue Theme class', function () { - $theme = $this->mock; - $theme([], $theme->getDefaultArgs()); - - // Check the output dir if the generated method is correctly generated. - $generatedTheme = \file_get_contents(Components::getProjectPaths('srcDestination', 'Enqueue/Theme/EnqueueTheme.php')); - - expect($generatedTheme) - ->toContain('class EnqueueTheme extends AbstractEnqueueTheme') - ->toContain('wp_enqueue_scripts') - ->not->toContain('admin_enqueue_scripts'); -}); - - -test('Custom Enqueue Theme CLI documentation is correct', function () { - expect($this->mock->getDoc())->toBeArray(); -}); diff --git a/tests/Unit/Enqueue/Theme/EnqueueThemeExampleTest.php b/tests/Unit/Enqueue/Theme/EnqueueThemeExampleTest.php deleted file mode 100644 index 6ac21eb17..000000000 --- a/tests/Unit/Enqueue/Theme/EnqueueThemeExampleTest.php +++ /dev/null @@ -1,124 +0,0 @@ - ['someValue'], - 'anotherKey' => ['anotherValue'] - ]; - } -}; -beforeEach(function() { - mock('alias:EightshiftBoilerplate\Config\Config') - ->shouldReceive([ - 'getProjectName' => 'MyProject', - 'getProjectPath' => 'tests/data', - 'getProjectVersion' => '1.0', - ]); - - Functions\when('wp_register_style')->alias(function($args) { - putenv("REGISTER_STYLE={$args}"); - }); - - Functions\when('wp_enqueue_style')->alias(function($args) { - putenv("ENQUEUE_STYLE={$args}"); - }); - - Functions\when('wp_register_script')->alias(function($args) { - putenv("REGISTER_SCRIPT={$args}"); - }); - - Functions\when('wp_enqueue_script')->alias(function($args) { - putenv("ENQUEUE_SCRIPT={$args}"); - }); - - $localize = 'localize'; - Functions\when('wp_localize_script')->justReturn(putenv("SIDEAFFECT={$localize}")); - - $manifest = new ManifestExample(); - // We need to 'kickstart' the manifest registration manually during tests. - $manifest->setAssetsManifestRaw(); - - $this->themeEnqueue = new EnqueueThemeExampleTest($manifest); - - $this->hookSuffix = 'test'; -}); - -afterEach(function() { - unset($this->themeEnqueue, $this->hookSuffix); - - putenv('REGISTER_STYLE'); - putenv('ENQUEUE_STYLE'); - putenv('REGISTER_SCRIPT'); - putenv('ENQUEUE_SCRIPT'); - putenv('SIDEAFFECT'); -}); - - -test('Register method will call wp_enqueue_scripts hook', function () { - $this->themeEnqueue->register(); - - $this->assertSame(10, has_action('wp_enqueue_scripts', 'Tests\Unit\Enqueue\Theme\EnqueueThemeExampleTest->enqueueStyles()')); - $this->assertSame(10, has_action('wp_enqueue_scripts', 'Tests\Unit\Enqueue\Theme\EnqueueThemeExampleTest->enqueueScripts()')); - $this->assertNotSame(10, has_action('admin_enqueue_scripts', 'Tests\Unit\Enqueue\Theme\EnqueueThemeExampleTest->enqueueStyles()')); - $this->assertNotSame(10, has_action('admin_enqueue_scripts', 'Tests\Unit\Enqueue\Theme\EnqueueThemeExampleTest->enqueueScripts()')); -}); - -test('getAssetsPrefix method will return string', function () { - $assetsPrefix = $this->themeEnqueue->getAssetsPrefix(); - - $this->assertIsString($assetsPrefix, 'getAssetsPrefix method must return a string'); -}); - -test('getAssetsVersion method will return string', function () { - $assetsVersion = $this->themeEnqueue->getAssetsVersion(); - - $this->assertIsString($assetsVersion, 'getAssetsVersion method must return a string'); -}); - -test('enqueueStyles method will enqueue styles in a theme', function () { - $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->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'); -}); - -test('getThemeScriptHandle will return string', function () { - $adminHandle = $this->themeEnqueue->getThemeScriptHandle(); - - expect($adminHandle) - ->toBeString() - ->not->toBeArray(); -}); - -test('getThemeStyleHandle will return string', function () { - $adminHandle = $this->themeEnqueue->getThemeStyleHandle(); - - expect($adminHandle) - ->toBeString() - ->not->toBeArray(); -}); diff --git a/tests/Unit/Exception/ComponentExceptionTest.php b/tests/Unit/Exception/ComponentExceptionTest.php deleted file mode 100644 index 02c86694b..000000000 --- a/tests/Unit/Exception/ComponentExceptionTest.php +++ /dev/null @@ -1,57 +0,0 @@ -toBeObject() - ->toBeInstanceOf(ComponentException::class) - ->toHaveProperty('message') - ->and($message) - ->toEqual($exceptionObject->getMessage()); -}) -->with('exceptionArguments'); - -test('Checks if the throwNotStringOrArray method functions correctly with objects.', -function () { - - $object = new stdClass(); - $exceptionObject = ComponentException::throwNotStringOrArray($object); - - expect($exceptionObject)->toBeObject() - ->toBeInstanceOf(ComponentException::class) - ->toHaveProperty('message') - ->and('Object couldn\'t be converted to string. Please provide only string or array.') - ->toEqual($exceptionObject->getMessage()); -}); - -test('Checks if throwUnableToLocateComponent method will return correct response.', function () { - - $component = 'nonexistent'; - $output = ComponentException::throwUnableToLocateComponent($component); - - 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()); -}); diff --git a/tests/Unit/Exception/FailedToLoadViewTest.php b/tests/Unit/Exception/FailedToLoadViewTest.php deleted file mode 100644 index a5829c451..000000000 --- a/tests/Unit/Exception/FailedToLoadViewTest.php +++ /dev/null @@ -1,21 +0,0 @@ -getMessage()}."; - - 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 deleted file mode 100644 index dc3fdee60..000000000 --- a/tests/Unit/Exception/InvalidBlockTest.php +++ /dev/null @@ -1,123 +0,0 @@ -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(); - - 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 () { - - $blockPath = 'some/random/path'; - $missingName = InvalidBlock::missingNameException($blockPath); - - 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 () { - - $blockName = 'paragraph'; - $blockPath = 'some/random/path'; - $missingView = InvalidBlock::missingViewException($blockName, $blockPath); - - 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 () { - - $blockPath = 'some/random/path'; - $missingRenderView = InvalidBlock::missingRenderViewException($blockPath); - - 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 () { - - $manifestPath = 'some/random/path'; - $missingManifestPath = InvalidBlock::missingSettingsManifestException($manifestPath); - - 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 () { - - $manifestPath = 'some/random/path'; - $missingManifestPath = InvalidBlock::missingWrapperManifestException($manifestPath); - - 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 () { - - $manifestPath = 'some/random/path'; - $missingComponentManifest = InvalidBlock::missingComponentManifestException($manifestPath); - - 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 () { - - $wrapperPath = 'some/random/path'; - $missingWrapperView = InvalidBlock::missingWrapperViewException($wrapperPath); - - 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(); - - 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 deleted file mode 100644 index d423c15e4..000000000 --- a/tests/Unit/Exception/InvalidCallbackTest.php +++ /dev/null @@ -1,18 +0,0 @@ -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 deleted file mode 100644 index cb305b4cc..000000000 --- a/tests/Unit/Exception/InvalidManifestTest.php +++ /dev/null @@ -1,44 +0,0 @@ -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 () { - - $manifestPath = 'some/random/path'; - - $exceptionObject = InvalidManifest::missingManifestException($manifestPath); - - 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 () { - - $errorMessage = 'Some error message'; - - $exceptionObject = InvalidManifest::manifestStructureException($errorMessage); - - 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 deleted file mode 100644 index 7edac3e84..000000000 --- a/tests/Unit/Exception/InvalidServiceTest.php +++ /dev/null @@ -1,18 +0,0 @@ -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 deleted file mode 100644 index 19fff6aa6..000000000 --- a/tests/Unit/Exception/PluginActivationFailureTest.php +++ /dev/null @@ -1,18 +0,0 @@ -toBeObject() - ->toBeInstanceOf(PluginActivationFailure::class) - ->toHaveProperty('message') - ->and($message) - ->toEqual($exceptionObject->getMessage()); -}); diff --git a/tests/Unit/Geolocation/AbstractGeolocationTest.php b/tests/Unit/Geolocation/AbstractGeolocationTest.php deleted file mode 100644 index 8330d5880..000000000 --- a/tests/Unit/Geolocation/AbstractGeolocationTest.php +++ /dev/null @@ -1,211 +0,0 @@ -geolocation = new GeolocationExample(); - $this->germanIp = '54.93.127.0'; -}); - -afterEach(function () { - unset($this->geolocation); - unset($this->germanIp); -}); - -//---------------------------------------------------------------------------------// - -test('useGeolocation function will return true', function () { - expect($this->geolocation->useGeolocation())->toBeTrue(); -}); - -//---------------------------------------------------------------------------------// - -test('getAdditionalCountries will return an empty array', function () { - expect($this->geolocation->getAdditionalCountries()) - ->toBeArray() - ->toBeEmpty(); -}); - -//---------------------------------------------------------------------------------// - -test('getIpAddress will return an empty string', function () { - expect($this->geolocation->getIpAddress()) - ->toBeString() - ->toBeEmpty(); -}); - -//---------------------------------------------------------------------------------// - -test('setLocationCookie will exit on the WordPress admin pages', function () { - $action = 'is_admin'; - - Functions\when($action)->justReturn(putenv("IS_ADMIN_ACTION={$action}")); - - $this->geolocation->setLocationCookie(); - - expect(getenv('IS_ADMIN_ACTION'))->toEqual($action); -}); - -test('setLocationCookie will exit if useGeolocation is false', function () { - Functions\when('is_admin')->justReturn(false); - - $mock = mock(GeolocationExample::class)->makePartial(); - $mock->shouldReceive('useGeolocation')->andReturn(false); - - expect($mock->setLocationCookie())->toBeNull(); -}); - -test('setLocationCookie will exit if cookie is set', function () { - $cookieName = $this->geolocation->getGeolocationCookieName(); - - $_COOKIE[$cookieName] = 'HR'; - - expect($this->geolocation->setLocationCookie())->toBeNull(); - - unset($_COOKIE[$cookieName]); -}); - -test('setLocationCookie will set cookie to localhost', function () { - $mock = mock(GeolocationExample::class)->makePartial(); - $mock->shouldReceive('setCookie') - ->withArgs(function (string $name, string $value) { - putenv("ES_SIDEAFFECT_1={$name}"); - putenv("ES_SIDEAFFECT_2={$value}"); - })->andReturnTrue(); - - $mock->setLocationCookie(); - - expect(getenv('ES_SIDEAFFECT_1')) - ->toEqual($this->geolocation->getGeolocationCookieName()) - ->and(getenv('ES_SIDEAFFECT_2'))->toEqual('localhost'); -}); - -test('setLocationCookie will set cookie based on the server location', function () { - $mock = mock(GeolocationExample::class)->makePartial(); - - $sep = \DIRECTORY_SEPARATOR; - - $mock->shouldReceive('getGeolocationPharLocation') - ->andReturn(Components::getProjectPaths('testsData', "geolocation{$sep}geoip.phar")); - $mock->shouldReceive('getGeolocationDbLocation') - ->andReturn(Components::getProjectPaths('testsData', "geolocation{$sep}geoip.mmdb")); - $mock->shouldReceive('setCookie')->withArgs(function (string $name, string $value) { - putenv("ES_SIDEAFFECT_1={$name}"); - putenv("ES_SIDEAFFECT_2={$value}"); - }); - - $_SERVER['REMOTE_ADDR'] = $this->germanIp; - - $mock->setLocationCookie(); - - expect(getenv('ES_SIDEAFFECT_2'))->toEqual('DE'); - - unset($_SERVER['REMOTE_ADDR']); -}); - -test('setLocationCookie will set cookie based on the provided manual ip', function () { - $mock = mock(GeolocationExample::class)->makePartial(); - - $sep = \DIRECTORY_SEPARATOR; - - $mock->shouldReceive('getGeolocationPharLocation') - ->andReturn(Components::getProjectPaths('testsData', "geolocation{$sep}geoip.phar")); - $mock->shouldReceive('getGeolocationDbLocation') - ->andReturn(Components::getProjectPaths('testsData', "geolocation{$sep}geoip.mmdb")); - $mock->shouldReceive('getIpAddress')->andReturn($this->germanIp); - $mock->shouldReceive('setCookie')->withArgs(function (string $name, string $value) { - putenv("ES_SIDEAFFECT_1={$name}"); - putenv("ES_SIDEAFFECT_2={$value}"); - }); - - $mock->setLocationCookie(); - - expect(getenv('ES_SIDEAFFECT_2'))->toEqual('DE'); -}); - -test('setLocationCookie will exit if geolocation DB is missing', function () { - $mock = mock(GeolocationExample::class)->makePartial(); - - $sep = \DIRECTORY_SEPARATOR; - - $mock->shouldReceive('getGeolocationPharLocation') - ->andReturn(Components::getProjectPaths('testsData', "geolocation{$sep}geoip.phar")); - - $mock->shouldReceive('getGeolocationDbLocation')->andReturn(''); - $mock->shouldReceive('getIpAddress')->andReturn($this->germanIp); - - $mock->setLocationCookie(); - expect($this->geolocation->setLocationCookie())->toBeNull(); -}); - -test('getGeolocation will throw error if geolocation phar is missing', function () { - $mock = mock(GeolocationExample::class)->makePartial(); - - $sep = \DIRECTORY_SEPARATOR; - - $mock->shouldReceive('getGeolocationPharLocation') - ->andReturn(''); - - $mock->shouldReceive('getGeolocationDbLocation') - ->andReturn(Components::getProjectPaths('testsData', "geolocation{$sep}geoip.mmdb")); - $mock->shouldReceive('getIpAddress')->andReturn($this->germanIp); - - $mock->getGeolocation(); -})->expectExceptionMessage('Missing Geolocation phar on this location '); - -test('getGeolocation will return error if GeoIp reader throws an error', function () { - $mock = mock(GeolocationExample::class)->makePartial(); - - $sep = \DIRECTORY_SEPARATOR; - - $mock->shouldReceive('getGeolocationPharLocation') - ->andReturn(Components::getProjectPaths('testsData', "geolocation{$sep}geoip.phar")); - - $mock->shouldReceive('getGeolocationDbLocation') - ->andReturn(Components::getProjectPaths('testsData', "geolocation{$sep}geoip.mmdb")); - - $mock->shouldReceive('getIpAddress')->andReturn('0.0.0.0'); - - expect($mock->getGeolocation()) - ->toBe('ERROR: The address 0.0.0.0 is not in the database.'); -}); - -//---------------------------------------------------------------------------------// - -test('getCountries returns array of correct defaults from manifest and code', function () { - $countries = $this->geolocation->getCountries(); - - expect($countries[0])->toBeArray()->toHaveKeys(['label', 'value', 'group']) - ->and(count($countries))->toEqual(252) - ->and($countries[0]['value'])->toEqual('europe') - ->and($countries[1]['value'])->toEqual('european-union') - ->and($countries[2]['value'])->toEqual('ex-yugoslavia') - ->and($countries[3]['value'])->toEqual('AF'); -}); - -test('getCountries returns array of defaults with additional items', function () { - $mock = mock(GeolocationExample::class)->makePartial(); - $mock->shouldReceive('getAdditionalCountries')->andReturn([ - [ - 'label' => 'test', - 'value' => 'test', - 'group' => ['test'], - ] - ]); - - $countries = $mock->getCountries(); - - expect(count($countries))->toEqual(253) - ->and($countries[0]['value'])->toEqual('europe') - ->and($countries[252]['value'])->toEqual('test'); -}); - -//---------------------------------------------------------------------------------// diff --git a/tests/Unit/Geolocation/GeolocationCliTest.php b/tests/Unit/Geolocation/GeolocationCliTest.php deleted file mode 100644 index 100593d5e..000000000 --- a/tests/Unit/Geolocation/GeolocationCliTest.php +++ /dev/null @@ -1,60 +0,0 @@ -geolocationCli = new GeolocationCli('boilerplate'); -}); - -afterEach(function () { - unset($this->geolocationCli); -}); - -test('Geolocation CLI command parent name is correct', function () { - $mock = $this->geolocationCli; - $commandName = $mock->getCommandParentName(); - - expect($commandName)->toEqual(CliCreate::COMMAND_NAME); -}); - -test('Geolocation CLI command name is correct', function () { - $mock = $this->geolocationCli; - $commandName = $mock->getCommandName(); - - expect($commandName)->toEqual('geolocation'); -}); - -test('Geolocation CLI command will correctly copy the geolocation example class with default args', function () { - $mock = $this->geolocationCli; - $args = $mock->getDefaultArgs(); - $mock([], $args); - - // Check the output dir if the generated method is correctly generated. - $output = \file_get_contents(Components::getProjectPaths('srcDestination', 'Geolocation/Geolocation.php')); - - expect($output) - ->toContain('class Geolocation extends AbstractGeolocation', $args['cookie_name']) - ->not->toContain('%cookie_name%'); -}); - -test('Geolocation CLI command will correctly copy the geolocation example class with develop args', function () { - $mock = $this->geolocationCli; - $args = $mock->getDefaultArgs(); - $mock([], $args); - - // Check the output dir if the generated method is correctly generated. - $output = \file_get_contents(Components::getProjectPaths('srcDestination', 'Geolocation/Geolocation.php')); - - expect($output) - ->toContain('class Geolocation extends AbstractGeolocation', $args['cookie_name']) - ->not->toContain('%cookie_name%'); -}); - -test('Geolocation CLI documentation is correct', function () { - expect($this->geolocationCli->getDoc())->toBeArray()->toHaveKey('synopsis'); - expect($this->geolocationCli->getDoc()['synopsis'][0]['name'])->toEqual('cookie_name'); -}); diff --git a/tests/Unit/Geolocation/GeolocationExampleTest.php b/tests/Unit/Geolocation/GeolocationExampleTest.php deleted file mode 100644 index bd57c33ce..000000000 --- a/tests/Unit/Geolocation/GeolocationExampleTest.php +++ /dev/null @@ -1,37 +0,0 @@ -geolocation = new GeolocationExample(); -}); - -test('Register method will call correct hooks', function () { - $this->geolocation->register(); - - expect(\method_exists($this->geolocation, 'register'))->toBeTrue(); - expect(\has_action('init', [$this->geolocation, 'setLocationCookie']))->toBe(10); -}); - -test('getGeolocationCookieName will return correct cookie name', function () { - $this->geolocation->getGeolocationCookieName(); - - expect($this->geolocation->getGeolocationCookieName())->toEqual('%cookie_name%'); -}); - -test('getGeolocationPharLocation will return the location of the geiop2.phar file', function () { - $reflection = new \ReflectionClass(GeolocationExample::class); - $path = dirname($reflection->getFileName()); - - expect($this->geolocation->getGeolocationPharLocation())->toEqual($path . \DIRECTORY_SEPARATOR . 'geoip2.phar'); -}); - -test('getGeolocationDbLocation will return the location of the Geolite2-Country.mmdb file', function () { - $reflection = new \ReflectionClass(GeolocationExample::class); - $path = dirname($reflection->getFileName()); - - expect($this->geolocation->getGeolocationDbLocation())->toEqual($path . \DIRECTORY_SEPARATOR . 'GeoLite2-Country.mmdb'); -}); diff --git a/tests/Unit/GitIgnore/GitIgnoreCliTest.php b/tests/Unit/GitIgnore/GitIgnoreCliTest.php deleted file mode 100644 index 38c80a32c..000000000 --- a/tests/Unit/GitIgnore/GitIgnoreCliTest.php +++ /dev/null @@ -1,70 +0,0 @@ -mock = new GitIgnoreCli('boilerplate'); -}); - -afterEach(function () { - unset($this->mock); -}); - -//---------------------------------------------------------------------------------// - -test('getCommandParentName will return correct value', function () { - expect($this->mock->getCommandParentName()) - ->toBeString() - ->toEqual(CliCreate::COMMAND_NAME); -}); - -//---------------------------------------------------------------------------------// - -test('getCommandName will return correct value', function () { - expect($this->mock->getCommandName()) - ->toBeString() - ->toEqual('gitignore'); -}); - -//---------------------------------------------------------------------------------// - -test('getDefaultArgs will return correct array', function () { - expect($this->mock->getDefaultArgs()) - ->toBeArray() - ->toHaveKeys(['path']); -}); - -//---------------------------------------------------------------------------------// - -test('getDoc will return correct array', function () { - $docs = $this->mock->getDoc(); - - expect($docs) - ->toBeArray() - ->toHaveKeys(['shortdesc', 'synopsis', 'longdesc']) - ->and(count($docs['synopsis']))->toEqual(1) - ->and($docs['synopsis'][0]['name'])->toEqual('path'); -}); - -//---------------------------------------------------------------------------------// - -test('__invoke will will correctly copy example class with default args', function () { - $mock = $this->mock; - $mock([], [ - 'path' => Components::getProjectPaths('cliOutput'), - ]); - - $output = \file_get_contents(Components::getProjectPaths('cliOutput', '.gitignore')); - - expect($output) - ->toContain( - 'wp-admin', - '/index.php', - 'wp-content/*', - 'wp-content/themes/twenty*/', - ); -}); diff --git a/tests/Unit/Helpers/AttributesTraitTest.php b/tests/Unit/Helpers/AttributesTraitTest.php deleted file mode 100644 index 371f9c432..000000000 --- a/tests/Unit/Helpers/AttributesTraitTest.php +++ /dev/null @@ -1,424 +0,0 @@ -toBeString() - ->toBe('right'); -}); - -test('checkAttr will throw an exception in the case that the block name is missing in the manifest', function () { - $manifest = Components::getManifest(Components::getProjectPaths('blocksDestinationCustom', 'button')); - $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. 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 () { - $manifest = Components::getManifest(Components::getProjectPaths('blocksDestinationComponents', 'button')); - $attributes['buttonIsAnchor'] = true; - - $results = Components::checkAttr('buttonIsAnchor', $attributes, $manifest); - - expect($results) - ->toBeBool() - ->toBeTrue(); -}); - -test('Asserts that checkAttr returns false in case attribute is boolean and default is not set', function () { - $manifest = Components::getManifest(Components::getProjectPaths('blocksDestinationComponents', 'button')); - $attributes['buttonIsAnchor'] = true; - - $results = Components::checkAttr('buttonIsNewTab', $attributes, $manifest); - - expect($results) - ->toBeBool() - ->toBeFalse(); -}); - -test('Asserts that checkAttr returns null in case attribute is boolean, default is not set and undefined is allowed', function () { - $manifest = Components::getManifest(Components::getProjectPaths('blocksDestinationComponents', 'button')); - $attributes['buttonIsAnchor'] = true; - - $results = Components::checkAttr('buttonIsNewTab', $attributes, $manifest, true); - - expect($results) - ->not->toBeBool() - ->toBeNull(); -}); - -test('Asserts that checkAttr works in case attribute is array', function () { - $manifest = Components::getManifest(Components::getProjectPaths('blocksDestinationComponents', 'button')); - $attributes['buttonAttrs'] = ['attr 1', 'attr 2']; - - $results = Components::checkAttr('buttonAttrs', $attributes, $manifest); - - expect($results) - ->toBeArray(); - - expect($results[0]) - ->toBe('attr 1'); - expect($results[1]) - ->toBe('attr 2'); -}); - -test('Asserts that checkAttr returns empty array in case attribute is array or object and default is not set', function () { - $manifest = Components::getManifest(Components::getProjectPaths('blocksDestinationComponents', 'button')); - $attributes['buttonSize'] = 'large'; - - $results = Components::checkAttr('buttonAttrs', $attributes, $manifest); - - - expect($results) - ->toBeArray() - ->toBe([]); -}); - -test('Asserts that checkAttr returns null in case attribute is array or object, default is not set, and undefined is allowed', function () { - $manifest = Components::getManifest(Components::getProjectPaths('blocksDestinationComponents', 'button')); - $attributes['buttonSize'] = 'large'; - - $results = Components::checkAttr('buttonAttrs', $attributes, $manifest, true); - - expect($results) - ->not->toBeArray() - ->toBeNull(); -}); - -test('Asserts that checkAttr returns default value', function () { - $manifest = Components::getManifest(Components::getProjectPaths('blocksDestinationComponents', 'button')); - $attributes['title'] = 'Some attribute'; - - $results = Components::checkAttr('buttonAlign', $attributes, $manifest, 'button'); - - expect($results) - ->toBeString() - ->toBe('left'); -}); - -test('Asserts that checkAttr throws exception if manifest key is not set', function () { - $manifest = Components::getManifest(Components::getProjectPaths('blocksDestinationComponents', 'button')); - $attributes['title'] = 'Some attribute'; - - Components::checkAttr('bla', $attributes, $manifest, 'button'); -})->throws(Exception::class, "bla key does not exist in the button component manifest. Please check your implementation."); - -test('Asserts that checkAttr returns attribute based on prefix if set', function () { - $manifest = Components::getManifest(Components::getProjectPaths('blocksDestinationComponents', 'button')); - $attributes = [ - 'prefix' => 'prefixedMultipleTimesButton', - 'prefixedMultipleTimesButtonAlign' => 'right' - ]; - - $results = Components::checkAttr('buttonAlign', $attributes, $manifest); - - expect($results) - ->toBeString() - ->toBe('right'); -}); - -// ------------------------------------------ -// checkAttrResponsive -// ------------------------------------------ - -test('Asserts that checkAttrResponsive returns the correct output.', function () { - $manifest = Components::getManifest(Components::getProjectPaths('blocksDestinationComponents', 'heading')); - $attributes = [ - 'headingContentSpacingLarge' => '10', - 'headingContentSpacingDesktop' => '5', - 'headingContentSpacingTablet' => '3', - 'headingContentSpacingMobile' => '1', - ]; - - $results = Components::checkAttrResponsive('headingContentSpacing', $attributes, $manifest); - - expect($results) - ->toBeArray() - ->toHaveKey('large'); - - expect($results['large']) - ->toBe('10'); -}); - -test('Asserts that checkAttrResponsive returns empty values if attribute is not provided.', function () { - $manifest = Components::getManifest(Components::getProjectPaths('blocksDestinationComponents', 'heading')); - $attributes = []; - - $results = Components::checkAttrResponsive('headingContentSpacing', $attributes, $manifest); - - expect($results) - ->toBeArray() - ->toHaveKey('large'); - - expect($results['large']) - ->toBe(''); -}); - -test('Asserts that checkAttrResponsive returns null if default is not set and undefined is allowed.', function () { - $manifest = Components::getManifest(Components::getProjectPaths('blocksDestinationComponents', 'heading')); - $attributes = [ - 'headingContentSpacingDesktop' => '2' - ]; - - $results = Components::checkAttrResponsive('headingContentSpacing', $attributes, $manifest, true); - - expect($results) - ->toBeArray() - ->toHaveKey('large') - ->toHaveKey('desktop') - ->toHaveKey('tablet'); - - expect($results['large']) - ->toBeNull(); - expect($results['desktop']) - ->toBe('2'); - expect($results['tablet']) - ->toBeNull(); -}); - -test('Asserts that checkAttrResponsive throws error if responsiveAttribute key is missing', function () { - $manifest = Components::getManifest(Components::getProjectPaths('blocksDestinationComponents', 'button')); - $attributes = []; - - Components::checkAttrResponsive('headingContentSpacing', $attributes, $manifest, 'button'); -})->throws(Exception::class, 'It looks like you are missing responsiveAttributes key in your button component manifest.'); - -test('Asserts that checkAttrResponsive throws error if keyName key is missing responsiveAttributes array', function () { - $manifest = Components::getManifest(Components::getProjectPaths('blocksDestinationComponents', 'heading')); - $attributes = []; - - Components::checkAttrResponsive('testAttribute', $attributes, $manifest, 'button'); -})->throws(Exception::class, 'It looks like you are missing the testAttribute key in your manifest responsiveAttributes array.'); - -test('Asserts that checkAttrResponsive throws error if keyName key is missing responsiveAttributes array for blockName', function () { - $manifest = Components::getManifest(Components::getProjectPaths('blocksDestinationCustom', 'heading')); - $attributes = []; - - Components::checkAttrResponsive('bla', $attributes, $manifest, 'button'); -})->throws(Exception::class, 'It looks like you are missing responsiveAttributes key in your heading block manifest.'); - -// ------------------------------------------ -// getAttrKey -// ------------------------------------------ - -test('Asserts that getAttrKey will return the key in case of the wrapper', function () { - - $attributeKey = Components::getAttrKey('wrapper', [], []); - - expect($attributeKey) - ->toBeString() - ->toBe('wrapper'); -}); - -// ------------------------------------------ -// props -// ------------------------------------------ - -test('Asserts props for heading block will return only heading attributes', function () { - $headingBlock = Components::getManifest(Components::getProjectPaths('blocksDestinationCustom', 'heading')); - $headingComponent = Components::getManifest(Components::getProjectPaths('blocksDestinationComponents', 'heading')); - $typographyComponent = Components::getManifest(Components::getProjectPaths('blocksDestinationComponents', 'typography')); - - $attributes = array_merge( - $headingBlock['attributes'], - $headingComponent['attributes'], - $typographyComponent['attributes'] - ); - - mock('alias:EightshiftBoilerplate\Config\Config') - ->shouldReceive('getProjectPath') - ->andReturn('tests/data'); - - $this->blocksExample = new BlocksExample(); - $this->blocksExample->getBlocksDataFullRaw(); - $output = Components::props($headingBlock['blockName'], $attributes); - - expect($output) - ->toBeArray() - ->toHaveKey('headingAlign') - ->not->toHaveKey('typographySize'); -}); - -test('Asserts props for heading component will return only typography attributes', function () { - $headingBlock = Components::getManifest(Components::getProjectPaths('blocksDestinationCustom', 'heading')); - $headingComponent = Components::getManifest(Components::getProjectPaths('blocksDestinationComponents', 'heading')); - $typographyComponent = Components::getManifest(Components::getProjectPaths('blocksDestinationComponents', 'typography')); - - $attributes = array_merge( - $headingBlock['attributes'], - $headingComponent['attributes'], - $typographyComponent['attributes'] - ); - - mock('alias:EightshiftBoilerplate\Config\Config') - ->shouldReceive('getProjectPath') - ->andReturn('tests/data'); - - $this->blocksExample = new BlocksExample(); - $this->blocksExample->getBlocksDataFullRaw(); - $output = Components::props('typography', $attributes); - - expect($output) - ->toBeArray() - ->toHaveKey('typographyContent') - ->not->toHaveKey('headingSize'); -}); - -test('Asserts props will correctly build the prefix', function () { - $headingBlock = Components::getManifest(Components::getProjectPaths('blocksDestinationCustom', 'heading')); - $headingComponent = Components::getManifest(Components::getProjectPaths('blocksDestinationComponents', 'heading')); - $typographyComponent = Components::getManifest(Components::getProjectPaths('blocksDestinationComponents', 'typography')); - - $attributes = array_merge( - $headingBlock['attributes'], - $headingComponent['attributes'], - $typographyComponent['attributes'] - ); - - mock('alias:EightshiftBoilerplate\Config\Config') - ->shouldReceive('getProjectPath') - ->andReturn('tests/data'); - - $this->blocksExample = new BlocksExample(); - $this->blocksExample->getBlocksDataFullRaw(); - $output = Components::props('heading', $attributes); - - expect($output) - ->toBeArray() - ->toHaveKey('prefix'); - - expect($output['prefix']) - ->toBe('heading'); - - // Next level - $output = Components::props('typography', $output); - - expect($output) - ->toBeArray() - ->toHaveKey('prefix'); - - expect($output['prefix']) - ->toBe('headingTypography'); -}); - -test('Asserts props will correctly leave only the the needed attributes', function () { - $attributes = [ - 'componentName' => 'mock-card', - 'mockCardHeadingTypographyContent' => 'mock heading content', - 'mockCardParagraphTypographyContent' => 'mock paragraph content', - ]; - - mock('alias:EightshiftBoilerplate\Config\Config') - ->shouldReceive('getProjectPath') - ->andReturn('tests/data'); - - $this->blocksExample = new BlocksExample(); - $this->blocksExample->getBlocksDataFullRaw(); - $output = Components::props('mock-card', $attributes); - - expect($output) - ->toBeArray() - ->toHaveKey('mockCardHeadingTypographyContent') - ->toHaveKey('mockCardParagraphTypographyContent'); - - // Now let's pass these to mock heading - $output = Components::props('heading', $output); - - expect($output) - ->toBeArray() - ->toHaveKey('mockCardHeadingTypographyContent') - ->not->toHaveKey('mockCardParagraphTypographyContent'); - - $output = Components::props('typography', $output); - - expect($output) - ->toBeArray() - ->toHaveKey('mockCardHeadingTypographyContent'); -}); - -test('Asserts props will correctly generate manual keys in camelCase', function () { - $attributes = [ - 'componentName' => 'mock-card', - 'mockCardHeadingContent' => 'mock heading content', - 'mockCardParagraphContent' => 'mock paragraph content', - ]; - - $manual = [ - 'buttonContent' => 'mock button content', - ]; - - mock('alias:EightshiftBoilerplate\Config\Config') - ->shouldReceive('getProjectPath') - ->andReturn('tests/data'); - - $this->blocksExample = new BlocksExample(); - $this->blocksExample->getBlocksDataFullRaw(); - $output = Components::props('mock-card', $attributes, $manual); - - expect($output) - ->toBeArray() - ->toHaveKey('mockCardButtonContent') - ->not->toHaveKey('mockCardbuttonContent'); -}); - -test('Props will include the correct attribute in the manual case', function () { - $attributes = [ - 'componentName' => 'mock-card', - 'componentJsClass' => 'js-mock-card', - 'mockCardHeadingContent' => 'mock heading content', - 'mockCardParagraphContent' => 'mock paragraph content', - ]; - - $manual = [ - 'buttonContent' => 'mock button content', - 'selectorClass' => 'selector', - ]; - - mock('alias:EightshiftBoilerplate\Config\Config') - ->shouldReceive('getProjectPath') - ->andReturn('tests/data'); - - $this->blocksExample = new BlocksExample(); - $this->blocksExample->getBlocksDataFullRaw(); - $output = Components::props('mock-card', $attributes, $manual); - - expect($output) - ->toBeArray() - ->toHaveKey('mockCardButtonContent') - ->toHaveKey('selectorClass') - ->toHaveKey('componentJsClass'); -}); - -// ------------------------------------------ -// getDefaultRenderAttributes -// ------------------------------------------ - -test('Asserts that getDefaultRenderAttributes function will return empty array on non iterable manifest', function () { - - $output = Components::render('button-false', [], '', true); - - expect($output) - ->toBeString(); -}); diff --git a/tests/Unit/Helpers/ComponentHelpersTest.php b/tests/Unit/Helpers/ComponentHelpersTest.php deleted file mode 100644 index 200020f1e..000000000 --- a/tests/Unit/Helpers/ComponentHelpersTest.php +++ /dev/null @@ -1,100 +0,0 @@ -not->toBeEmpty() - ->toContain('Hello!'); -}); - -test('Asserts that rendering a component will output a wrapper if parentClass is provided', function () { - $results = Components::render('button', ['parentClass' => 'test']); - - expect($results) - ->not->toBeEmpty() - ->toContain('Hello!') - ->not->toContain('test__button.php') - ->toContain('test__button'); -}); - -test('Asserts that providing a missing component will throw an exception without extension', function () { - Components::render('component', []); -})->throws(ComponentException::class); - -test('Asserts that providing a missing component will throw an exception', function () { - Components::render('component-a.php', []); -})->throws(ComponentException::class); - -test('Asserts that render used components defaults', function () { - $results = Components::render('button', [], '', true); - - expect($results) - ->not->toBeEmpty() - ->toContain('Hello!'); -}); - -// ------------------------------------------ -// getManifest -// ------------------------------------------ - -test('Asserts that "getManifest" will return correct files if path name is used.', function () { - expect(Components::getManifest(Components::getProjectPaths('testsData', 'src/Blocks/wrapper'))) - ->toBeArray() - ->toHaveKey('componentName') - ->and(Components::getManifest(Components::getProjectPaths('testsData', 'src/Blocks'))) - ->toBeArray() - ->toHaveKey('namespace') - ->and(Components::getManifest(Components::getProjectPaths('testsData', 'src/Blocks/components/button'))) - ->toBeArray() - ->toHaveKey('componentName') - ->and(Components::getManifest(Components::getProjectPaths('testsData', 'src/Blocks/custom/button'))) - ->toBeArray() - ->toHaveKey('blockName'); -}); - -test('Asserts that "getManifest" will return correct files if name is used.', function () { - expect(Components::getManifest('wrapper')) - ->toBeArray() - ->toHaveKey('componentName') - ->and(Components::getManifest('settings')) - ->toBeArray() - ->toHaveKey('namespace') - ->and(Components::getManifest('component', 'button')) - ->toBeArray() - ->toHaveKey('componentName') - ->and(Components::getManifest('block', 'button')) - ->toBeArray() - ->toHaveKey('blockName'); -}); - -// ------------------------------------------ -// getManifestDirect -// ------------------------------------------ - -test('Asserts that reading manifest.json using getManifest will return an array', function () { - $results = Components::getManifestDirect(Components::getProjectPaths('testsData', 'src/Blocks/components/button')); - - expect($results) - ->toBeArray() - ->toHaveKey('componentName'); -}); - -test('Asserts that not specifying the path in getManifest will throw an exception', function () { - Components::getManifestDirect(\dirname(__FILE__)); -})->throws(ComponentException::class); diff --git a/tests/Unit/Helpers/CssVariablesTraitTest.php b/tests/Unit/Helpers/CssVariablesTraitTest.php deleted file mode 100644 index 884d93832..000000000 --- a/tests/Unit/Helpers/CssVariablesTraitTest.php +++ /dev/null @@ -1,279 +0,0 @@ -toBeString() - ->toContain('') - ->toContain(':root {') - ->toContain('--global-colors-primary: #C3151B;') - ->toContain('--global-colors-primary-values: 195 21 27;') - ->not->toContain('--button-content:'); -}); - -test('Asserts that outputCssVariablesGlobal returns empty string if global manifest data is not provided', function () { - $output = Components::outputCssVariablesGlobal(); - - expect($output) - ->toBeString() - ->not->toContain('"); -}); - -test('Asserts that "outputCssVariablesInline" will return empty style tag if styles are empty.', function () { - Components::setConfigOutputCssGloballyAdditionalStyles([]); - Components::setStyles([]); - - $result = Components::outputCssVariablesInline(); - - expect($result)->toBeString()->toEqual(""); -}); - -test('Asserts that "outputCssVariablesInline" will return style tag with the correct styles.', function () { - Components::setConfigOutputCssOptimize(false); - - ; - $manifest = Components::getManifest(Components::getProjectPaths('blocksDestinationComponents', 'variables')); - $attributes = [ - 'variableValue' => 'value3', - ]; - - Components::outputCssVariables($attributes, $manifest, 'unique'); - - $result = Components::outputCssVariablesInline(); - - expect($result)->toBeString()->toContain( - "