diff --git a/.vortex/installer/src/Command/InstallCommand.php b/.vortex/installer/src/Command/InstallCommand.php index 3001028b2..4d1f5151b 100644 --- a/.vortex/installer/src/Command/InstallCommand.php +++ b/.vortex/installer/src/Command/InstallCommand.php @@ -16,8 +16,8 @@ use DrevOps\VortexInstaller\Runner\ExecutableFinderAwareTrait; use DrevOps\VortexInstaller\Runner\RunnerInterface; use DrevOps\VortexInstaller\Schema\AgentHelp; -use DrevOps\VortexInstaller\Schema\ConfigValidator; use DrevOps\VortexInstaller\Schema\SchemaGenerator; +use DrevOps\VortexInstaller\Schema\SchemaValidator; use DrevOps\VortexInstaller\Task\Task; use DrevOps\VortexInstaller\Utils\Config; use DrevOps\VortexInstaller\Utils\Env; @@ -62,6 +62,8 @@ class InstallCommand extends Command implements CommandRunnerAwareInterface, Exe const OPTION_VALIDATE = 'validate'; + const OPTION_PROMPTS = 'prompts'; + const OPTION_AGENT_HELP = 'agent-help'; /** @@ -142,6 +144,7 @@ protected function configure(): void { $this->addOption(static::OPTION_URI, 'l', InputOption::VALUE_REQUIRED, 'Remote or local repository URI with an optional git ref set after @.'); $this->addOption(static::OPTION_NO_CLEANUP, NULL, InputOption::VALUE_NONE, 'Do not remove installer after successful installation.'); $this->addOption(static::OPTION_BUILD, 'b', InputOption::VALUE_NONE, 'Run auto-build after installation without prompting.'); + $this->addOption(static::OPTION_PROMPTS, 'p', InputOption::VALUE_REQUIRED, 'A JSON string with prompt answers or a path to a JSON file. Keys are prompt IDs from --schema.'); $this->addOption(static::OPTION_SCHEMA, NULL, InputOption::VALUE_NONE, 'Output prompt schema as JSON.'); $this->addOption(static::OPTION_VALIDATE, NULL, InputOption::VALUE_NONE, 'Validate config without installing.'); $this->addOption(static::OPTION_AGENT_HELP, NULL, InputOption::VALUE_NONE, 'Output instructions for AI agents on how to use the installer.'); @@ -306,8 +309,8 @@ protected function handleSchema(InputInterface $input, OutputInterface $output): $config = Config::fromString('{}'); $prompt_manager = new PromptManager($config); - $generator = new SchemaGenerator(); - $schema = $generator->generate($prompt_manager->getHandlers()); + $generator = new SchemaGenerator($prompt_manager->getHandlers()); + $schema = $generator->generate(); $output->write((string) json_encode($schema, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); @@ -318,28 +321,30 @@ protected function handleSchema(InputInterface $input, OutputInterface $output): * Handle --validate option. */ protected function handleValidate(InputInterface $input, OutputInterface $output): int { - $config_option = $input->getOption(static::OPTION_CONFIG); + $prompts_option = $input->getOption(static::OPTION_PROMPTS); - if (empty($config_option) || !is_string($config_option)) { - $output->writeln('The --validate option requires --config.'); + if (empty($prompts_option) || !is_string($prompts_option)) { + $output->writeln('The --validate option requires --prompts.'); return Command::FAILURE; } - $config_json = is_file($config_option) ? (string) file_get_contents($config_option) : $config_option; - $user_config = json_decode($config_json, TRUE); + $prompts_json = is_file($prompts_option) ? (string) file_get_contents($prompts_option) : $prompts_option; + $decoded = json_decode($prompts_json); - if (!is_array($user_config)) { - $output->writeln('Invalid JSON in --config.'); + if (!$decoded instanceof \stdClass) { + $output->writeln('Invalid JSON in --prompts. Expected a JSON object.'); return Command::FAILURE; } + $user_config = json_decode($prompts_json, TRUE); + $config = Config::fromString('{}'); $prompt_manager = new PromptManager($config); - $validator = new ConfigValidator(); - $result = $validator->validate($user_config, $prompt_manager->getHandlers()); + $validator = new SchemaValidator($prompt_manager->getHandlers()); + $result = $validator->validate($user_config); $output->write((string) json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); diff --git a/.vortex/installer/src/Prompts/PromptManager.php b/.vortex/installer/src/Prompts/PromptManager.php index e59db6719..3c124adac 100644 --- a/.vortex/installer/src/Prompts/PromptManager.php +++ b/.vortex/installer/src/Prompts/PromptManager.php @@ -43,9 +43,9 @@ use DrevOps\VortexInstaller\Prompts\Handlers\Tools; use DrevOps\VortexInstaller\Prompts\Handlers\VersionScheme; use DrevOps\VortexInstaller\Prompts\Handlers\Webroot; +use DrevOps\VortexInstaller\Schema\SchemaValidator; use DrevOps\VortexInstaller\Utils\Config; use DrevOps\VortexInstaller\Utils\Converter; -use DrevOps\VortexInstaller\Utils\Env; use DrevOps\VortexInstaller\Utils\Tui; use Symfony\Component\Console\Output\OutputInterface; use function Laravel\Prompts\confirm; @@ -87,6 +87,15 @@ class PromptManager { */ protected array $handlers = []; + /** + * Prompt overrides from --prompts CLI option. + * + * Keyed by handler ID with validated values. + * + * @var array + */ + protected array $promptOverrides = []; + /** * PromptManager constructor. * @@ -97,6 +106,7 @@ public function __construct( protected Config $config, ) { $this->initHandlers(); + $this->resolvePromptOverrides(); } /** @@ -577,6 +587,39 @@ protected function initHandlers(): void { } } + /** + * Resolve prompt overrides from --prompts CLI option. + * + * Reads the raw prompt array from Config, normalizes keys to handler IDs, + * validates values against handler types and options, and stores the + * validated overrides. + * + * @throws \RuntimeException + * If any prompt value is invalid. + */ + private function resolvePromptOverrides(): void { + $raw = $this->config->get(Config::PROMPTS); + + if (!is_array($raw) || empty($raw)) { + return; + } + + $validator = new SchemaValidator($this->handlers); + $result = $validator->validate($raw); + + if (!empty($result['errors'])) { + $messages = array_map(fn(array $error): string => sprintf('%s: %s', $error['prompt'], $error['message']), $result['errors']); + throw new \RuntimeException(sprintf('Invalid --prompts values: %s', implode('; ', $messages))); + } + + // Use the resolved values which include defaults for missing prompts. + foreach ($raw as $key => $value) { + if (isset($this->handlers[$key])) { + $this->promptOverrides[$key] = $value; + } + } + } + /** * Dispatch a prompt using the handler's type enum. * @@ -646,22 +689,13 @@ private function args(string $handler_class, mixed $default_override = NULL, arr // Find appropriate default value. $default_from_handler = $handler->default($responses); - // Create the env var name. - $var_name = $handler::envName(); - // Get from config. - $config_val = $this->config->get($var_name); - $default_from_config = is_null($config_val) ? NULL : $config_val; - // Get from env. - $env_val = Env::get($var_name); - $default_from_env = is_null($env_val) ? NULL : Env::toValue($env_val); + // Get from prompt overrides (--prompts CLI option). + $default_from_prompts = $this->promptOverrides[$id] ?? NULL; // Get from discovery. $default_from_discovery = $this->handlers[$id]->discover(); - if (!is_null($default_from_config)) { - $default = $default_from_config; - } - elseif (!is_null($default_from_env)) { - $default = $default_from_env; + if (!is_null($default_from_prompts)) { + $default = $default_from_prompts; } elseif (!is_null($default_from_discovery)) { $default = $default_from_discovery; diff --git a/.vortex/installer/src/Schema/AgentHelp.php b/.vortex/installer/src/Schema/AgentHelp.php index c80db1fb4..cc2fa4504 100644 --- a/.vortex/installer/src/Schema/AgentHelp.php +++ b/.vortex/installer/src/Schema/AgentHelp.php @@ -31,17 +31,16 @@ public static function render(): string { available configuration prompts, their types, valid values, defaults, and dependencies. -2. **Build a config**: Using the schema, construct a JSON object where keys are - either prompt IDs (e.g., `hosting_provider`) or environment variable names - (e.g., `VORTEX_INSTALLER_PROMPT_HOSTING_PROVIDER`). Set values according to - the prompt types and allowed options from the schema. +2. **Build prompt answers**: Using the schema, construct a JSON object where + keys are prompt IDs (the `id` field from the schema). Set values according + to the prompt types and allowed options. -3. **Validate the config**: Run with `--validate --config=''` to check - your config without performing an installation. The output is a JSON object - with `valid`, `errors`, `warnings`, and `resolved` fields. +3. **Validate**: Run with `--validate --prompts=''` to check your prompt + answers without performing an installation. The output is a JSON object with + `valid`, `errors`, `warnings`, and `resolved` fields. -4. **Install**: Run with `--no-interaction --config='' --destination=` - to perform the actual installation using your validated config. +4. **Install**: Run with `--no-interaction --prompts='' --destination=` + to perform the actual installation using your validated prompt answers. ## Commands @@ -49,22 +48,31 @@ public static function render(): string { # Get the prompt schema php installer.php --schema -# Validate a config (JSON string) -php installer.php --validate --config='{"name":"My Project","hosting_provider":"lagoon"}' +# Validate prompt answers (JSON string) +php installer.php --validate --prompts='{"name":"My Project","hosting_provider":"lagoon"}' -# Validate a config (JSON file) -php installer.php --validate --config=config.json +# Validate prompt answers (JSON file) +php installer.php --validate --prompts=prompts.json # Install non-interactively -php installer.php --no-interaction --config='' --destination=./my-project +php installer.php --no-interaction --prompts='' --destination=./my-project ``` +## Options + +- `--prompts` (`-p`): JSON object of prompt answers, keyed by prompt ID. + Accepts a JSON string or a path to a JSON file. +- `--config` (`-c`): JSON object of installer configuration (repository, ref, + and other internal settings). Not for prompt answers. +- `--destination`: Target directory for installation. +- `--no-interaction` (`-n`): Non-interactive mode. Prompts without answers in + `--prompts` use discovered or default values. + ## Schema Format The `--schema` output contains a `prompts` array. Each prompt has: -- `id`: The prompt identifier (use as config key). -- `env`: The environment variable name (alternative config key). +- `id`: The prompt identifier (use as key in `--prompts` JSON). - `type`: One of `text`, `select`, `multiselect`, `confirm`, `suggest`. - `label`: Human-readable label. - `description`: Optional description text. @@ -80,7 +88,7 @@ public static function render(): string { - `text` / `suggest`: string value. - `select`: string value matching one of the option values. -- `multiselect`: array of strings, each matching an option value. +- `multiselect`: JSON array of strings, each matching an option value. - `confirm`: boolean (`true` or `false`). ## Dependencies @@ -110,7 +118,7 @@ public static function render(): string { - Start with `--schema` to understand what prompts exist. - Provide values only for prompts you want to customize; defaults will be used for the rest. -- Use `--validate` to check your config before installing. +- Use `--validate` to check your prompt answers before installing. - The `resolved` field in validation output shows the complete config that would be used, including defaults. AGENT_HELP; diff --git a/.vortex/installer/src/Schema/SchemaGenerator.php b/.vortex/installer/src/Schema/SchemaGenerator.php index 2dc9460cf..2fddf40d8 100644 --- a/.vortex/installer/src/Schema/SchemaGenerator.php +++ b/.vortex/installer/src/Schema/SchemaGenerator.php @@ -16,25 +16,32 @@ class SchemaGenerator { /** - * Generate schema from handlers. + * Constructor. * * @param array $handlers * An associative array of handler instances keyed by handler ID. + */ + public function __construct( + protected array $handlers, + ) { + } + + /** + * Generate schema from handlers. * * @return array * The schema structure with a 'prompts' key. */ - public function generate(array $handlers): array { + public function generate(): array { $prompts = []; - foreach ($handlers as $id => $handler) { + foreach ($this->handlers as $id => $handler) { if (in_array($id, static::getExcludedHandlers(), TRUE)) { continue; } $prompts[] = [ 'id' => $handler::id(), - 'env' => $handler::envName(), 'type' => $handler->type()->value, 'label' => $handler->label(), 'description' => $handler::description([]), diff --git a/.vortex/installer/src/Schema/ConfigValidator.php b/.vortex/installer/src/Schema/SchemaValidator.php similarity index 66% rename from .vortex/installer/src/Schema/ConfigValidator.php rename to .vortex/installer/src/Schema/SchemaValidator.php index a575e0e8b..19f3c058b 100644 --- a/.vortex/installer/src/Schema/ConfigValidator.php +++ b/.vortex/installer/src/Schema/SchemaValidator.php @@ -8,32 +8,52 @@ use DrevOps\VortexInstaller\Prompts\PromptType; /** - * Validates a config array against handler definitions. + * Validates prompt values against handler definitions. * * @package DrevOps\VortexInstaller\Schema */ -class ConfigValidator { +class SchemaValidator { /** - * Validate a config array against handlers. + * Constructor. * - * @param array $config - * The config array to validate, keyed by env var name or handler ID. * @param array $handlers * An associative array of handler instances keyed by handler ID. + */ + public function __construct( + protected array $handlers, + ) { + } + + /** + * Validate a config array against handlers. + * + * @param array $config + * The config array to validate, keyed by handler ID. * * @return array * Validation result with keys: valid, errors, warnings, resolved. */ - public function validate(array $config, array $handlers): array { + public function validate(array $config): array { $errors = []; $warnings = []; $resolved = []; - // Normalize config keys: support both env var names and handler IDs. - $normalized = $this->normalizeConfig($config, $handlers); + // Normalize config keys to handler IDs. + $normalized = $this->normalizeConfig($config); - foreach ($handlers as $id => $handler) { + // Report unknown prompt IDs. + $known_ids = array_keys($this->handlers); + foreach (array_keys($normalized) as $key) { + if (!in_array($key, $known_ids, TRUE)) { + $errors[] = [ + 'prompt' => $key, + 'message' => sprintf('Unknown prompt "%s".', $key), + ]; + } + } + + foreach ($this->handlers as $id => $handler) { if (in_array($id, SchemaGenerator::getExcludedHandlers(), TRUE)) { continue; } @@ -41,59 +61,41 @@ public function validate(array $config, array $handlers): array { $has_value = array_key_exists($id, $normalized); $value = $normalized[$id] ?? NULL; - // Check dependency conditions. + // Skip prompts not provided in the input. + if (!$has_value) { + continue; + } + + // Check dependency conditions for provided prompts. $depends_on = $handler->dependsOn(); if ($depends_on !== NULL) { $dep_result = $this->checkDependency($depends_on, $normalized); if ($dep_result === 'skip') { - // System dependency - skip validation. - if ($has_value) { - $resolved[$id] = $value; - } - continue; - } - - if ($dep_result === FALSE) { - // Dependency not met. - if ($has_value) { - $dep_keys = array_keys($depends_on); - $dep_values = []; - foreach ($depends_on as $dep_id => $acceptable) { - $dep_values[] = $dep_id . '=' . implode('|', array_map(fn($v): string => var_export($v, TRUE), $acceptable)); - } - $warnings[] = [ + $type_error = $this->validateType($handler, $value); + if ($type_error !== NULL) { + $errors[] = [ 'prompt' => $id, - 'message' => sprintf('Value will be ignored: %s condition is not met.', implode(', ', $dep_values)), + 'message' => $type_error, ]; + continue; } - // Dependency not met + missing value = OK (skip). - continue; - } - // Dependency met + missing required value = error. - if (!$has_value && $handler->isRequired()) { - $errors[] = [ - 'prompt' => $id, - 'message' => sprintf('Missing required value for "%s" (dependency condition is met).', $id), - ]; + $resolved[$id] = $value; continue; } - } - // If no value provided, use default. - if (!$has_value) { - $default = $handler->default($normalized); - if ($default !== NULL) { - $resolved[$id] = $default; - } - elseif ($handler->isRequired()) { - $errors[] = [ + if ($dep_result === FALSE) { + $dep_values = []; + foreach ($depends_on as $dep_id => $acceptable) { + $dep_values[] = $dep_id . '=' . implode('|', array_map(fn($v): string => var_export($v, TRUE), $acceptable)); + } + $warnings[] = [ 'prompt' => $id, - 'message' => sprintf('Missing required value for "%s".', $id), + 'message' => sprintf('Value will be ignored: %s condition is not met.', implode(', ', $dep_values)), ]; + continue; } - continue; } // Validate value based on type. @@ -124,32 +126,15 @@ public function validate(array $config, array $handlers): array { * * @param array $config * The raw config array. - * @param array $handlers - * Handler instances. * * @return array * Config keyed by handler IDs. */ - protected function normalizeConfig(array $config, array $handlers): array { + protected function normalizeConfig(array $config): array { $normalized = []; - // Build env-name-to-id mapping. - $env_to_id = []; - foreach ($handlers as $id => $handler) { - $env_to_id[$handler::envName()] = $id; - } - foreach ($config as $key => $value) { - if (isset($env_to_id[$key])) { - $normalized[$env_to_id[$key]] = $value; - } - elseif (isset($handlers[$key])) { - $normalized[$key] = $value; - } - else { - // Try as-is (might be an unknown key). - $normalized[$key] = $value; - } + $normalized[$key] = $value; } return $normalized; diff --git a/.vortex/installer/src/Utils/Config.php b/.vortex/installer/src/Utils/Config.php index 978d5a35b..dd7006624 100644 --- a/.vortex/installer/src/Utils/Config.php +++ b/.vortex/installer/src/Utils/Config.php @@ -41,6 +41,8 @@ final class Config { const BUILD_NOW = 'VORTEX_INSTALLER_BUILD_NOW'; + const PROMPTS = 'VORTEX_INSTALLER_PROMPTS'; + /** * Store of configuration values. * diff --git a/.vortex/installer/src/Utils/OptionsResolver.php b/.vortex/installer/src/Utils/OptionsResolver.php index 431eeaef8..c1b936eb4 100644 --- a/.vortex/installer/src/Utils/OptionsResolver.php +++ b/.vortex/installer/src/Utils/OptionsResolver.php @@ -124,6 +124,29 @@ public static function resolve(array $options): array { // Internal flag to skip processing of the demo mode. $config->set(Config::IS_DEMO_DB_DOWNLOAD_SKIP, (bool) Env::get(Config::IS_DEMO_DB_DOWNLOAD_SKIP, FALSE)); + // Parse --prompts JSON if provided. + if (isset($options['prompts']) && is_scalar($options['prompts'])) { + $prompts_candidate = strval($options['prompts']); + if (is_file($prompts_candidate)) { + if (!is_readable($prompts_candidate)) { + throw new \RuntimeException(sprintf('Cannot read --prompts file: %s.', $prompts_candidate)); + } + $prompts_json = (string) file_get_contents($prompts_candidate); + } + else { + $prompts_json = $prompts_candidate; + } + $prompts = json_decode($prompts_json, TRUE); + + if (!is_array($prompts)) { + throw new \RuntimeException('Invalid JSON provided for --prompts.'); + } + + // Store the raw parsed array. Schema validation against prompt handlers + // is performed in PromptManager::resolvePromptOverrides(). + $config->set(Config::PROMPTS, $prompts, TRUE); + } + // Set no-cleanup flag. $config->set(Config::NO_CLEANUP, (bool) $options['no-cleanup']); diff --git a/.vortex/installer/tests/Fixtures/schema/valid_env_keys.json b/.vortex/installer/tests/Fixtures/schema/valid_env_keys.json deleted file mode 100644 index 57bd469ee..000000000 --- a/.vortex/installer/tests/Fixtures/schema/valid_env_keys.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "VORTEX_INSTALLER_PROMPT_NAME": "Env Key Site", - "VORTEX_INSTALLER_PROMPT_MACHINE_NAME": "env_key_site", - "VORTEX_INSTALLER_PROMPT_ORG": "Env Org", - "VORTEX_INSTALLER_PROMPT_ORG_MACHINE_NAME": "env_org", - "VORTEX_INSTALLER_PROMPT_DOMAIN": "env-key.com", - "VORTEX_INSTALLER_PROMPT_MODULE_PREFIX": "env_key", - "VORTEX_INSTALLER_PROMPT_WEBROOT": "web", - "VORTEX_INSTALLER_PROMPT_HOSTING_PROVIDER": "none" -} diff --git a/.vortex/installer/tests/Functional/Command/SchemaValidateCommandTest.php b/.vortex/installer/tests/Functional/Command/SchemaValidateCommandTest.php index dadee8451..ccd5ab76d 100644 --- a/.vortex/installer/tests/Functional/Command/SchemaValidateCommandTest.php +++ b/.vortex/installer/tests/Functional/Command/SchemaValidateCommandTest.php @@ -10,7 +10,7 @@ use DrevOps\VortexInstaller\Prompts\Handlers\HostingProvider; use DrevOps\VortexInstaller\Prompts\Handlers\Migration; use DrevOps\VortexInstaller\Prompts\Handlers\Name; -use DrevOps\VortexInstaller\Schema\ConfigValidator; +use DrevOps\VortexInstaller\Schema\SchemaValidator; use DrevOps\VortexInstaller\Schema\SchemaGenerator; use DrevOps\VortexInstaller\Tests\Functional\FunctionalTestCase; use PHPUnit\Framework\Attributes\CoversClass; @@ -21,7 +21,7 @@ */ #[CoversClass(InstallCommand::class)] #[CoversClass(SchemaGenerator::class)] -#[CoversClass(ConfigValidator::class)] +#[CoversClass(SchemaValidator::class)] class SchemaValidateCommandTest extends FunctionalTestCase { /** @@ -65,7 +65,7 @@ public function testSchemaPromptsHaveRequiredFields(): void { ]); $schema = json_decode($this->applicationGetOutput(), TRUE); - $required_fields = ['id', 'env', 'type', 'label', 'required']; + $required_fields = ['id', 'type', 'label', 'required']; foreach ($schema['prompts'] as $prompt) { foreach ($required_fields as $required_field) { @@ -138,7 +138,7 @@ public function testValidate(?string $config, array $expectations): void { if ($config !== NULL) { // Resolve fixture files relative to the fixtures directory. $path = str_starts_with($config, '/') ? $config : static::$schemaFixturesDir . '/' . $config; - $options['--' . InstallCommand::OPTION_CONFIG] = $path; + $options['--' . InstallCommand::OPTION_PROMPTS] = $path; } $expect_failure = isset($expectations['valid']) ? !$expectations['valid'] : TRUE; @@ -202,18 +202,15 @@ public function testValidate(?string $config, array $expectations): void { public static function dataProviderValidate(): \Iterator { // Valid configs. yield 'full config with lagoon hosting' => ['valid_full.json', ['valid' => TRUE]]; - yield 'minimal config with defaults' => [ + yield 'minimal config' => [ 'valid_minimal.json', [ 'valid' => TRUE, 'resolved' => [ - HostingProvider::id() => HostingProvider::NONE, - Migration::id() => FALSE, Name::id() => 'Minimal Site', ], ], ]; - yield 'config using env var key names' => ['valid_env_keys.json', ['valid' => TRUE]]; yield 'database provision with container registry' => ['valid_database_provision.json', ['valid' => TRUE]]; yield 'migration enabled' => ['valid_migration.json', ['valid' => TRUE]]; yield 'acquia hosting' => ['valid_acquia.json', ['valid' => TRUE]]; @@ -240,16 +237,13 @@ public static function dataProviderValidate(): \Iterator { ['valid' => TRUE, 'warning_prompt' => HostingProjectName::id()], ]; // Empty and array configs. - yield 'empty JSON object uses defaults' => [ + yield 'empty JSON object is valid' => [ 'empty.json', - [ - 'valid' => FALSE, - 'resolved' => [HostingProvider::id() => HostingProvider::NONE], - ], + ['valid' => TRUE], ]; - yield 'JSON array treated as empty config' => [ + yield 'JSON array rejected' => [ 'json_array.json', - ['valid' => FALSE], + ['output_contains' => 'Invalid JSON'], ]; // Broken/unparseable inputs. yield 'broken JSON syntax' => ['broken_json.json', ['output_contains' => 'Invalid JSON']]; @@ -258,7 +252,7 @@ public static function dataProviderValidate(): \Iterator { yield 'JSON string instead of object' => ['json_string.json', ['output_contains' => 'Invalid JSON']]; yield 'non-existent file treated as raw JSON' => ['/nonexistent/path/config.json', ['output_contains' => 'Invalid JSON']]; // Missing --config. - yield 'validate without --config fails' => [NULL, ['output_contains' => '--config']]; + yield 'validate without --prompts fails' => [NULL, ['output_contains' => '--prompts']]; } // ------------------------------------------------------------------------- diff --git a/.vortex/installer/tests/Functional/Handlers/AbstractHandlerProcessTestCase.php b/.vortex/installer/tests/Functional/Handlers/AbstractHandlerProcessTestCase.php index fb3988bad..140e975ac 100644 --- a/.vortex/installer/tests/Functional/Handlers/AbstractHandlerProcessTestCase.php +++ b/.vortex/installer/tests/Functional/Handlers/AbstractHandlerProcessTestCase.php @@ -24,6 +24,15 @@ abstract class AbstractHandlerProcessTestCase extends FunctionalTestCase { */ public array $installOptions = []; + /** + * Prompt overrides to pass via --prompts option. + * + * Keyed by handler ID. Set in $before closures. + * + * @var array + */ + public array $prompts = []; + protected function setUp(): void { parent::setUp(); @@ -56,6 +65,10 @@ public function testHandlerProcess( $before($this); } + if (!empty($this->prompts)) { + $this->installOptions[InstallCommand::OPTION_PROMPTS] = json_encode($this->prompts); + } + $this->runNonInteractiveInstall(options: $this->installOptions); $expected = empty($expected) ? ['Welcome to the Vortex non-interactive installer'] : $expected; @@ -85,26 +98,4 @@ protected function assertCommon(): void { $this->assertJsonFileIsValid('composer.json'); } - protected static function defaultAnswers(): array { - return [ - 'namespace' => 'YodasHut', - 'project' => 'force-crystal', - 'author' => 'Luke Skywalker', - 'use_php' => static::TUI_DEFAULT, - 'use_php_command' => static::TUI_DEFAULT, - 'php_command_name' => static::TUI_DEFAULT, - 'use_php_command_build' => static::TUI_DEFAULT, - 'use_php_script' => static::TUI_DEFAULT, - 'use_nodejs' => static::TUI_DEFAULT, - 'use_shell' => static::TUI_DEFAULT, - 'use_release_drafter' => static::TUI_DEFAULT, - 'use_pr_autoassign' => static::TUI_DEFAULT, - 'use_funding' => static::TUI_DEFAULT, - 'use_pr_template' => static::TUI_DEFAULT, - 'use_renovate' => static::TUI_DEFAULT, - 'use_docs' => static::TUI_DEFAULT, - 'remove_self' => static::TUI_DEFAULT, - ]; - } - } diff --git a/.vortex/installer/tests/Functional/Handlers/AiCodeInstructionsHandlerProcessTest.php b/.vortex/installer/tests/Functional/Handlers/AiCodeInstructionsHandlerProcessTest.php index a825221b6..229a58d2a 100644 --- a/.vortex/installer/tests/Functional/Handlers/AiCodeInstructionsHandlerProcessTest.php +++ b/.vortex/installer/tests/Functional/Handlers/AiCodeInstructionsHandlerProcessTest.php @@ -5,8 +5,6 @@ namespace DrevOps\VortexInstaller\Tests\Functional\Handlers; use DrevOps\VortexInstaller\Prompts\Handlers\AiCodeInstructions; -use DrevOps\VortexInstaller\Tests\Functional\FunctionalTestCase; -use DrevOps\VortexInstaller\Utils\Env; use PHPUnit\Framework\Attributes\CoversClass; #[CoversClass(AiCodeInstructions::class)] @@ -14,15 +12,15 @@ class AiCodeInstructionsHandlerProcessTest extends AbstractHandlerProcessTestCas public static function dataProviderHandlerProcess(): \Iterator { yield 'ai_instructions_enabled' => [ - static::cw(fn() => Env::put(AiCodeInstructions::envName(), Env::TRUE)), - static::cw(function (FunctionalTestCase $test): void { + static::cw(fn($test): true => $test->prompts[AiCodeInstructions::id()] = TRUE), + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertFileExists(static::$sut . '/AGENTS.md'); $test->assertFileExists(static::$sut . '/CLAUDE.md'); }), ]; yield 'ai_instructions_disabled' => [ - static::cw(fn() => Env::put(AiCodeInstructions::envName(), Env::FALSE)), - static::cw(function (FunctionalTestCase $test): void { + static::cw(fn($test): false => $test->prompts[AiCodeInstructions::id()] = FALSE), + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertFileDoesNotExist(static::$sut . '/AGENTS.md'); $test->assertFileDoesNotExist(static::$sut . '/CLAUDE.md'); }), diff --git a/.vortex/installer/tests/Functional/Handlers/BaselineHandlerProcessTest.php b/.vortex/installer/tests/Functional/Handlers/BaselineHandlerProcessTest.php index aad001a4d..ddf9eeac7 100644 --- a/.vortex/installer/tests/Functional/Handlers/BaselineHandlerProcessTest.php +++ b/.vortex/installer/tests/Functional/Handlers/BaselineHandlerProcessTest.php @@ -78,27 +78,27 @@ public static function dataProviderHandlerProcess(): \Iterator { ]; yield 'non_interactive_config_file' => [ static::cw(function (AbstractHandlerProcessTestCase $test): void { - $config_file = static::$tmp . DIRECTORY_SEPARATOR . 'config.json'; - File::dump($config_file, (string) json_encode([ + $prompts_file = static::$tmp . DIRECTORY_SEPARATOR . 'prompts.json'; + File::dump($prompts_file, (string) json_encode([ // Test overriding scalar value. - Org::envName() => 'My custom org', + Org::id() => 'My custom org', // Test overriding array value. - Services::envName() => [Services::SOLR, Services::CLAMAV], + Services::id() => [Services::SOLR, Services::CLAMAV], ])); - $test->installOptions['config'] = $config_file; + $test->installOptions['prompts'] = $prompts_file; }), NULL, ['Welcome to the Vortex non-interactive installer'], ]; yield 'non_interactive_config_string' => [ static::cw(function (AbstractHandlerProcessTestCase $test): void { - $config_string = (string) json_encode([ + $prompts_string = (string) json_encode([ // Test overriding scalar value. - Org::envName() => 'My other custom org', + Org::id() => 'My other custom org', // Test overriding array value. - Services::envName() => [Services::SOLR, Services::REDIS], + Services::id() => [Services::SOLR, Services::REDIS], ]); - $test->installOptions['config'] = $config_string; + $test->installOptions['prompts'] = $prompts_string; }), NULL, ['Welcome to the Vortex non-interactive installer'], diff --git a/.vortex/installer/tests/Functional/Handlers/CiProviderHandlerProcessTest.php b/.vortex/installer/tests/Functional/Handlers/CiProviderHandlerProcessTest.php index 9608a56ed..3f2911878 100644 --- a/.vortex/installer/tests/Functional/Handlers/CiProviderHandlerProcessTest.php +++ b/.vortex/installer/tests/Functional/Handlers/CiProviderHandlerProcessTest.php @@ -6,8 +6,6 @@ use DrevOps\VortexInstaller\Prompts\Handlers\AiCodeInstructions; use DrevOps\VortexInstaller\Prompts\Handlers\CiProvider; -use DrevOps\VortexInstaller\Tests\Functional\FunctionalTestCase; -use DrevOps\VortexInstaller\Utils\Env; use PHPUnit\Framework\Attributes\CoversClass; #[CoversClass(CiProvider::class)] @@ -15,21 +13,21 @@ class CiProviderHandlerProcessTest extends AbstractHandlerProcessTestCase { public static function dataProviderHandlerProcess(): \Iterator { yield 'ciprovider_gha' => [ - static::cw(function (): void { - Env::put(CiProvider::envName(), CiProvider::GITHUB_ACTIONS); - Env::put(AiCodeInstructions::envName(), Env::TRUE); + static::cw(function ($test): void { + $test->prompts[CiProvider::id()] = CiProvider::GITHUB_ACTIONS; + $test->prompts[AiCodeInstructions::id()] = TRUE; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertFileNotContainsString(static::$sut . '/.github/workflows/build-test-deploy.yml', '1.x'); $test->assertFileNotContainsString(static::$sut . '/.github/workflows/build-test-deploy.yml', '2.x'); }), ]; yield 'ciprovider_circleci' => [ - static::cw(function (): void { - Env::put(CiProvider::envName(), CiProvider::CIRCLECI); - Env::put(AiCodeInstructions::envName(), Env::TRUE); + static::cw(function ($test): void { + $test->prompts[CiProvider::id()] = CiProvider::CIRCLECI; + $test->prompts[AiCodeInstructions::id()] = TRUE; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertFileNotContainsString(static::$sut . '/.circleci/config.yml', '1.x'); $test->assertFileNotContainsString(static::$sut . '/.circleci/config.yml', '2.x'); }), diff --git a/.vortex/installer/tests/Functional/Handlers/CodeProviderHandlerProcessTest.php b/.vortex/installer/tests/Functional/Handlers/CodeProviderHandlerProcessTest.php index 7eecdb011..8a2230940 100644 --- a/.vortex/installer/tests/Functional/Handlers/CodeProviderHandlerProcessTest.php +++ b/.vortex/installer/tests/Functional/Handlers/CodeProviderHandlerProcessTest.php @@ -5,8 +5,6 @@ namespace DrevOps\VortexInstaller\Tests\Functional\Handlers; use DrevOps\VortexInstaller\Prompts\Handlers\CodeProvider; -use DrevOps\VortexInstaller\Tests\Functional\FunctionalTestCase; -use DrevOps\VortexInstaller\Utils\Env; use PHPUnit\Framework\Attributes\CoversClass; #[CoversClass(CodeProvider::class)] @@ -14,15 +12,15 @@ class CodeProviderHandlerProcessTest extends AbstractHandlerProcessTestCase { public static function dataProviderHandlerProcess(): \Iterator { yield 'code_provider_github' => [ - static::cw(fn() => Env::put(CodeProvider::envName(), CodeProvider::GITHUB)), - static::cw(function (FunctionalTestCase $test): void { + static::cw(fn($test): string => $test->prompts[CodeProvider::id()] = CodeProvider::GITHUB), + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertFileDoesNotExist(static::$sut . '/.github/PULL_REQUEST_TEMPLATE.dist.md'); $test->assertFileContainsString(static::$sut . '/.github/PULL_REQUEST_TEMPLATE.md', 'Checklist before requesting a review'); }), ]; yield 'code_provider_other' => [ - static::cw(fn() => Env::put(CodeProvider::envName(), CodeProvider::OTHER)), - static::cw(function (FunctionalTestCase $test): void { + static::cw(fn($test): string => $test->prompts[CodeProvider::id()] = CodeProvider::OTHER), + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertDirectoryDoesNotExist(static::$sut . '/.github'); }), ]; diff --git a/.vortex/installer/tests/Functional/Handlers/CustomModulesHandlerProcessTest.php b/.vortex/installer/tests/Functional/Handlers/CustomModulesHandlerProcessTest.php index a31faf02b..36d902db9 100644 --- a/.vortex/installer/tests/Functional/Handlers/CustomModulesHandlerProcessTest.php +++ b/.vortex/installer/tests/Functional/Handlers/CustomModulesHandlerProcessTest.php @@ -8,8 +8,6 @@ use DrevOps\VortexInstaller\Prompts\Handlers\CustomModules; use DrevOps\VortexInstaller\Prompts\Handlers\Services; use DrevOps\VortexInstaller\Tests\Functional\FunctionalTestCase; -use DrevOps\VortexInstaller\Utils\Converter; -use DrevOps\VortexInstaller\Utils\Env; use PHPUnit\Framework\Attributes\CoversClass; #[CoversClass(CustomModules::class)] @@ -17,44 +15,44 @@ class CustomModulesHandlerProcessTest extends AbstractHandlerProcessTestCase { public static function dataProviderHandlerProcess(): \Iterator { yield 'custom_modules_no_base' => [ - static::cw(function (): void { - Env::put(CustomModules::envName(), Converter::toList([CustomModules::SEARCH, CustomModules::DEMO])); - Env::put(AiCodeInstructions::envName(), Env::TRUE); + static::cw(function ($test): void { + $test->prompts[CustomModules::id()] = [CustomModules::SEARCH, CustomModules::DEMO]; + $test->prompts[AiCodeInstructions::id()] = TRUE; }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains('_base')), ]; yield 'custom_modules_no_demo' => [ - static::cw(function (): void { - Env::put(CustomModules::envName(), Converter::toList([CustomModules::BASE, CustomModules::SEARCH])); - Env::put(AiCodeInstructions::envName(), Env::TRUE); + static::cw(function ($test): void { + $test->prompts[CustomModules::id()] = [CustomModules::BASE, CustomModules::SEARCH]; + $test->prompts[AiCodeInstructions::id()] = TRUE; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertSutNotContains('_demo'); $test->assertSutNotContains('counter_block'); }), ]; yield 'custom_modules_no_search' => [ - static::cw(function (): void { - Env::put(CustomModules::envName(), Converter::toList([CustomModules::BASE, CustomModules::DEMO])); - Env::put(AiCodeInstructions::envName(), Env::TRUE); + static::cw(function ($test): void { + $test->prompts[CustomModules::id()] = [CustomModules::BASE, CustomModules::DEMO]; + $test->prompts[AiCodeInstructions::id()] = TRUE; }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains('_search')), ]; yield 'custom_modules_none' => [ - static::cw(fn() => Env::put(CustomModules::envName(), ',')), - static::cw(function (FunctionalTestCase $test): void { + static::cw(fn($test): array => $test->prompts[CustomModules::id()] = []), + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertSutNotContains('_base'); $test->assertSutNotContains('_demo'); $test->assertSutNotContains('_search'); }), ]; yield 'custom_modules_search_without_solr' => [ - static::cw(function (): void { + static::cw(function ($test): void { // Search module selected but Solr service deselected - safety net // should force-remove search module. - Env::put(CustomModules::envName(), Converter::toList([CustomModules::BASE, CustomModules::SEARCH, CustomModules::DEMO])); - Env::put(Services::envName(), Converter::toList([Services::CLAMAV, Services::REDIS])); - Env::put(AiCodeInstructions::envName(), Env::TRUE); + $test->prompts[CustomModules::id()] = [CustomModules::BASE, CustomModules::SEARCH, CustomModules::DEMO]; + $test->prompts[Services::id()] = [Services::CLAMAV, Services::REDIS]; + $test->prompts[AiCodeInstructions::id()] = TRUE; }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains('_search')), ]; diff --git a/.vortex/installer/tests/Functional/Handlers/DatabaseDownloadSourceHandlerProcessTest.php b/.vortex/installer/tests/Functional/Handlers/DatabaseDownloadSourceHandlerProcessTest.php index 93efaca0b..d98482fa8 100644 --- a/.vortex/installer/tests/Functional/Handlers/DatabaseDownloadSourceHandlerProcessTest.php +++ b/.vortex/installer/tests/Functional/Handlers/DatabaseDownloadSourceHandlerProcessTest.php @@ -7,7 +7,6 @@ use DrevOps\VortexInstaller\Prompts\Handlers\AiCodeInstructions; use DrevOps\VortexInstaller\Prompts\Handlers\DatabaseDownloadSource; use DrevOps\VortexInstaller\Prompts\Handlers\DatabaseImage; -use DrevOps\VortexInstaller\Utils\Env; use PHPUnit\Framework\Attributes\CoversClass; #[CoversClass(DatabaseDownloadSource::class)] @@ -16,26 +15,26 @@ class DatabaseDownloadSourceHandlerProcessTest extends AbstractHandlerProcessTes public static function dataProviderHandlerProcess(): \Iterator { yield 'db_download_source_url' => [ - static::cw(fn() => Env::put(DatabaseDownloadSource::envName(), DatabaseDownloadSource::URL)), + static::cw(fn($test): string => $test->prompts[DatabaseDownloadSource::id()] = DatabaseDownloadSource::URL), ]; yield 'db_download_source_ftp' => [ - static::cw(fn() => Env::put(DatabaseDownloadSource::envName(), DatabaseDownloadSource::FTP)), + static::cw(fn($test): string => $test->prompts[DatabaseDownloadSource::id()] = DatabaseDownloadSource::FTP), ]; yield 'db_download_source_acquia' => [ - static::cw(fn() => Env::put(DatabaseDownloadSource::envName(), DatabaseDownloadSource::ACQUIA)), + static::cw(fn($test): string => $test->prompts[DatabaseDownloadSource::id()] = DatabaseDownloadSource::ACQUIA), ]; yield 'db_download_source_lagoon' => [ - static::cw(fn() => Env::put(DatabaseDownloadSource::envName(), DatabaseDownloadSource::LAGOON)), + static::cw(fn($test): string => $test->prompts[DatabaseDownloadSource::id()] = DatabaseDownloadSource::LAGOON), ]; yield 'db_download_source_container_registry' => [ - static::cw(function (): void { - Env::put(DatabaseDownloadSource::envName(), DatabaseDownloadSource::CONTAINER_REGISTRY); - Env::put(DatabaseImage::envName(), 'the_empire/star_wars:latest'); - Env::put(AiCodeInstructions::envName(), Env::TRUE); + static::cw(function ($test): void { + $test->prompts[DatabaseDownloadSource::id()] = DatabaseDownloadSource::CONTAINER_REGISTRY; + $test->prompts[DatabaseImage::id()] = 'the_empire/star_wars:latest'; + $test->prompts[AiCodeInstructions::id()] = TRUE; }), ]; yield 'db_download_source_s3' => [ - static::cw(fn() => Env::put(DatabaseDownloadSource::envName(), DatabaseDownloadSource::S3)), + static::cw(fn($test): string => $test->prompts[DatabaseDownloadSource::id()] = DatabaseDownloadSource::S3), ]; } diff --git a/.vortex/installer/tests/Functional/Handlers/DependencyUpdatesProviderHandlerProcessTest.php b/.vortex/installer/tests/Functional/Handlers/DependencyUpdatesProviderHandlerProcessTest.php index d8ff84f3b..ff3dcda7b 100644 --- a/.vortex/installer/tests/Functional/Handlers/DependencyUpdatesProviderHandlerProcessTest.php +++ b/.vortex/installer/tests/Functional/Handlers/DependencyUpdatesProviderHandlerProcessTest.php @@ -6,7 +6,6 @@ use DrevOps\VortexInstaller\Prompts\Handlers\CiProvider; use DrevOps\VortexInstaller\Prompts\Handlers\DependencyUpdatesProvider; -use DrevOps\VortexInstaller\Utils\Env; use PHPUnit\Framework\Attributes\CoversClass; #[CoversClass(DependencyUpdatesProvider::class)] @@ -14,19 +13,19 @@ class DependencyUpdatesProviderHandlerProcessTest extends AbstractHandlerProcess public static function dataProviderHandlerProcess(): \Iterator { yield 'deps_updates_provider_ci_gha' => [ - static::cw(fn() => Env::put(DependencyUpdatesProvider::envName(), DependencyUpdatesProvider::RENOVATEBOT_CI)), + static::cw(fn($test): string => $test->prompts[DependencyUpdatesProvider::id()] = DependencyUpdatesProvider::RENOVATEBOT_CI), ]; yield 'deps_updates_provider_ci_circleci' => [ - static::cw(function (): void { - Env::put(DependencyUpdatesProvider::envName(), DependencyUpdatesProvider::RENOVATEBOT_CI); - Env::put(CiProvider::envName(), CiProvider::CIRCLECI); + static::cw(function ($test): void { + $test->prompts[DependencyUpdatesProvider::id()] = DependencyUpdatesProvider::RENOVATEBOT_CI; + $test->prompts[CiProvider::id()] = CiProvider::CIRCLECI; }), ]; yield 'deps_updates_provider_app' => [ - static::cw(fn() => Env::put(DependencyUpdatesProvider::envName(), DependencyUpdatesProvider::RENOVATEBOT_APP)), + static::cw(fn($test): string => $test->prompts[DependencyUpdatesProvider::id()] = DependencyUpdatesProvider::RENOVATEBOT_APP), ]; yield 'deps_updates_provider_none' => [ - static::cw(fn() => Env::put(DependencyUpdatesProvider::envName(), DependencyUpdatesProvider::NONE)), + static::cw(fn($test): string => $test->prompts[DependencyUpdatesProvider::id()] = DependencyUpdatesProvider::NONE), ]; } diff --git a/.vortex/installer/tests/Functional/Handlers/DeployTypeHandlerProcessTest.php b/.vortex/installer/tests/Functional/Handlers/DeployTypeHandlerProcessTest.php index 54e5fdaba..14925b6a7 100644 --- a/.vortex/installer/tests/Functional/Handlers/DeployTypeHandlerProcessTest.php +++ b/.vortex/installer/tests/Functional/Handlers/DeployTypeHandlerProcessTest.php @@ -6,8 +6,6 @@ use DrevOps\VortexInstaller\Prompts\Handlers\CiProvider; use DrevOps\VortexInstaller\Prompts\Handlers\DeployTypes; -use DrevOps\VortexInstaller\Utils\Converter; -use DrevOps\VortexInstaller\Utils\Env; use PHPUnit\Framework\Attributes\CoversClass; #[CoversClass(DeployTypes::class)] @@ -15,33 +13,33 @@ class DeployTypeHandlerProcessTest extends AbstractHandlerProcessTestCase { public static function dataProviderHandlerProcess(): \Iterator { yield 'deploy_types_artifact' => [ - static::cw(fn() => Env::put(DeployTypes::envName(), Converter::toList([DeployTypes::ARTIFACT], ',', TRUE))), + static::cw(fn($test): array => $test->prompts[DeployTypes::id()] = [DeployTypes::ARTIFACT]), ]; yield 'deploy_types_lagoon' => [ - static::cw(fn() => Env::put(DeployTypes::envName(), Converter::toList([DeployTypes::LAGOON], ',', TRUE))), + static::cw(fn($test): array => $test->prompts[DeployTypes::id()] = [DeployTypes::LAGOON]), ]; yield 'deploy_types_container_image' => [ - static::cw(fn() => Env::put(DeployTypes::envName(), Converter::toList([DeployTypes::CONTAINER_IMAGE], ',', TRUE))), + static::cw(fn($test): array => $test->prompts[DeployTypes::id()] = [DeployTypes::CONTAINER_IMAGE]), ]; yield 'deploy_types_webhook' => [ - static::cw(fn() => Env::put(DeployTypes::envName(), Converter::toList([DeployTypes::WEBHOOK], ',', TRUE))), + static::cw(fn($test): array => $test->prompts[DeployTypes::id()] = [DeployTypes::WEBHOOK]), ]; yield 'deploy_types_all_gha' => [ - static::cw(fn() => Env::put(DeployTypes::envName(), Converter::toList([DeployTypes::WEBHOOK, DeployTypes::CONTAINER_IMAGE, DeployTypes::LAGOON, DeployTypes::ARTIFACT]))), + static::cw(fn($test): array => $test->prompts[DeployTypes::id()] = [DeployTypes::WEBHOOK, DeployTypes::CONTAINER_IMAGE, DeployTypes::LAGOON, DeployTypes::ARTIFACT]), ]; yield 'deploy_types_all_circleci' => [ - static::cw(function (): void { - Env::put(DeployTypes::envName(), Converter::toList([DeployTypes::WEBHOOK, DeployTypes::CONTAINER_IMAGE, DeployTypes::LAGOON, DeployTypes::ARTIFACT])); - Env::put(CiProvider::envName(), CiProvider::CIRCLECI); + static::cw(function ($test): void { + $test->prompts[DeployTypes::id()] = [DeployTypes::WEBHOOK, DeployTypes::CONTAINER_IMAGE, DeployTypes::LAGOON, DeployTypes::ARTIFACT]; + $test->prompts[CiProvider::id()] = CiProvider::CIRCLECI; }), ]; yield 'deploy_types_none_gha' => [ - static::cw(fn() => Env::put(DeployTypes::envName(), ',')), + static::cw(fn($test): array => $test->prompts[DeployTypes::id()] = []), ]; yield 'deploy_types_none_circleci' => [ - static::cw(function (): void { - Env::put(DeployTypes::envName(), ','); - Env::put(CiProvider::envName(), CiProvider::CIRCLECI); + static::cw(function ($test): void { + $test->prompts[DeployTypes::id()] = []; + $test->prompts[CiProvider::id()] = CiProvider::CIRCLECI; }), ]; } diff --git a/.vortex/installer/tests/Functional/Handlers/DocsHandlerProcessTest.php b/.vortex/installer/tests/Functional/Handlers/DocsHandlerProcessTest.php index 020351493..6e2f8ce27 100644 --- a/.vortex/installer/tests/Functional/Handlers/DocsHandlerProcessTest.php +++ b/.vortex/installer/tests/Functional/Handlers/DocsHandlerProcessTest.php @@ -5,7 +5,6 @@ namespace DrevOps\VortexInstaller\Tests\Functional\Handlers; use DrevOps\VortexInstaller\Prompts\Handlers\PreserveDocsProject; -use DrevOps\VortexInstaller\Utils\Env; use PHPUnit\Framework\Attributes\CoversClass; #[CoversClass(PreserveDocsProject::class)] @@ -13,10 +12,10 @@ class DocsHandlerProcessTest extends AbstractHandlerProcessTestCase { public static function dataProviderHandlerProcess(): \Iterator { yield 'preserve_docs_project_enabled' => [ - static::cw(fn() => Env::put(PreserveDocsProject::envName(), Env::TRUE)), + static::cw(fn($test): true => $test->prompts[PreserveDocsProject::id()] = TRUE), ]; yield 'preserve_docs_project_disabled' => [ - static::cw(fn() => Env::put(PreserveDocsProject::envName(), Env::FALSE)), + static::cw(fn($test): false => $test->prompts[PreserveDocsProject::id()] = FALSE), ]; } diff --git a/.vortex/installer/tests/Functional/Handlers/HostingProjectNameHandlerProcessTest.php b/.vortex/installer/tests/Functional/Handlers/HostingProjectNameHandlerProcessTest.php index 8e5ae2afa..43088eaea 100644 --- a/.vortex/installer/tests/Functional/Handlers/HostingProjectNameHandlerProcessTest.php +++ b/.vortex/installer/tests/Functional/Handlers/HostingProjectNameHandlerProcessTest.php @@ -6,8 +6,6 @@ use DrevOps\VortexInstaller\Prompts\Handlers\HostingProvider; use DrevOps\VortexInstaller\Prompts\Handlers\HostingProjectName; -use DrevOps\VortexInstaller\Tests\Functional\FunctionalTestCase; -use DrevOps\VortexInstaller\Utils\Env; use PHPUnit\Framework\Attributes\CoversClass; #[CoversClass(HostingProjectName::class)] @@ -15,22 +13,22 @@ class HostingProjectNameHandlerProcessTest extends AbstractHandlerProcessTestCas public static function dataProviderHandlerProcess(): \Iterator { yield 'hosting_project_name___acquia' => [ - static::cw(function (): void { - Env::put(HostingProvider::envName(), HostingProvider::ACQUIA); - Env::put(HostingProjectName::envName(), 'my_custom_acquia-project'); + static::cw(function ($test): void { + $test->prompts[HostingProvider::id()] = HostingProvider::ACQUIA; + $test->prompts[HostingProjectName::id()] = 'my_custom_acquia-project'; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertSutContains([ 'VORTEX_ACQUIA_APP_NAME=my_custom_acquia-project', ]); }), ]; yield 'hosting_project_name___lagoon' => [ - static::cw(function (): void { - Env::put(HostingProvider::envName(), HostingProvider::LAGOON); - Env::put(HostingProjectName::envName(), 'my_custom_lagoon-project'); + static::cw(function ($test): void { + $test->prompts[HostingProvider::id()] = HostingProvider::LAGOON; + $test->prompts[HostingProjectName::id()] = 'my_custom_lagoon-project'; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertSutContains([ 'LAGOON_PROJECT=my_custom_lagoon-project', '/my_custom_lagoon-project-\$\{env-name\}/', diff --git a/.vortex/installer/tests/Functional/Handlers/HostingProviderHandlerProcessTest.php b/.vortex/installer/tests/Functional/Handlers/HostingProviderHandlerProcessTest.php index a956a542d..cdd9618ec 100644 --- a/.vortex/installer/tests/Functional/Handlers/HostingProviderHandlerProcessTest.php +++ b/.vortex/installer/tests/Functional/Handlers/HostingProviderHandlerProcessTest.php @@ -7,7 +7,6 @@ use DrevOps\VortexInstaller\Prompts\Handlers\AiCodeInstructions; use DrevOps\VortexInstaller\Prompts\Handlers\HostingProvider; use DrevOps\VortexInstaller\Tests\Functional\FunctionalTestCase; -use DrevOps\VortexInstaller\Utils\Env; use PHPUnit\Framework\Attributes\CoversClass; #[CoversClass(HostingProvider::class)] @@ -15,15 +14,18 @@ class HostingProviderHandlerProcessTest extends AbstractHandlerProcessTestCase { public static function dataProviderHandlerProcess(): \Iterator { yield 'hosting_acquia' => [ - static::cw(function (): void { - Env::put(HostingProvider::envName(), HostingProvider::ACQUIA); - Env::put(AiCodeInstructions::envName(), Env::TRUE); + static::cw(function ($test): void { + $test->prompts[HostingProvider::id()] = HostingProvider::ACQUIA; + $test->prompts[AiCodeInstructions::id()] = TRUE; }), + // Cannot assert for the full absence of 'lagoon' since we use Lagoon + // images for local and CI even with Acquia. + static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains('lagoon_')), ]; yield 'hosting_lagoon' => [ - static::cw(function (): void { - Env::put(HostingProvider::envName(), HostingProvider::LAGOON); - Env::put(AiCodeInstructions::envName(), Env::TRUE); + static::cw(function ($test): void { + $test->prompts[HostingProvider::id()] = HostingProvider::LAGOON; + $test->prompts[AiCodeInstructions::id()] = TRUE; }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains('acquia')), ]; diff --git a/.vortex/installer/tests/Functional/Handlers/MigrationDownloadSourceHandlerProcessTest.php b/.vortex/installer/tests/Functional/Handlers/MigrationDownloadSourceHandlerProcessTest.php index 794529147..e167c133d 100644 --- a/.vortex/installer/tests/Functional/Handlers/MigrationDownloadSourceHandlerProcessTest.php +++ b/.vortex/installer/tests/Functional/Handlers/MigrationDownloadSourceHandlerProcessTest.php @@ -7,8 +7,6 @@ use DrevOps\VortexInstaller\Prompts\Handlers\Migration; use DrevOps\VortexInstaller\Prompts\Handlers\MigrationDownloadSource; use DrevOps\VortexInstaller\Prompts\Handlers\MigrationImage; -use DrevOps\VortexInstaller\Tests\Functional\FunctionalTestCase; -use DrevOps\VortexInstaller\Utils\Env; use PHPUnit\Framework\Attributes\CoversClass; #[CoversClass(MigrationDownloadSource::class)] @@ -16,11 +14,11 @@ class MigrationDownloadSourceHandlerProcessTest extends AbstractHandlerProcessTe public static function dataProviderHandlerProcess(): \Iterator { yield 'migration_download_source_url' => [ - static::cw(function (): void { - Env::put(Migration::envName(), Env::TRUE); - Env::put(MigrationDownloadSource::envName(), MigrationDownloadSource::URL); + static::cw(function ($test): void { + $test->prompts[Migration::id()] = TRUE; + $test->prompts[MigrationDownloadSource::id()] = MigrationDownloadSource::URL; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertFileContainsString(static::$sut . '/.env', 'VORTEX_DOWNLOAD_DB2_SOURCE=url'); $test->assertFileContainsString(static::$sut . '/.env', 'VORTEX_DOWNLOAD_DB2_URL='); $test->assertFileNotContainsString(static::$sut . '/.env', 'VORTEX_DOWNLOAD_DB2_FTP_HOST'); @@ -28,11 +26,11 @@ public static function dataProviderHandlerProcess(): \Iterator { }), ]; yield 'migration_download_source_ftp' => [ - static::cw(function (): void { - Env::put(Migration::envName(), Env::TRUE); - Env::put(MigrationDownloadSource::envName(), MigrationDownloadSource::FTP); + static::cw(function ($test): void { + $test->prompts[Migration::id()] = TRUE; + $test->prompts[MigrationDownloadSource::id()] = MigrationDownloadSource::FTP; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertFileContainsString(static::$sut . '/.env', 'VORTEX_DOWNLOAD_DB2_SOURCE=ftp'); $test->assertFileContainsString(static::$sut . '/.env', 'VORTEX_DOWNLOAD_DB2_FTP_HOST'); $test->assertFileNotContainsString(static::$sut . '/.env', 'VORTEX_DOWNLOAD_DB2_URL='); @@ -40,11 +38,11 @@ public static function dataProviderHandlerProcess(): \Iterator { }), ]; yield 'migration_download_source_acquia' => [ - static::cw(function (): void { - Env::put(Migration::envName(), Env::TRUE); - Env::put(MigrationDownloadSource::envName(), MigrationDownloadSource::ACQUIA); + static::cw(function ($test): void { + $test->prompts[Migration::id()] = TRUE; + $test->prompts[MigrationDownloadSource::id()] = MigrationDownloadSource::ACQUIA; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertFileContainsString(static::$sut . '/.env', 'VORTEX_DOWNLOAD_DB2_SOURCE=acquia'); $test->assertFileNotContainsString(static::$sut . '/.env', 'VORTEX_DOWNLOAD_DB2_URL='); $test->assertFileNotContainsString(static::$sut . '/.env', 'VORTEX_DOWNLOAD_DB2_FTP_HOST'); @@ -52,11 +50,11 @@ public static function dataProviderHandlerProcess(): \Iterator { }), ]; yield 'migration_download_source_lagoon' => [ - static::cw(function (): void { - Env::put(Migration::envName(), Env::TRUE); - Env::put(MigrationDownloadSource::envName(), MigrationDownloadSource::LAGOON); + static::cw(function ($test): void { + $test->prompts[Migration::id()] = TRUE; + $test->prompts[MigrationDownloadSource::id()] = MigrationDownloadSource::LAGOON; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertFileContainsString(static::$sut . '/.env', 'VORTEX_DOWNLOAD_DB2_SOURCE=lagoon'); $test->assertFileNotContainsString(static::$sut . '/.env', 'VORTEX_DOWNLOAD_DB2_URL='); $test->assertFileNotContainsString(static::$sut . '/.env', 'VORTEX_DOWNLOAD_DB2_FTP_HOST'); @@ -64,11 +62,11 @@ public static function dataProviderHandlerProcess(): \Iterator { }), ]; yield 'migration_download_source_s3' => [ - static::cw(function (): void { - Env::put(Migration::envName(), Env::TRUE); - Env::put(MigrationDownloadSource::envName(), MigrationDownloadSource::S3); + static::cw(function ($test): void { + $test->prompts[Migration::id()] = TRUE; + $test->prompts[MigrationDownloadSource::id()] = MigrationDownloadSource::S3; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertFileContainsString(static::$sut . '/.env', 'VORTEX_DOWNLOAD_DB2_SOURCE=s3'); $test->assertFileContainsString(static::$sut . '/.env', 'VORTEX_DOWNLOAD_DB2_S3_BUCKET'); $test->assertFileNotContainsString(static::$sut . '/.env', 'VORTEX_DOWNLOAD_DB2_URL='); @@ -76,12 +74,12 @@ public static function dataProviderHandlerProcess(): \Iterator { }), ]; yield 'migration_download_source_container_registry' => [ - static::cw(function (): void { - Env::put(Migration::envName(), Env::TRUE); - Env::put(MigrationDownloadSource::envName(), MigrationDownloadSource::CONTAINER_REGISTRY); - Env::put(MigrationImage::envName(), 'the_empire/star_wars-migration:latest'); + static::cw(function ($test): void { + $test->prompts[Migration::id()] = TRUE; + $test->prompts[MigrationDownloadSource::id()] = MigrationDownloadSource::CONTAINER_REGISTRY; + $test->prompts[MigrationImage::id()] = 'the_empire/star_wars-migration:latest'; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertFileContainsString(static::$sut . '/.env', 'VORTEX_DOWNLOAD_DB2_SOURCE=container_registry'); $test->assertFileContainsString(static::$sut . '/.env', 'VORTEX_DB2_IMAGE=the_empire/star_wars-migration:latest'); $test->assertFileNotContainsString(static::$sut . '/.env', 'VORTEX_DOWNLOAD_DB2_URL='); diff --git a/.vortex/installer/tests/Functional/Handlers/MigrationHandlerProcessTest.php b/.vortex/installer/tests/Functional/Handlers/MigrationHandlerProcessTest.php index 6761a3535..04ca6c13a 100644 --- a/.vortex/installer/tests/Functional/Handlers/MigrationHandlerProcessTest.php +++ b/.vortex/installer/tests/Functional/Handlers/MigrationHandlerProcessTest.php @@ -7,8 +7,6 @@ use DrevOps\VortexInstaller\Prompts\Handlers\CiProvider; use DrevOps\VortexInstaller\Prompts\Handlers\HostingProvider; use DrevOps\VortexInstaller\Prompts\Handlers\Migration; -use DrevOps\VortexInstaller\Tests\Functional\FunctionalTestCase; -use DrevOps\VortexInstaller\Utils\Env; use PHPUnit\Framework\Attributes\CoversClass; #[CoversClass(Migration::class)] @@ -16,8 +14,8 @@ class MigrationHandlerProcessTest extends AbstractHandlerProcessTestCase { public static function dataProviderHandlerProcess(): \Iterator { yield 'migration_enabled' => [ - static::cw(fn() => Env::put(Migration::envName(), Env::TRUE)), - static::cw(function (FunctionalTestCase $test): void { + static::cw(fn($test): true => $test->prompts[Migration::id()] = TRUE), + static::cw(function (AbstractHandlerProcessTestCase $test): void { // Files and directories created by the handler. $test->assertFileExists(static::$sut . '/web/sites/default/settings.migration.php'); $test->assertFileExists(static::$sut . '/scripts/custom/provision-20-migration.sh'); @@ -38,11 +36,11 @@ public static function dataProviderHandlerProcess(): \Iterator { }), ]; yield 'migration_enabled_circleci' => [ - static::cw(function (): void { - Env::put(Migration::envName(), Env::TRUE); - Env::put(CiProvider::envName(), CiProvider::CIRCLECI); + static::cw(function ($test): void { + $test->prompts[Migration::id()] = TRUE; + $test->prompts[CiProvider::id()] = CiProvider::CIRCLECI; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertFileExists(static::$sut . '/web/sites/default/settings.migration.php'); $test->assertFileExists(static::$sut . '/scripts/custom/provision-20-migration.sh'); $test->assertDirectoryExists(static::$sut . '/web/modules/custom/ys_migrate'); @@ -52,8 +50,8 @@ public static function dataProviderHandlerProcess(): \Iterator { }), ]; yield 'migration_disabled' => [ - static::cw(fn() => Env::put(Migration::envName(), Env::FALSE)), - static::cw(function (FunctionalTestCase $test): void { + static::cw(fn($test): false => $test->prompts[Migration::id()] = FALSE), + static::cw(function (AbstractHandlerProcessTestCase $test): void { // Files and directories removed by the handler. $test->assertFileDoesNotExist(static::$sut . '/web/sites/default/settings.migration.php'); $test->assertFileDoesNotExist(static::$sut . '/scripts/custom/provision-20-migration.sh'); @@ -74,11 +72,11 @@ public static function dataProviderHandlerProcess(): \Iterator { }), ]; yield 'migration_disabled_circleci' => [ - static::cw(function (): void { - Env::put(Migration::envName(), Env::FALSE); - Env::put(CiProvider::envName(), CiProvider::CIRCLECI); + static::cw(function ($test): void { + $test->prompts[Migration::id()] = FALSE; + $test->prompts[CiProvider::id()] = CiProvider::CIRCLECI; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertFileDoesNotExist(static::$sut . '/web/sites/default/settings.migration.php'); $test->assertFileDoesNotExist(static::$sut . '/scripts/custom/provision-20-migration.sh'); $test->assertDirectoryDoesNotExist(static::$sut . '/web/modules/custom/ys_migrate'); @@ -88,11 +86,11 @@ public static function dataProviderHandlerProcess(): \Iterator { }), ]; yield 'migration_enabled_lagoon' => [ - static::cw(function (): void { - Env::put(Migration::envName(), Env::TRUE); - Env::put(HostingProvider::envName(), HostingProvider::LAGOON); + static::cw(function ($test): void { + $test->prompts[Migration::id()] = TRUE; + $test->prompts[HostingProvider::id()] = HostingProvider::LAGOON; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertFileExists(static::$sut . '/web/sites/default/settings.migration.php'); $test->assertFileExists(static::$sut . '/scripts/custom/provision-20-migration.sh'); $test->assertDirectoryExists(static::$sut . '/web/modules/custom/ys_migrate'); @@ -102,11 +100,11 @@ public static function dataProviderHandlerProcess(): \Iterator { }), ]; yield 'migration_disabled_lagoon' => [ - static::cw(function (): void { - Env::put(Migration::envName(), Env::FALSE); - Env::put(HostingProvider::envName(), HostingProvider::LAGOON); + static::cw(function ($test): void { + $test->prompts[Migration::id()] = FALSE; + $test->prompts[HostingProvider::id()] = HostingProvider::LAGOON; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertFileDoesNotExist(static::$sut . '/web/sites/default/settings.migration.php'); $test->assertFileDoesNotExist(static::$sut . '/scripts/custom/provision-20-migration.sh'); $test->assertDirectoryDoesNotExist(static::$sut . '/web/modules/custom/ys_migrate'); diff --git a/.vortex/installer/tests/Functional/Handlers/ModulesHandlerProcessTest.php b/.vortex/installer/tests/Functional/Handlers/ModulesHandlerProcessTest.php index 2411be7d9..2b6052810 100644 --- a/.vortex/installer/tests/Functional/Handlers/ModulesHandlerProcessTest.php +++ b/.vortex/installer/tests/Functional/Handlers/ModulesHandlerProcessTest.php @@ -6,8 +6,6 @@ use DrevOps\VortexInstaller\Prompts\Handlers\Modules; use DrevOps\VortexInstaller\Tests\Functional\FunctionalTestCase; -use DrevOps\VortexInstaller\Utils\Converter; -use DrevOps\VortexInstaller\Utils\Env; use PHPUnit\Framework\Attributes\CoversClass; #[CoversClass(Modules::class)] @@ -15,86 +13,74 @@ class ModulesHandlerProcessTest extends AbstractHandlerProcessTestCase { public static function dataProviderHandlerProcess(): \Iterator { yield 'modules_no_admin_toolbar' => [ - static::cw(function (): void { - $selected_modules = static::getModulesExcept('admin_toolbar'); - Env::put(Modules::envName(), Converter::toList($selected_modules)); + static::cw(function ($test): void { + $test->prompts[Modules::id()] = static::getModulesExcept('admin_toolbar'); }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains('drupal/admin_toolbar')), ]; yield 'modules_no_coffee' => [ - static::cw(function (): void { - $selected_modules = static::getModulesExcept('coffee'); - Env::put(Modules::envName(), Converter::toList($selected_modules)); + static::cw(function ($test): void { + $test->prompts[Modules::id()] = static::getModulesExcept('coffee'); }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains('coffee')), ]; yield 'modules_no_config_split' => [ - static::cw(function (): void { - $selected_modules = static::getModulesExcept('config_split'); - Env::put(Modules::envName(), Converter::toList($selected_modules)); + static::cw(function ($test): void { + $test->prompts[Modules::id()] = static::getModulesExcept('config_split'); }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains('config_split')), ]; yield 'modules_no_config_update' => [ - static::cw(function (): void { - $selected_modules = static::getModulesExcept('config_update'); - Env::put(Modules::envName(), Converter::toList($selected_modules)); + static::cw(function ($test): void { + $test->prompts[Modules::id()] = static::getModulesExcept('config_update'); }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains('config_update')), ]; yield 'modules_no_environment_indicator' => [ - static::cw(function (): void { - $selected_modules = static::getModulesExcept('environment_indicator'); - Env::put(Modules::envName(), Converter::toList($selected_modules)); + static::cw(function ($test): void { + $test->prompts[Modules::id()] = static::getModulesExcept('environment_indicator'); }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains('environment_indicator')), ]; yield 'modules_no_pathauto' => [ - static::cw(function (): void { - $selected_modules = static::getModulesExcept('pathauto'); - Env::put(Modules::envName(), Converter::toList($selected_modules)); + static::cw(function ($test): void { + $test->prompts[Modules::id()] = static::getModulesExcept('pathauto'); }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains('drupal/pathauto')), ]; yield 'modules_no_redirect' => [ - static::cw(function (): void { - $selected_modules = static::getModulesExcept('redirect'); - Env::put(Modules::envName(), Converter::toList($selected_modules)); + static::cw(function ($test): void { + $test->prompts[Modules::id()] = static::getModulesExcept('redirect'); }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains('drupal/redirect')), ]; yield 'modules_no_robotstxt' => [ - static::cw(function (): void { - $selected_modules = static::getModulesExcept('robotstxt'); - Env::put(Modules::envName(), Converter::toList($selected_modules)); + static::cw(function ($test): void { + $test->prompts[Modules::id()] = static::getModulesExcept('robotstxt'); }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains('robotstxt')), ]; yield 'modules_no_seckit' => [ - static::cw(function (): void { - $selected_modules = static::getModulesExcept('seckit'); - Env::put(Modules::envName(), Converter::toList($selected_modules)); + static::cw(function ($test): void { + $test->prompts[Modules::id()] = static::getModulesExcept('seckit'); }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains('seckit')), ]; yield 'modules_no_shield' => [ - static::cw(function (): void { - $selected_modules = static::getModulesExcept('shield'); - Env::put(Modules::envName(), Converter::toList($selected_modules)); + static::cw(function ($test): void { + $test->prompts[Modules::id()] = static::getModulesExcept('shield'); }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains('shield')), ]; yield 'modules_no_stage_file_proxy' => [ - static::cw(function (): void { - $selected_modules = static::getModulesExcept('stage_file_proxy'); - Env::put(Modules::envName(), Converter::toList($selected_modules)); + static::cw(function ($test): void { + $test->prompts[Modules::id()] = static::getModulesExcept('stage_file_proxy'); }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains('stage_file_proxy')), ]; yield 'modules_no_seckit_shield_stage_file_proxy' => [ - static::cw(function (): void { - $selected_modules = static::getModulesExcept(['seckit', 'shield', 'stage_file_proxy']); - Env::put(Modules::envName(), Converter::toList($selected_modules)); + static::cw(function ($test): void { + $test->prompts[Modules::id()] = static::getModulesExcept(['seckit', 'shield', 'stage_file_proxy']); }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains([ 'seckit', @@ -103,8 +89,8 @@ public static function dataProviderHandlerProcess(): \Iterator { ])), ]; yield 'modules_none' => [ - static::cw(fn() => Env::put(Modules::envName(), ',')), - static::cw(function (FunctionalTestCase $test): void { + static::cw(fn($test): array => $test->prompts[Modules::id()] = []), + static::cw(function (AbstractHandlerProcessTestCase $test): void { foreach (array_keys(Modules::getAvailableModules()) as $module) { // Cannot assert by the module name alone, as some module names // are generic words that may appear elsewhere. diff --git a/.vortex/installer/tests/Functional/Handlers/NamesHandlerProcessTest.php b/.vortex/installer/tests/Functional/Handlers/NamesHandlerProcessTest.php index e1745defc..76b6e1a97 100644 --- a/.vortex/installer/tests/Functional/Handlers/NamesHandlerProcessTest.php +++ b/.vortex/installer/tests/Functional/Handlers/NamesHandlerProcessTest.php @@ -11,7 +11,7 @@ use DrevOps\VortexInstaller\Prompts\Handlers\Org; use DrevOps\VortexInstaller\Prompts\Handlers\OrgMachineName; use DrevOps\VortexInstaller\Prompts\Handlers\Theme; -use DrevOps\VortexInstaller\Utils\Env; +use DrevOps\VortexInstaller\Prompts\Handlers\ThemeCustom; use PHPUnit\Framework\Attributes\CoversClass; #[CoversClass(Name::class)] @@ -19,14 +19,15 @@ class NamesHandlerProcessTest extends AbstractHandlerProcessTestCase { public static function dataProviderHandlerProcess(): \Iterator { yield 'names' => [ - static::cw(function (): void { - Env::put(Name::envName(), 'New hope'); - Env::put(MachineName::envName(), 'the_new_hope'); - Env::put(Org::envName(), 'Jedi Order'); - Env::put(OrgMachineName::envName(), 'the_jedi_order'); - Env::put(Domain::envName(), 'death-star.com'); - Env::put(ModulePrefix::envName(), 'the_force'); - Env::put(Theme::envName(), 'lightsaber'); + static::cw(function ($test): void { + $test->prompts[Name::id()] = 'New hope'; + $test->prompts[MachineName::id()] = 'the_new_hope'; + $test->prompts[Org::id()] = 'Jedi Order'; + $test->prompts[OrgMachineName::id()] = 'the_jedi_order'; + $test->prompts[Domain::id()] = 'death-star.com'; + $test->prompts[ModulePrefix::id()] = 'the_force'; + $test->prompts[Theme::id()] = Theme::CUSTOM; + $test->prompts[ThemeCustom::id()] = 'lightsaber'; }), ]; } diff --git a/.vortex/installer/tests/Functional/Handlers/NotificationChannelsHandlerProcessTest.php b/.vortex/installer/tests/Functional/Handlers/NotificationChannelsHandlerProcessTest.php index e5e9ef54d..4a5f533a8 100644 --- a/.vortex/installer/tests/Functional/Handlers/NotificationChannelsHandlerProcessTest.php +++ b/.vortex/installer/tests/Functional/Handlers/NotificationChannelsHandlerProcessTest.php @@ -5,9 +5,6 @@ namespace DrevOps\VortexInstaller\Tests\Functional\Handlers; use DrevOps\VortexInstaller\Prompts\Handlers\NotificationChannels; -use DrevOps\VortexInstaller\Tests\Functional\FunctionalTestCase; -use DrevOps\VortexInstaller\Utils\Converter; -use DrevOps\VortexInstaller\Utils\Env; use PHPUnit\Framework\Attributes\CoversClass; #[CoversClass(NotificationChannels::class)] @@ -15,17 +12,17 @@ class NotificationChannelsHandlerProcessTest extends AbstractHandlerProcessTestC public static function dataProviderHandlerProcess(): \Iterator { yield 'notification_channels_all' => [ - static::cw(function (): void { - Env::put(NotificationChannels::envName(), Converter::toList([ + static::cw(function ($test): void { + $test->prompts[NotificationChannels::id()] = [ NotificationChannels::EMAIL, NotificationChannels::GITHUB, NotificationChannels::JIRA, NotificationChannels::NEWRELIC, NotificationChannels::SLACK, NotificationChannels::WEBHOOK, - ], ',', TRUE)); + ]; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertSutContains('VORTEX_NOTIFY_EMAIL_FROM'); $test->assertSutContains('VORTEX_NOTIFY_EMAIL_RECIPIENTS'); $test->assertSutContains('VORTEX_NOTIFY_JIRA_USER_EMAIL'); @@ -33,10 +30,10 @@ public static function dataProviderHandlerProcess(): \Iterator { }), ]; yield 'notification_channels_email_only' => [ - static::cw(function (): void { - Env::put(NotificationChannels::envName(), Converter::toList([NotificationChannels::EMAIL], ',', TRUE)); + static::cw(function ($test): void { + $test->prompts[NotificationChannels::id()] = [NotificationChannels::EMAIL]; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertSutContains('VORTEX_NOTIFY_EMAIL_FROM'); $test->assertSutContains('VORTEX_NOTIFY_EMAIL_RECIPIENTS'); $test->assertSutNotContains('VORTEX_NOTIFY_JIRA_USER_EMAIL'); @@ -44,10 +41,10 @@ public static function dataProviderHandlerProcess(): \Iterator { }), ]; yield 'notification_channels_github_only' => [ - static::cw(function (): void { - Env::put(NotificationChannels::envName(), Converter::toList([NotificationChannels::GITHUB], ',', TRUE)); + static::cw(function ($test): void { + $test->prompts[NotificationChannels::id()] = [NotificationChannels::GITHUB]; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertSutNotContains('VORTEX_NOTIFY_EMAIL_FROM'); $test->assertSutNotContains('VORTEX_NOTIFY_EMAIL_RECIPIENTS'); $test->assertSutNotContains('VORTEX_NOTIFY_JIRA_USER_EMAIL'); @@ -55,10 +52,10 @@ public static function dataProviderHandlerProcess(): \Iterator { }), ]; yield 'notification_channels_jira_only' => [ - static::cw(function (): void { - Env::put(NotificationChannels::envName(), Converter::toList([NotificationChannels::JIRA], ',', TRUE)); + static::cw(function ($test): void { + $test->prompts[NotificationChannels::id()] = [NotificationChannels::JIRA]; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertSutContains('VORTEX_NOTIFY_JIRA_USER_EMAIL'); $test->assertSutNotContains('VORTEX_NOTIFY_EMAIL_FROM'); $test->assertSutNotContains('VORTEX_NOTIFY_EMAIL_RECIPIENTS'); @@ -66,10 +63,10 @@ public static function dataProviderHandlerProcess(): \Iterator { }), ]; yield 'notification_channels_newrelic_only' => [ - static::cw(function (): void { - Env::put(NotificationChannels::envName(), Converter::toList([NotificationChannels::NEWRELIC], ',', TRUE)); + static::cw(function ($test): void { + $test->prompts[NotificationChannels::id()] = [NotificationChannels::NEWRELIC]; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertSutNotContains('VORTEX_NOTIFY_EMAIL_FROM'); $test->assertSutNotContains('VORTEX_NOTIFY_EMAIL_RECIPIENTS'); $test->assertSutNotContains('VORTEX_NOTIFY_JIRA_USER_EMAIL'); @@ -77,10 +74,10 @@ public static function dataProviderHandlerProcess(): \Iterator { }), ]; yield 'notification_channels_slack_only' => [ - static::cw(function (): void { - Env::put(NotificationChannels::envName(), Converter::toList([NotificationChannels::SLACK], ',', TRUE)); + static::cw(function ($test): void { + $test->prompts[NotificationChannels::id()] = [NotificationChannels::SLACK]; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertSutNotContains('VORTEX_NOTIFY_EMAIL_FROM'); $test->assertSutNotContains('VORTEX_NOTIFY_EMAIL_RECIPIENTS'); $test->assertSutNotContains('VORTEX_NOTIFY_JIRA_USER_EMAIL'); @@ -88,10 +85,10 @@ public static function dataProviderHandlerProcess(): \Iterator { }), ]; yield 'notification_channels_webhook_only' => [ - static::cw(function (): void { - Env::put(NotificationChannels::envName(), Converter::toList([NotificationChannels::WEBHOOK], ',', TRUE)); + static::cw(function ($test): void { + $test->prompts[NotificationChannels::id()] = [NotificationChannels::WEBHOOK]; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertSutContains('VORTEX_NOTIFY_WEBHOOK_URL'); $test->assertSutNotContains('VORTEX_NOTIFY_EMAIL_FROM'); $test->assertSutNotContains('VORTEX_NOTIFY_EMAIL_RECIPIENTS'); @@ -99,8 +96,8 @@ public static function dataProviderHandlerProcess(): \Iterator { }), ]; yield 'notification_channels_none' => [ - static::cw(fn() => Env::put(NotificationChannels::envName(), ',')), - static::cw(function (FunctionalTestCase $test): void { + static::cw(fn($test): array => $test->prompts[NotificationChannels::id()] = []), + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertSutNotContains('VORTEX_NOTIFY_EMAIL_FROM'); $test->assertSutNotContains('VORTEX_NOTIFY_EMAIL_RECIPIENTS'); $test->assertSutNotContains('VORTEX_NOTIFY_JIRA_USER_EMAIL'); diff --git a/.vortex/installer/tests/Functional/Handlers/ProfileHandlerProcessTest.php b/.vortex/installer/tests/Functional/Handlers/ProfileHandlerProcessTest.php index 93c7ae004..5d716cacc 100644 --- a/.vortex/installer/tests/Functional/Handlers/ProfileHandlerProcessTest.php +++ b/.vortex/installer/tests/Functional/Handlers/ProfileHandlerProcessTest.php @@ -5,7 +5,7 @@ namespace DrevOps\VortexInstaller\Tests\Functional\Handlers; use DrevOps\VortexInstaller\Prompts\Handlers\Profile; -use DrevOps\VortexInstaller\Utils\Env; +use DrevOps\VortexInstaller\Prompts\Handlers\ProfileCustom; use PHPUnit\Framework\Attributes\CoversClass; #[CoversClass(Profile::class)] @@ -13,10 +13,13 @@ class ProfileHandlerProcessTest extends AbstractHandlerProcessTestCase { public static function dataProviderHandlerProcess(): \Iterator { yield 'profile_minimal' => [ - static::cw(fn() => Env::put(Profile::envName(), Profile::MINIMAL)), + static::cw(fn($test): string => $test->prompts[Profile::id()] = Profile::MINIMAL), ]; yield 'profile_the_empire' => [ - static::cw(fn() => Env::put(Profile::envName(), 'the_empire')), + static::cw(function ($test): void { + $test->prompts[Profile::id()] = Profile::CUSTOM; + $test->prompts[ProfileCustom::id()] = 'the_empire'; + }), ]; } diff --git a/.vortex/installer/tests/Functional/Handlers/ProvisionTypeHandlerProcessTest.php b/.vortex/installer/tests/Functional/Handlers/ProvisionTypeHandlerProcessTest.php index eb666033c..099d04c38 100644 --- a/.vortex/installer/tests/Functional/Handlers/ProvisionTypeHandlerProcessTest.php +++ b/.vortex/installer/tests/Functional/Handlers/ProvisionTypeHandlerProcessTest.php @@ -7,7 +7,6 @@ use DrevOps\VortexInstaller\Prompts\Handlers\AiCodeInstructions; use DrevOps\VortexInstaller\Prompts\Handlers\HostingProvider; use DrevOps\VortexInstaller\Prompts\Handlers\ProvisionType; -use DrevOps\VortexInstaller\Utils\Env; use PHPUnit\Framework\Attributes\CoversClass; #[CoversClass(ProvisionType::class)] @@ -15,19 +14,19 @@ class ProvisionTypeHandlerProcessTest extends AbstractHandlerProcessTestCase { public static function dataProviderHandlerProcess(): \Iterator { yield 'provision_database' => [ - static::cw(fn() => Env::put(ProvisionType::envName(), ProvisionType::DATABASE)), + static::cw(fn($test): string => $test->prompts[ProvisionType::id()] = ProvisionType::DATABASE), ]; yield 'provision_database_lagoon' => [ - static::cw(function (): void { - Env::put(ProvisionType::envName(), ProvisionType::DATABASE); - Env::put(HostingProvider::envName(), HostingProvider::LAGOON); - Env::put(AiCodeInstructions::envName(), Env::TRUE); + static::cw(function ($test): void { + $test->prompts[ProvisionType::id()] = ProvisionType::DATABASE; + $test->prompts[HostingProvider::id()] = HostingProvider::LAGOON; + $test->prompts[AiCodeInstructions::id()] = TRUE; }), ]; yield 'provision_profile' => [ - static::cw(function (): void { - Env::put(ProvisionType::envName(), ProvisionType::PROFILE); - Env::put(AiCodeInstructions::envName(), Env::TRUE); + static::cw(function ($test): void { + $test->prompts[ProvisionType::id()] = ProvisionType::PROFILE; + $test->prompts[AiCodeInstructions::id()] = TRUE; }), ]; } diff --git a/.vortex/installer/tests/Functional/Handlers/PullRequestHandlerProcessTest.php b/.vortex/installer/tests/Functional/Handlers/PullRequestHandlerProcessTest.php index d72946458..c04ec7175 100644 --- a/.vortex/installer/tests/Functional/Handlers/PullRequestHandlerProcessTest.php +++ b/.vortex/installer/tests/Functional/Handlers/PullRequestHandlerProcessTest.php @@ -6,7 +6,6 @@ use DrevOps\VortexInstaller\Prompts\Handlers\AssignAuthorPr; use DrevOps\VortexInstaller\Prompts\Handlers\LabelMergeConflictsPr; -use DrevOps\VortexInstaller\Utils\Env; use PHPUnit\Framework\Attributes\CoversClass; #[CoversClass(AssignAuthorPr::class)] @@ -15,16 +14,16 @@ class PullRequestHandlerProcessTest extends AbstractHandlerProcessTestCase { public static function dataProviderHandlerProcess(): \Iterator { yield 'assign_author_pr_enabled' => [ - static::cw(fn() => Env::put(AssignAuthorPr::envName(), Env::TRUE)), + static::cw(fn($test): true => $test->prompts[AssignAuthorPr::id()] = TRUE), ]; yield 'assign_author_pr_disabled' => [ - static::cw(fn() => Env::put(AssignAuthorPr::envName(), Env::FALSE)), + static::cw(fn($test): false => $test->prompts[AssignAuthorPr::id()] = FALSE), ]; yield 'label_merge_conflicts_pr_enabled' => [ - static::cw(fn() => Env::put(LabelMergeConflictsPr::envName(), Env::TRUE)), + static::cw(fn($test): true => $test->prompts[LabelMergeConflictsPr::id()] = TRUE), ]; yield 'label_merge_conflicts_pr_disabled' => [ - static::cw(fn() => Env::put(LabelMergeConflictsPr::envName(), Env::FALSE)), + static::cw(fn($test): false => $test->prompts[LabelMergeConflictsPr::id()] = FALSE), ]; } diff --git a/.vortex/installer/tests/Functional/Handlers/ServicesHandlerProcessTest.php b/.vortex/installer/tests/Functional/Handlers/ServicesHandlerProcessTest.php index b72677e7d..0a720fd09 100644 --- a/.vortex/installer/tests/Functional/Handlers/ServicesHandlerProcessTest.php +++ b/.vortex/installer/tests/Functional/Handlers/ServicesHandlerProcessTest.php @@ -7,8 +7,6 @@ use DrevOps\VortexInstaller\Prompts\Handlers\AiCodeInstructions; use DrevOps\VortexInstaller\Prompts\Handlers\Services; use DrevOps\VortexInstaller\Tests\Functional\FunctionalTestCase; -use DrevOps\VortexInstaller\Utils\Converter; -use DrevOps\VortexInstaller\Utils\Env; use PHPUnit\Framework\Attributes\CoversClass; #[CoversClass(Services::class)] @@ -16,29 +14,29 @@ class ServicesHandlerProcessTest extends AbstractHandlerProcessTestCase { public static function dataProviderHandlerProcess(): \Iterator { yield 'services_no_clamav' => [ - static::cw(function (): void { - Env::put(Services::envName(), Converter::toList([Services::SOLR, Services::REDIS])); - Env::put(AiCodeInstructions::envName(), Env::TRUE); + static::cw(function ($test): void { + $test->prompts[Services::id()] = [Services::SOLR, Services::REDIS]; + $test->prompts[AiCodeInstructions::id()] = TRUE; }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains('clamav')), ]; yield 'services_no_redis' => [ - static::cw(function (): void { - Env::put(Services::envName(), Converter::toList([Services::CLAMAV, Services::SOLR])); - Env::put(AiCodeInstructions::envName(), Env::TRUE); + static::cw(function ($test): void { + $test->prompts[Services::id()] = [Services::CLAMAV, Services::SOLR]; + $test->prompts[AiCodeInstructions::id()] = TRUE; }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains('redis')), ]; yield 'services_no_solr' => [ - static::cw(function (): void { - Env::put(Services::envName(), Converter::toList([Services::CLAMAV, Services::REDIS])); - Env::put(AiCodeInstructions::envName(), Env::TRUE); + static::cw(function ($test): void { + $test->prompts[Services::id()] = [Services::CLAMAV, Services::REDIS]; + $test->prompts[AiCodeInstructions::id()] = TRUE; }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains('solr')), ]; yield 'services_none' => [ - static::cw(fn() => Env::put(Services::envName(), ',')), - static::cw(function (FunctionalTestCase $test): void { + static::cw(fn($test): array => $test->prompts[Services::id()] = []), + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertSutNotContains('clamav'); $test->assertSutNotContains('solr'); $test->assertSutNotContains('redis'); diff --git a/.vortex/installer/tests/Functional/Handlers/StarterHandlerProcessTest.php b/.vortex/installer/tests/Functional/Handlers/StarterHandlerProcessTest.php index 9f8c9a4c5..ac5a67bec 100644 --- a/.vortex/installer/tests/Functional/Handlers/StarterHandlerProcessTest.php +++ b/.vortex/installer/tests/Functional/Handlers/StarterHandlerProcessTest.php @@ -6,7 +6,6 @@ use DrevOps\VortexInstaller\Prompts\Handlers\Starter; use DrevOps\VortexInstaller\Tests\Functional\FunctionalTestCase; -use DrevOps\VortexInstaller\Utils\Env; use PHPUnit\Framework\Attributes\CoversClass; #[CoversClass(Starter::class)] @@ -14,7 +13,7 @@ class StarterHandlerProcessTest extends AbstractHandlerProcessTestCase { public static function dataProviderHandlerProcess(): \Iterator { yield 'starter_demo_db' => [ - static::cw(fn() => Env::put(Starter::envName(), Starter::LOAD_DATABASE_DEMO)), + static::cw(fn($test): string => $test->prompts[Starter::id()] = Starter::LOAD_DATABASE_DEMO), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains([ 'drupal/cms', 'wikimedia/composer-merge-plugin', @@ -22,7 +21,7 @@ public static function dataProviderHandlerProcess(): \Iterator { ])), ]; yield 'starter_drupal_profile' => [ - static::cw(fn() => Env::put(Starter::envName(), Starter::INSTALL_PROFILE_CORE)), + static::cw(fn($test): string => $test->prompts[Starter::id()] = Starter::INSTALL_PROFILE_CORE), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains([ 'drupal/cms', 'wikimedia/composer-merge-plugin', @@ -30,7 +29,7 @@ public static function dataProviderHandlerProcess(): \Iterator { ])), ]; yield 'starter_drupal_cms_profile' => [ - static::cw(fn() => Env::put(Starter::envName(), Starter::INSTALL_PROFILE_DRUPALCMS)), + static::cw(fn($test): string => $test->prompts[Starter::id()] = Starter::INSTALL_PROFILE_DRUPALCMS), static::cw(fn(FunctionalTestCase $test) => $test->assertSutContains([ 'drupal/cms', 'wikimedia/composer-merge-plugin', diff --git a/.vortex/installer/tests/Functional/Handlers/ThemeHandlerProcessTest.php b/.vortex/installer/tests/Functional/Handlers/ThemeHandlerProcessTest.php index 78f6abc1c..50d502de9 100644 --- a/.vortex/installer/tests/Functional/Handlers/ThemeHandlerProcessTest.php +++ b/.vortex/installer/tests/Functional/Handlers/ThemeHandlerProcessTest.php @@ -5,8 +5,8 @@ namespace DrevOps\VortexInstaller\Tests\Functional\Handlers; use DrevOps\VortexInstaller\Prompts\Handlers\Theme; +use DrevOps\VortexInstaller\Prompts\Handlers\ThemeCustom; use DrevOps\VortexInstaller\Tests\Functional\FunctionalTestCase; -use DrevOps\VortexInstaller\Utils\Env; use DrevOps\VortexInstaller\Utils\File; use PHPUnit\Framework\Attributes\CoversClass; @@ -15,7 +15,7 @@ class ThemeHandlerProcessTest extends AbstractHandlerProcessTestCase { public static function dataProviderHandlerProcess(): \Iterator { yield 'theme_olivero' => [ - static::cw(fn() => Env::put(Theme::envName(), Theme::OLIVERO)), + static::cw(fn($test): string => $test->prompts[Theme::id()] = Theme::OLIVERO), static::cw(fn(FunctionalTestCase $test) => $test->assertDirectoryNotContainsString(static::$sut, 'themes/custom', [ '.gitignore', 'scripts/vortex', @@ -25,7 +25,7 @@ public static function dataProviderHandlerProcess(): \Iterator { ])), ]; yield 'theme_claro' => [ - static::cw(fn() => Env::put(Theme::envName(), Theme::CLARO)), + static::cw(fn($test): string => $test->prompts[Theme::id()] = Theme::CLARO), static::cw(fn(FunctionalTestCase $test) => $test->assertDirectoryNotContainsString(static::$sut, 'themes/custom', [ '.gitignore', 'scripts/vortex', @@ -35,7 +35,7 @@ public static function dataProviderHandlerProcess(): \Iterator { ])), ]; yield 'theme_stark' => [ - static::cw(fn() => Env::put(Theme::envName(), Theme::STARK)), + static::cw(fn($test): string => $test->prompts[Theme::id()] = Theme::STARK), static::cw(fn(FunctionalTestCase $test) => $test->assertDirectoryNotContainsString(static::$sut, 'themes/custom', [ '.gitignore', 'scripts/vortex', @@ -45,12 +45,16 @@ public static function dataProviderHandlerProcess(): \Iterator { ])), ]; yield 'theme_custom' => [ - static::cw(fn() => Env::put(Theme::envName(), 'light_saber')), + static::cw(function ($test): void { + $test->prompts[Theme::id()] = Theme::CUSTOM; + $test->prompts[ThemeCustom::id()] = 'light_saber'; + }), static::cw(fn(FunctionalTestCase $test) => $test->assertDirectoryNotContainsString(static::$sut, 'your_site_theme')), ]; yield 'theme_custom_non_vortex' => [ - static::cw(function (FunctionalTestCase $test): void { - Env::put(Theme::envName(), 'star_wars'); + static::cw(function (AbstractHandlerProcessTestCase $test): void { + $test->prompts[Theme::id()] = Theme::CUSTOM; + $test->prompts[ThemeCustom::id()] = 'star_wars'; // Run a first install to create a proper Vortex project // with a Vortex-sourced custom theme. @@ -68,7 +72,7 @@ public static function dataProviderHandlerProcess(): \Iterator { File::dump($theme_dir . '/package.json', '{"name": "star_wars_custom"}' . PHP_EOL); File::dump($theme_dir . '/styles.css', '.star-wars { color: blue; }' . PHP_EOL); }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { // The project's own theme files must be preserved unchanged — // Vortex must not overwrite them with its template theme files. $theme_dir = static::$sut . '/web/themes/custom/star_wars'; diff --git a/.vortex/installer/tests/Functional/Handlers/TimezoneHandlerProcessTest.php b/.vortex/installer/tests/Functional/Handlers/TimezoneHandlerProcessTest.php index 0042cf0ff..aa059b1e8 100644 --- a/.vortex/installer/tests/Functional/Handlers/TimezoneHandlerProcessTest.php +++ b/.vortex/installer/tests/Functional/Handlers/TimezoneHandlerProcessTest.php @@ -6,8 +6,6 @@ use DrevOps\VortexInstaller\Prompts\Handlers\CiProvider; use DrevOps\VortexInstaller\Prompts\Handlers\Timezone; -use DrevOps\VortexInstaller\Tests\Functional\FunctionalTestCase; -use DrevOps\VortexInstaller\Utils\Env; use PHPUnit\Framework\Attributes\CoversClass; #[CoversClass(Timezone::class)] @@ -15,11 +13,11 @@ class TimezoneHandlerProcessTest extends AbstractHandlerProcessTestCase { public static function dataProviderHandlerProcess(): \Iterator { yield 'timezone_gha' => [ - static::cw(function (): void { - Env::put(Timezone::envName(), 'America/New_York'); - Env::put(CiProvider::envName(), CiProvider::GITHUB_ACTIONS); + static::cw(function ($test): void { + $test->prompts[Timezone::id()] = 'America/New_York'; + $test->prompts[CiProvider::id()] = CiProvider::GITHUB_ACTIONS; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { // Timezone should be replaced in .env file. $test->assertFileContainsString(static::$sut . '/.env', 'TZ=America/New_York'); $test->assertFileNotContainsString(static::$sut . '/.env', 'UTC'); @@ -39,11 +37,11 @@ public static function dataProviderHandlerProcess(): \Iterator { }), ]; yield 'timezone_circleci' => [ - static::cw(function (): void { - Env::put(Timezone::envName(), 'America/New_York'); - Env::put(CiProvider::envName(), CiProvider::CIRCLECI); + static::cw(function ($test): void { + $test->prompts[Timezone::id()] = 'America/New_York'; + $test->prompts[CiProvider::id()] = CiProvider::CIRCLECI; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { // Timezone should not be replaced in CircleCI config in code as it // should be overridden via UI. $test->assertFileNotContainsString(static::$sut . '/.circleci/config.yml', 'TZ: America/New_York'); diff --git a/.vortex/installer/tests/Functional/Handlers/ToolsHandlerProcessTest.php b/.vortex/installer/tests/Functional/Handlers/ToolsHandlerProcessTest.php index 0b35e30e3..8c8ec7f19 100644 --- a/.vortex/installer/tests/Functional/Handlers/ToolsHandlerProcessTest.php +++ b/.vortex/installer/tests/Functional/Handlers/ToolsHandlerProcessTest.php @@ -8,8 +8,6 @@ use DrevOps\VortexInstaller\Prompts\Handlers\Theme; use DrevOps\VortexInstaller\Prompts\Handlers\Tools; use DrevOps\VortexInstaller\Tests\Functional\FunctionalTestCase; -use DrevOps\VortexInstaller\Utils\Converter; -use DrevOps\VortexInstaller\Utils\Env; use PHPUnit\Framework\Attributes\CoversClass; #[CoversClass(Tools::class)] @@ -17,10 +15,10 @@ class ToolsHandlerProcessTest extends AbstractHandlerProcessTestCase { public static function dataProviderHandlerProcess(): \Iterator { yield 'tools_none' => [ - static::cw(function (): void { - Env::put(Tools::envName(), Converter::toList([])); + static::cw(function ($test): void { + $test->prompts[Tools::id()] = []; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertSutNotContains([ 'phpcs', 'phpcbf', @@ -56,10 +54,10 @@ public static function dataProviderHandlerProcess(): \Iterator { }), ]; yield 'tools_no_phpcs' => [ - static::cw(function (): void { + static::cw(function ($test): void { $tools = array_keys(Tools::getToolDefinitions('tools')); - Env::put(Tools::envName(), Converter::toList(array_diff($tools, [Tools::PHPCS]))); - Env::put(CiProvider::envName(), CiProvider::GITHUB_ACTIONS); + $test->prompts[Tools::id()] = array_values(array_diff($tools, [Tools::PHPCS])); + $test->prompts[CiProvider::id()] = CiProvider::GITHUB_ACTIONS; }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains([ 'phpcs', @@ -70,10 +68,10 @@ public static function dataProviderHandlerProcess(): \Iterator { ])), ]; yield 'tools_no_phpcs_circleci' => [ - static::cw(function (): void { + static::cw(function ($test): void { $tools = array_keys(Tools::getToolDefinitions('tools')); - Env::put(Tools::envName(), Converter::toList(array_diff($tools, [Tools::PHPCS]))); - Env::put(CiProvider::envName(), CiProvider::CIRCLECI); + $test->prompts[Tools::id()] = array_values(array_diff($tools, [Tools::PHPCS])); + $test->prompts[CiProvider::id()] = CiProvider::CIRCLECI; }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains([ 'phpcs', @@ -84,10 +82,10 @@ public static function dataProviderHandlerProcess(): \Iterator { ])), ]; yield 'tools_no_phpstan' => [ - static::cw(function (): void { + static::cw(function ($test): void { $tools = array_keys(Tools::getToolDefinitions('tools')); - Env::put(Tools::envName(), Converter::toList(array_diff($tools, [Tools::PHPSTAN]))); - Env::put(CiProvider::envName(), CiProvider::GITHUB_ACTIONS); + $test->prompts[Tools::id()] = array_values(array_diff($tools, [Tools::PHPSTAN])); + $test->prompts[CiProvider::id()] = CiProvider::GITHUB_ACTIONS; }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains([ 'phpstan', @@ -96,10 +94,10 @@ public static function dataProviderHandlerProcess(): \Iterator { ])), ]; yield 'tools_no_phpstan_circleci' => [ - static::cw(function (): void { + static::cw(function ($test): void { $tools = array_keys(Tools::getToolDefinitions('tools')); - Env::put(Tools::envName(), Converter::toList(array_diff($tools, [Tools::PHPSTAN]))); - Env::put(CiProvider::envName(), CiProvider::CIRCLECI); + $test->prompts[Tools::id()] = array_values(array_diff($tools, [Tools::PHPSTAN])); + $test->prompts[CiProvider::id()] = CiProvider::CIRCLECI; }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains([ 'phpstan', @@ -108,10 +106,10 @@ public static function dataProviderHandlerProcess(): \Iterator { ])), ]; yield 'tools_no_rector' => [ - static::cw(function (): void { + static::cw(function ($test): void { $tools = array_keys(Tools::getToolDefinitions('tools')); - Env::put(Tools::envName(), Converter::toList(array_diff($tools, [Tools::RECTOR]))); - Env::put(CiProvider::envName(), CiProvider::GITHUB_ACTIONS); + $test->prompts[Tools::id()] = array_values(array_diff($tools, [Tools::RECTOR])); + $test->prompts[CiProvider::id()] = CiProvider::GITHUB_ACTIONS; }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains([ 'rector', @@ -119,10 +117,10 @@ public static function dataProviderHandlerProcess(): \Iterator { ])), ]; yield 'tools_no_rector_circleci' => [ - static::cw(function (): void { + static::cw(function ($test): void { $tools = array_keys(Tools::getToolDefinitions('tools')); - Env::put(Tools::envName(), Converter::toList(array_diff($tools, [Tools::RECTOR]))); - Env::put(CiProvider::envName(), CiProvider::CIRCLECI); + $test->prompts[Tools::id()] = array_values(array_diff($tools, [Tools::RECTOR])); + $test->prompts[CiProvider::id()] = CiProvider::CIRCLECI; }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains([ 'rector', @@ -130,10 +128,10 @@ public static function dataProviderHandlerProcess(): \Iterator { ])), ]; yield 'tools_no_phpmd' => [ - static::cw(function (): void { + static::cw(function ($test): void { $tools = array_keys(Tools::getToolDefinitions('tools')); - Env::put(Tools::envName(), Converter::toList(array_diff($tools, [Tools::PHPMD]))); - Env::put(CiProvider::envName(), CiProvider::GITHUB_ACTIONS); + $test->prompts[Tools::id()] = array_values(array_diff($tools, [Tools::PHPMD])); + $test->prompts[CiProvider::id()] = CiProvider::GITHUB_ACTIONS; }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains([ 'phpmd', @@ -141,10 +139,10 @@ public static function dataProviderHandlerProcess(): \Iterator { ])), ]; yield 'tools_no_phpmd_circleci' => [ - static::cw(function (): void { + static::cw(function ($test): void { $tools = array_keys(Tools::getToolDefinitions('tools')); - Env::put(Tools::envName(), Converter::toList(array_diff($tools, [Tools::PHPMD]))); - Env::put(CiProvider::envName(), CiProvider::CIRCLECI); + $test->prompts[Tools::id()] = array_values(array_diff($tools, [Tools::PHPMD])); + $test->prompts[CiProvider::id()] = CiProvider::CIRCLECI; }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains([ 'phpmd', @@ -152,12 +150,12 @@ public static function dataProviderHandlerProcess(): \Iterator { ])), ]; yield 'tools_no_eslint' => [ - static::cw(function (): void { + static::cw(function ($test): void { $tools = array_keys(Tools::getToolDefinitions('tools')); - Env::put(Tools::envName(), Converter::toList(array_diff($tools, [Tools::ESLINT]))); - Env::put(CiProvider::envName(), CiProvider::GITHUB_ACTIONS); + $test->prompts[Tools::id()] = array_values(array_diff($tools, [Tools::ESLINT])); + $test->prompts[CiProvider::id()] = CiProvider::GITHUB_ACTIONS; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $pj = static::$sut . '/package.json'; $test->assertFileNotContainsString($pj, '"eslint":'); $test->assertFileNotContainsString($pj, '"eslint-config-airbnb-base":'); @@ -178,12 +176,12 @@ public static function dataProviderHandlerProcess(): \Iterator { }), ]; yield 'tools_no_eslint_circleci' => [ - static::cw(function (): void { + static::cw(function ($test): void { $tools = array_keys(Tools::getToolDefinitions('tools')); - Env::put(Tools::envName(), Converter::toList(array_diff($tools, [Tools::ESLINT]))); - Env::put(CiProvider::envName(), CiProvider::CIRCLECI); + $test->prompts[Tools::id()] = array_values(array_diff($tools, [Tools::ESLINT])); + $test->prompts[CiProvider::id()] = CiProvider::CIRCLECI; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $pj = static::$sut . '/package.json'; $test->assertFileNotContainsString($pj, '"eslint":'); $test->assertFileNotContainsString($pj, '"eslint-config-airbnb-base":'); @@ -204,12 +202,12 @@ public static function dataProviderHandlerProcess(): \Iterator { }), ]; yield 'tools_no_stylelint' => [ - static::cw(function (): void { + static::cw(function ($test): void { $tools = array_keys(Tools::getToolDefinitions('tools')); - Env::put(Tools::envName(), Converter::toList(array_diff($tools, [Tools::STYLELINT]))); - Env::put(CiProvider::envName(), CiProvider::GITHUB_ACTIONS); + $test->prompts[Tools::id()] = array_values(array_diff($tools, [Tools::STYLELINT])); + $test->prompts[CiProvider::id()] = CiProvider::GITHUB_ACTIONS; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $pj = static::$sut . '/package.json'; $test->assertFileNotContainsString($pj, '"stylelint":'); $test->assertFileNotContainsString($pj, '"stylelint-config-standard":'); @@ -220,12 +218,12 @@ public static function dataProviderHandlerProcess(): \Iterator { }), ]; yield 'tools_no_stylelint_circleci' => [ - static::cw(function (): void { + static::cw(function ($test): void { $tools = array_keys(Tools::getToolDefinitions('tools')); - Env::put(Tools::envName(), Converter::toList(array_diff($tools, [Tools::STYLELINT]))); - Env::put(CiProvider::envName(), CiProvider::CIRCLECI); + $test->prompts[Tools::id()] = array_values(array_diff($tools, [Tools::STYLELINT])); + $test->prompts[CiProvider::id()] = CiProvider::CIRCLECI; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $pj = static::$sut . '/package.json'; $test->assertFileNotContainsString($pj, '"stylelint":'); $test->assertFileNotContainsString($pj, '"stylelint-config-standard":'); @@ -236,10 +234,10 @@ public static function dataProviderHandlerProcess(): \Iterator { }), ]; yield 'tools_no_phpunit' => [ - static::cw(function (): void { + static::cw(function ($test): void { $tools = array_keys(Tools::getToolDefinitions('tools')); - Env::put(Tools::envName(), Converter::toList(array_diff($tools, [Tools::PHPUNIT]))); - Env::put(CiProvider::envName(), CiProvider::GITHUB_ACTIONS); + $test->prompts[Tools::id()] = array_values(array_diff($tools, [Tools::PHPUNIT])); + $test->prompts[CiProvider::id()] = CiProvider::GITHUB_ACTIONS; }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains([ 'phpunit', @@ -249,10 +247,10 @@ public static function dataProviderHandlerProcess(): \Iterator { ])), ]; yield 'tools_no_phpunit_circleci' => [ - static::cw(function (): void { + static::cw(function ($test): void { $tools = array_keys(Tools::getToolDefinitions('tools')); - Env::put(Tools::envName(), Converter::toList(array_diff($tools, [Tools::PHPUNIT]))); - Env::put(CiProvider::envName(), CiProvider::CIRCLECI); + $test->prompts[Tools::id()] = array_values(array_diff($tools, [Tools::PHPUNIT])); + $test->prompts[CiProvider::id()] = CiProvider::CIRCLECI; }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains([ 'phpunit', @@ -262,10 +260,10 @@ public static function dataProviderHandlerProcess(): \Iterator { ])), ]; yield 'tools_no_behat' => [ - static::cw(function (): void { + static::cw(function ($test): void { $tools = array_keys(Tools::getToolDefinitions('tools')); - Env::put(Tools::envName(), Converter::toList(array_diff($tools, [Tools::BEHAT]))); - Env::put(CiProvider::envName(), CiProvider::GITHUB_ACTIONS); + $test->prompts[Tools::id()] = array_values(array_diff($tools, [Tools::BEHAT])); + $test->prompts[CiProvider::id()] = CiProvider::GITHUB_ACTIONS; }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains([ 'behat', @@ -279,10 +277,10 @@ public static function dataProviderHandlerProcess(): \Iterator { ])), ]; yield 'tools_no_behat_circleci' => [ - static::cw(function (): void { + static::cw(function ($test): void { $tools = array_keys(Tools::getToolDefinitions('tools')); - Env::put(Tools::envName(), Converter::toList(array_diff($tools, [Tools::BEHAT]))); - Env::put(CiProvider::envName(), CiProvider::CIRCLECI); + $test->prompts[Tools::id()] = array_values(array_diff($tools, [Tools::BEHAT])); + $test->prompts[CiProvider::id()] = CiProvider::CIRCLECI; }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains([ 'behat', @@ -295,10 +293,10 @@ public static function dataProviderHandlerProcess(): \Iterator { ])), ]; yield 'tools_groups_no_be_lint' => [ - static::cw(function (): void { + static::cw(function ($test): void { $tools = array_keys(Tools::getToolDefinitions('tools')); - Env::put(Tools::envName(), Converter::toList(array_diff($tools, [Tools::PHPCS, Tools::PHPMD, Tools::PHPSTAN, Tools::RECTOR]))); - Env::put(CiProvider::envName(), CiProvider::GITHUB_ACTIONS); + $test->prompts[Tools::id()] = array_values(array_diff($tools, [Tools::PHPCS, Tools::PHPMD, Tools::PHPSTAN, Tools::RECTOR])); + $test->prompts[CiProvider::id()] = CiProvider::GITHUB_ACTIONS; }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains([ 'phpcs', @@ -316,10 +314,10 @@ public static function dataProviderHandlerProcess(): \Iterator { ])), ]; yield 'tools_groups_no_be_lint_circleci' => [ - static::cw(function (): void { + static::cw(function ($test): void { $tools = array_keys(Tools::getToolDefinitions('tools')); - Env::put(Tools::envName(), Converter::toList(array_diff($tools, [Tools::PHPCS, Tools::PHPMD, Tools::PHPSTAN, Tools::RECTOR]))); - Env::put(CiProvider::envName(), CiProvider::CIRCLECI); + $test->prompts[Tools::id()] = array_values(array_diff($tools, [Tools::PHPCS, Tools::PHPMD, Tools::PHPSTAN, Tools::RECTOR])); + $test->prompts[CiProvider::id()] = CiProvider::CIRCLECI; }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains([ 'phpcs', @@ -337,12 +335,12 @@ public static function dataProviderHandlerProcess(): \Iterator { ])), ]; yield 'tools_no_jest' => [ - static::cw(function (): void { + static::cw(function ($test): void { $tools = array_keys(Tools::getToolDefinitions('tools')); - Env::put(Tools::envName(), Converter::toList(array_diff($tools, [Tools::JEST]))); - Env::put(CiProvider::envName(), CiProvider::GITHUB_ACTIONS); + $test->prompts[Tools::id()] = array_values(array_diff($tools, [Tools::JEST])); + $test->prompts[CiProvider::id()] = CiProvider::GITHUB_ACTIONS; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $pj = static::$sut . '/package.json'; $test->assertFileNotContainsString($pj, '"jest":'); $test->assertFileNotContainsString($pj, '"jest-environment-jsdom":'); @@ -352,12 +350,12 @@ public static function dataProviderHandlerProcess(): \Iterator { }), ]; yield 'tools_no_jest_circleci' => [ - static::cw(function (): void { + static::cw(function ($test): void { $tools = array_keys(Tools::getToolDefinitions('tools')); - Env::put(Tools::envName(), Converter::toList(array_diff($tools, [Tools::JEST]))); - Env::put(CiProvider::envName(), CiProvider::CIRCLECI); + $test->prompts[Tools::id()] = array_values(array_diff($tools, [Tools::JEST])); + $test->prompts[CiProvider::id()] = CiProvider::CIRCLECI; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $pj = static::$sut . '/package.json'; $test->assertFileNotContainsString($pj, '"jest":'); $test->assertFileNotContainsString($pj, '"jest-environment-jsdom":'); @@ -367,12 +365,12 @@ public static function dataProviderHandlerProcess(): \Iterator { }), ]; yield 'tools_groups_no_fe_lint' => [ - static::cw(function (): void { + static::cw(function ($test): void { $tools = array_keys(Tools::getToolDefinitions('tools')); - Env::put(Tools::envName(), Converter::toList(array_diff($tools, [Tools::ESLINT, Tools::STYLELINT, Tools::JEST]))); - Env::put(CiProvider::envName(), CiProvider::GITHUB_ACTIONS); + $test->prompts[Tools::id()] = array_values(array_diff($tools, [Tools::ESLINT, Tools::STYLELINT, Tools::JEST])); + $test->prompts[CiProvider::id()] = CiProvider::GITHUB_ACTIONS; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertFileDoesNotExist(static::$sut . '/package.json'); $test->assertFileDoesNotExist(static::$sut . '/yarn.lock'); $test->assertFileDoesNotExist(static::$sut . '/.eslintrc.json'); @@ -384,12 +382,12 @@ public static function dataProviderHandlerProcess(): \Iterator { }), ]; yield 'tools_groups_no_fe_lint_circleci' => [ - static::cw(function (): void { + static::cw(function ($test): void { $tools = array_keys(Tools::getToolDefinitions('tools')); - Env::put(Tools::envName(), Converter::toList(array_diff($tools, [Tools::ESLINT, Tools::STYLELINT, Tools::JEST]))); - Env::put(CiProvider::envName(), CiProvider::CIRCLECI); + $test->prompts[Tools::id()] = array_values(array_diff($tools, [Tools::ESLINT, Tools::STYLELINT, Tools::JEST])); + $test->prompts[CiProvider::id()] = CiProvider::CIRCLECI; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertFileDoesNotExist(static::$sut . '/package.json'); $test->assertFileDoesNotExist(static::$sut . '/yarn.lock'); $test->assertFileDoesNotExist(static::$sut . '/.eslintrc.json'); @@ -401,10 +399,10 @@ public static function dataProviderHandlerProcess(): \Iterator { }), ]; yield 'tools_groups_no_be_tests' => [ - static::cw(function (): void { + static::cw(function ($test): void { $tools = array_keys(Tools::getToolDefinitions('tools')); - Env::put(Tools::envName(), Converter::toList(array_diff($tools, [Tools::PHPUNIT, Tools::BEHAT]))); - Env::put(CiProvider::envName(), CiProvider::GITHUB_ACTIONS); + $test->prompts[Tools::id()] = array_values(array_diff($tools, [Tools::PHPUNIT, Tools::BEHAT])); + $test->prompts[CiProvider::id()] = CiProvider::GITHUB_ACTIONS; }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains([ 'phpunit', @@ -421,10 +419,10 @@ public static function dataProviderHandlerProcess(): \Iterator { ])), ]; yield 'tools_groups_no_be_tests_circleci' => [ - static::cw(function (): void { + static::cw(function ($test): void { $tools = array_keys(Tools::getToolDefinitions('tools')); - Env::put(Tools::envName(), Converter::toList(array_diff($tools, [Tools::PHPUNIT, Tools::BEHAT]))); - Env::put(CiProvider::envName(), CiProvider::CIRCLECI); + $test->prompts[Tools::id()] = array_values(array_diff($tools, [Tools::PHPUNIT, Tools::BEHAT])); + $test->prompts[CiProvider::id()] = CiProvider::CIRCLECI; }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains([ 'phpunit', @@ -441,13 +439,13 @@ public static function dataProviderHandlerProcess(): \Iterator { ])), ]; yield 'tools_groups_no_fe_lint_no_theme' => [ - static::cw(function (): void { + static::cw(function ($test): void { $tools = array_keys(Tools::getToolDefinitions('tools')); - Env::put(Tools::envName(), Converter::toList(array_diff($tools, [Tools::ESLINT, Tools::STYLELINT, Tools::JEST]))); - Env::put(CiProvider::envName(), CiProvider::GITHUB_ACTIONS); - Env::put(Theme::envName(), Theme::OLIVERO); + $test->prompts[Tools::id()] = array_values(array_diff($tools, [Tools::ESLINT, Tools::STYLELINT, Tools::JEST])); + $test->prompts[CiProvider::id()] = CiProvider::GITHUB_ACTIONS; + $test->prompts[Theme::id()] = Theme::OLIVERO; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertFileDoesNotExist(static::$sut . '/package.json'); $test->assertFileDoesNotExist(static::$sut . '/yarn.lock'); $test->assertFileDoesNotExist(static::$sut . '/.eslintrc.json'); @@ -465,13 +463,13 @@ public static function dataProviderHandlerProcess(): \Iterator { }), ]; yield 'tools_groups_no_fe_lint_no_theme_circleci' => [ - static::cw(function (): void { + static::cw(function ($test): void { $tools = array_keys(Tools::getToolDefinitions('tools')); - Env::put(Tools::envName(), Converter::toList(array_diff($tools, [Tools::ESLINT, Tools::STYLELINT, Tools::JEST]))); - Env::put(CiProvider::envName(), CiProvider::CIRCLECI); - Env::put(Theme::envName(), Theme::OLIVERO); + $test->prompts[Tools::id()] = array_values(array_diff($tools, [Tools::ESLINT, Tools::STYLELINT, Tools::JEST])); + $test->prompts[CiProvider::id()] = CiProvider::CIRCLECI; + $test->prompts[Theme::id()] = Theme::OLIVERO; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertFileDoesNotExist(static::$sut . '/package.json'); $test->assertFileDoesNotExist(static::$sut . '/yarn.lock'); $test->assertFileDoesNotExist(static::$sut . '/.eslintrc.json'); @@ -489,13 +487,13 @@ public static function dataProviderHandlerProcess(): \Iterator { }), ]; yield 'tools_no_stylelint_no_theme' => [ - static::cw(function (): void { + static::cw(function ($test): void { $tools = array_keys(Tools::getToolDefinitions('tools')); - Env::put(Tools::envName(), Converter::toList(array_diff($tools, [Tools::STYLELINT]))); - Env::put(CiProvider::envName(), CiProvider::GITHUB_ACTIONS); - Env::put(Theme::envName(), Theme::OLIVERO); + $test->prompts[Tools::id()] = array_values(array_diff($tools, [Tools::STYLELINT])); + $test->prompts[CiProvider::id()] = CiProvider::GITHUB_ACTIONS; + $test->prompts[Theme::id()] = Theme::OLIVERO; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $pj = static::$sut . '/package.json'; $test->assertFileNotContainsString($pj, '"stylelint":'); $test->assertFileNotContainsString($pj, '"stylelint-config-standard":'); @@ -507,13 +505,13 @@ public static function dataProviderHandlerProcess(): \Iterator { }), ]; yield 'tools_no_eslint_no_theme' => [ - static::cw(function (): void { + static::cw(function ($test): void { $tools = array_keys(Tools::getToolDefinitions('tools')); - Env::put(Tools::envName(), Converter::toList(array_diff($tools, [Tools::ESLINT]))); - Env::put(CiProvider::envName(), CiProvider::GITHUB_ACTIONS); - Env::put(Theme::envName(), Theme::OLIVERO); + $test->prompts[Tools::id()] = array_values(array_diff($tools, [Tools::ESLINT])); + $test->prompts[CiProvider::id()] = CiProvider::GITHUB_ACTIONS; + $test->prompts[Theme::id()] = Theme::OLIVERO; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $pj = static::$sut . '/package.json'; $test->assertFileNotContainsString($pj, '"eslint":'); $test->assertFileNotContainsString($pj, '"eslint-config-airbnb-base":'); diff --git a/.vortex/installer/tests/Functional/Handlers/VersionSchemeHandlerProcessTest.php b/.vortex/installer/tests/Functional/Handlers/VersionSchemeHandlerProcessTest.php index 0167f12a2..57f625a5d 100644 --- a/.vortex/installer/tests/Functional/Handlers/VersionSchemeHandlerProcessTest.php +++ b/.vortex/installer/tests/Functional/Handlers/VersionSchemeHandlerProcessTest.php @@ -5,8 +5,6 @@ namespace DrevOps\VortexInstaller\Tests\Functional\Handlers; use DrevOps\VortexInstaller\Prompts\Handlers\VersionScheme; -use DrevOps\VortexInstaller\Tests\Functional\FunctionalTestCase; -use DrevOps\VortexInstaller\Utils\Env; use PHPUnit\Framework\Attributes\CoversClass; #[CoversClass(VersionScheme::class)] @@ -14,10 +12,10 @@ class VersionSchemeHandlerProcessTest extends AbstractHandlerProcessTestCase { public static function dataProviderHandlerProcess(): \Iterator { yield 'version_scheme_calver' => [ - static::cw(function (): void { - Env::put(VersionScheme::envName(), VersionScheme::CALVER); + static::cw(function ($test): void { + $test->prompts[VersionScheme::id()] = VersionScheme::CALVER; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertSutContains('Calendar Versioning'); $test->assertSutContains('calver.org'); $test->assertSutNotContains('Semantic Versioning'); @@ -25,10 +23,10 @@ public static function dataProviderHandlerProcess(): \Iterator { }), ]; yield 'version_scheme_semver' => [ - static::cw(function (): void { - Env::put(VersionScheme::envName(), VersionScheme::SEMVER); + static::cw(function ($test): void { + $test->prompts[VersionScheme::id()] = VersionScheme::SEMVER; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertSutContains('Semantic Versioning'); $test->assertSutContains('semver.org'); $test->assertSutNotContains('Calendar Versioning'); @@ -36,10 +34,10 @@ public static function dataProviderHandlerProcess(): \Iterator { }), ]; yield 'version_scheme_other' => [ - static::cw(function (): void { - Env::put(VersionScheme::envName(), VersionScheme::OTHER); + static::cw(function ($test): void { + $test->prompts[VersionScheme::id()] = VersionScheme::OTHER; }), - static::cw(function (FunctionalTestCase $test): void { + static::cw(function (AbstractHandlerProcessTestCase $test): void { $test->assertSutNotContains('Semantic Versioning'); $test->assertSutNotContains('semver.org'); $test->assertSutNotContains('Calendar Versioning'); diff --git a/.vortex/installer/tests/Unit/Schema/AgentHelpTest.php b/.vortex/installer/tests/Unit/Schema/AgentHelpTest.php index 9459085dc..a6fa52a3c 100644 --- a/.vortex/installer/tests/Unit/Schema/AgentHelpTest.php +++ b/.vortex/installer/tests/Unit/Schema/AgentHelpTest.php @@ -78,7 +78,6 @@ public function testRenderContainsSchemaFields(string $field): void { public static function dataProviderRenderContainsSchemaFields(): \Iterator { yield 'id field' => ['id']; - yield 'env field' => ['env']; yield 'type field' => ['type']; yield 'label field' => ['label']; yield 'options field' => ['options']; diff --git a/.vortex/installer/tests/Unit/Schema/SchemaGeneratorTest.php b/.vortex/installer/tests/Unit/Schema/SchemaGeneratorTest.php index d7190bbd3..5072d3003 100644 --- a/.vortex/installer/tests/Unit/Schema/SchemaGeneratorTest.php +++ b/.vortex/installer/tests/Unit/Schema/SchemaGeneratorTest.php @@ -48,8 +48,8 @@ protected function getSchema(): array { $prompt_manager = new PromptManager($config); static::$handlers = $prompt_manager->getHandlers(); - $generator = new SchemaGenerator(); - static::$schema = $generator->generate(static::$handlers); + $generator = new SchemaGenerator(static::$handlers); + static::$schema = $generator->generate(); } return static::$schema; @@ -66,7 +66,7 @@ public function testGenerateSchema(): void { public function testAllPromptsHaveRequiredFields(): void { $schema = $this->getSchema(); - $required_fields = ['id', 'env', 'type', 'label', 'required']; + $required_fields = ['id', 'type', 'label', 'required']; foreach ($schema['prompts'] as $index => $prompt) { foreach ($required_fields as $required_field) { @@ -145,14 +145,6 @@ public function testUtilityHandlersExcluded(): void { $this->assertNotContains('internal', $ids, 'Internal handler should be excluded.'); } - public function testEnvNameFormat(): void { - $schema = $this->getSchema(); - - foreach ($schema['prompts'] as $prompt) { - $this->assertMatchesRegularExpression('/^VORTEX_INSTALLER_PROMPT_[A-Z0-9_]+$/', $prompt['env'], sprintf('Env name for "%s" does not match expected format.', $prompt['id'])); - } - } - public function testSchemaStaysInSync(): void { $schema = $this->getSchema(); diff --git a/.vortex/installer/tests/Unit/Schema/ConfigValidatorTest.php b/.vortex/installer/tests/Unit/Schema/SchemaValidatorTest.php similarity index 66% rename from .vortex/installer/tests/Unit/Schema/ConfigValidatorTest.php rename to .vortex/installer/tests/Unit/Schema/SchemaValidatorTest.php index a368e6ab9..b0fa70045 100644 --- a/.vortex/installer/tests/Unit/Schema/ConfigValidatorTest.php +++ b/.vortex/installer/tests/Unit/Schema/SchemaValidatorTest.php @@ -19,18 +19,18 @@ use DrevOps\VortexInstaller\Prompts\Handlers\Starter; use DrevOps\VortexInstaller\Prompts\Handlers\Webroot; use DrevOps\VortexInstaller\Prompts\PromptManager; -use DrevOps\VortexInstaller\Schema\ConfigValidator; +use DrevOps\VortexInstaller\Schema\SchemaValidator; use DrevOps\VortexInstaller\Tests\Unit\UnitTestCase; use DrevOps\VortexInstaller\Utils\Config; use PHPUnit\Framework\Attributes\CoversClass; /** - * Tests for the ConfigValidator class. + * Tests for the SchemaValidator class. */ -#[CoversClass(ConfigValidator::class)] -class ConfigValidatorTest extends UnitTestCase { +#[CoversClass(SchemaValidator::class)] +class SchemaValidatorTest extends UnitTestCase { - protected ConfigValidator $validator; + protected SchemaValidator $validator; /** * @var array @@ -43,11 +43,10 @@ class ConfigValidatorTest extends UnitTestCase { protected function setUp(): void { parent::setUp(); - $this->validator = new ConfigValidator(); - $config = Config::fromString('{}'); $prompt_manager = new PromptManager($config); $this->handlers = $prompt_manager->getHandlers(); + $this->validator = new SchemaValidator($this->handlers); } public function testValidConfigPasses(): void { @@ -63,7 +62,7 @@ public function testValidConfigPasses(): void { HostingProjectName::id() => 'test-project', ]; - $result = $this->validator->validate($config, $this->handlers); + $result = $this->validator->validate($config); $this->assertTrue($result['valid']); $this->assertEmpty($result['errors']); @@ -74,7 +73,7 @@ public function testInvalidSelectValue(): void { HostingProvider::id() => 'aws', ]; - $result = $this->validator->validate($config, $this->handlers); + $result = $this->validator->validate($config); $this->assertFalse($result['valid']); @@ -99,7 +98,7 @@ public function testInvalidMultiselectValue(): void { 'services' => ['nonexistent_service'], ]; - $result = $this->validator->validate($config, $this->handlers); + $result = $this->validator->validate($config); $this->assertFalse($result['valid']); @@ -107,17 +106,15 @@ public function testInvalidMultiselectValue(): void { $this->assertContains('services', $error_prompts); } - public function testMissingRequiredField(): void { - // Name is required. Provide empty config. + public function testEmptyConfigIsValid(): void { $config = []; - $result = $this->validator->validate($config, $this->handlers); + $result = $this->validator->validate($config); - // Should have errors for required fields that don't have defaults. - // Name is required but has a default via default(), so it may resolve. - // HostingProvider is required and has a default, so it resolves. - // Check that resolved includes defaults. - $this->assertArrayHasKey('resolved', $result); + // Empty config is valid — prompts not provided are skipped. + $this->assertTrue($result['valid']); + $this->assertEmpty($result['errors']); + $this->assertEmpty($result['resolved']); } public function testDependencyMetValueProvided(): void { @@ -126,7 +123,7 @@ public function testDependencyMetValueProvided(): void { DatabaseDownloadSource::id() => DatabaseDownloadSource::URL, ]; - $result = $this->validator->validate($config, $this->handlers); + $result = $this->validator->validate($config); // DatabaseDownloadSource depends on ProvisionType=database. // Both provided and condition met = OK. @@ -141,7 +138,7 @@ public function testDependencyNotMetValueProvided(): void { DatabaseDownloadSource::id() => DatabaseDownloadSource::URL, ]; - $result = $this->validator->validate($config, $this->handlers); + $result = $this->validator->validate($config); // DatabaseDownloadSource depends on ProvisionType=database. // ProvisionType=profile means condition not met + value provided = warning. @@ -154,12 +151,13 @@ public function testDependencyMetValueMissing(): void { Migration::id() => TRUE, ]; - $result = $this->validator->validate($config, $this->handlers); + $result = $this->validator->validate($config); // MigrationDownloadSource depends on Migration=true. - // Condition met + no value provided. It's not marked as required though, - // so it should use the default. - $this->assertArrayHasKey('resolved', $result); + // Condition met + no value provided + not required = OK (skip). + $this->assertTrue($result['valid']); + $error_prompts = array_column($result['errors'], 'prompt'); + $this->assertNotContains(MigrationDownloadSource::id(), $error_prompts); } public function testDependencyNotMetValueMissing(): void { @@ -167,7 +165,7 @@ public function testDependencyNotMetValueMissing(): void { Migration::id() => FALSE, ]; - $result = $this->validator->validate($config, $this->handlers); + $result = $this->validator->validate($config); // MigrationDownloadSource depends on Migration=true. // Condition not met + no value provided = OK (skip). @@ -180,7 +178,7 @@ public function testSystemDependencySkipped(): void { Starter::id() => Starter::LOAD_DATABASE_DEMO, ]; - $result = $this->validator->validate($config, $this->handlers); + $result = $this->validator->validate($config); // Starter has a _system dependency which should be skipped. $error_prompts = array_column($result['errors'], 'prompt'); @@ -189,39 +187,19 @@ public function testSystemDependencySkipped(): void { $this->assertSame(Starter::LOAD_DATABASE_DEMO, $result['resolved'][Starter::id()] ?? NULL); } - public function testResolvedShowsDefaults(): void { - $config = []; - - $result = $this->validator->validate($config, $this->handlers); - - // Handlers with defaults should appear in resolved. - $this->assertArrayHasKey('resolved', $result); - - // HostingProvider has a default of 'none'. - $this->assertSame(HostingProvider::NONE, $result['resolved'][HostingProvider::id()] ?? NULL); - - // Migration has a default of FALSE. - $this->assertSame(FALSE, $result['resolved'][Migration::id()] ?? NULL); - } - - public function testConfigWithEnvVarNames(): void { + public function testResolvedOnlyContainsProvidedValues(): void { $config = [ - 'VORTEX_INSTALLER_PROMPT_NAME' => 'Test Site', - 'VORTEX_INSTALLER_PROMPT_MACHINE_NAME' => 'test_site', - 'VORTEX_INSTALLER_PROMPT_ORG' => 'Test Org', - 'VORTEX_INSTALLER_PROMPT_ORG_MACHINE_NAME' => 'test_org', - 'VORTEX_INSTALLER_PROMPT_DOMAIN' => 'test-site.com', - 'VORTEX_INSTALLER_PROMPT_MODULE_PREFIX' => 'test_site', - 'VORTEX_INSTALLER_PROMPT_WEBROOT' => 'web', - 'VORTEX_INSTALLER_PROMPT_HOSTING_PROVIDER' => HostingProvider::LAGOON, - 'VORTEX_INSTALLER_PROMPT_HOSTING_PROJECT_NAME' => 'test-site', + HostingProvider::id() => HostingProvider::LAGOON, + HostingProjectName::id() => 'test-project', ]; - $result = $this->validator->validate($config, $this->handlers); + $result = $this->validator->validate($config); $this->assertTrue($result['valid']); - $this->assertSame('Test Site', $result['resolved'][Name::id()] ?? NULL); - $this->assertSame(HostingProvider::LAGOON, $result['resolved'][HostingProvider::id()] ?? NULL); + $this->assertSame(HostingProvider::LAGOON, $result['resolved'][HostingProvider::id()]); + $this->assertSame('test-project', $result['resolved'][HostingProjectName::id()]); + // Unprovided prompts should not appear in resolved. + $this->assertArrayNotHasKey(Migration::id(), $result['resolved']); } public function testConfirmWithNonBoolValue(): void { @@ -229,7 +207,7 @@ public function testConfirmWithNonBoolValue(): void { Migration::id() => 'yes', ]; - $result = $this->validator->validate($config, $this->handlers); + $result = $this->validator->validate($config); $this->assertFalse($result['valid']); diff --git a/.vortex/tests/phpunit/Functional/AhoyWorkflowTest.php b/.vortex/tests/phpunit/Functional/AhoyWorkflowTest.php index d2a11c73c..8c7c6d8d1 100644 --- a/.vortex/tests/phpunit/Functional/AhoyWorkflowTest.php +++ b/.vortex/tests/phpunit/Functional/AhoyWorkflowTest.php @@ -19,6 +19,7 @@ protected function setUp(): void { parent::setUp(); static::$sutInstallerEnv = []; + static::$sutInstallerPrompts = []; $this->dockerCleanup(); } @@ -138,9 +139,9 @@ public function testAhoyBuildIdempotence(): void { #[Group('p4')] public function testAhoyWorkflowDatabaseFromImageStorageInImage(): void { - static::$sutInstallerEnv = [ - 'VORTEX_INSTALLER_PROMPT_DATABASE_DOWNLOAD_SOURCE' => 'container_registry', - 'VORTEX_INSTALLER_PROMPT_DATABASE_IMAGE' => self::VORTEX_DB_IMAGE_TEST, + static::$sutInstallerPrompts = [ + 'database_download_source' => 'container_registry', + 'database_image' => self::VORTEX_DB_IMAGE_TEST, ]; $this->prepareSut(); $this->adjustAhoyForUnmountedVolumes(); @@ -212,9 +213,9 @@ public function testAhoyWorkflowDatabaseFromImageStorageInImage(): void { #[Group('p1')] public function testAhoyWorkflowProfileStandard(): void { - static::$sutInstallerEnv = [ - 'VORTEX_INSTALLER_PROMPT_STARTER' => 'install_profile_core', - 'VORTEX_INSTALLER_PROMPT_PROVISION_TYPE' => 'profile', + static::$sutInstallerPrompts = [ + 'starter' => 'install_profile_core', + 'provision_type' => 'profile', ]; $this->prepareSut(); $this->adjustAhoyForUnmountedVolumes(); @@ -238,9 +239,9 @@ public function testAhoyWorkflowProfileStandard(): void { #[Group('p4')] public function testAhoyWorkflowProfileDrupalCms(): void { - static::$sutInstallerEnv = [ - 'VORTEX_INSTALLER_PROMPT_STARTER' => 'install_profile_drupalcms', - 'VORTEX_INSTALLER_PROMPT_PROVISION_TYPE' => 'profile', + static::$sutInstallerPrompts = [ + 'starter' => 'install_profile_drupalcms', + 'provision_type' => 'profile', ]; $this->prepareSut(); $this->adjustAhoyForUnmountedVolumes(); @@ -270,8 +271,10 @@ public function testAhoyWorkflowProfileDrupalCms(): void { public function testAhoyWorkflowMigration(): void { static::$sutInstallerEnv = [ 'VORTEX_INSTALLER_IS_DEMO' => '1', - 'VORTEX_INSTALLER_PROMPT_MIGRATION' => 'true', - 'VORTEX_INSTALLER_PROMPT_MIGRATION_DOWNLOAD_SOURCE' => 'url', + ]; + static::$sutInstallerPrompts = [ + 'migration' => TRUE, + 'migration_download_source' => 'url', ]; $this->prepareSut(); $this->adjustAhoyForUnmountedVolumes(); @@ -296,9 +299,11 @@ public function testAhoyWorkflowMigration(): void { public function testAhoyWorkflowMigrationDatabaseFromImage(): void { static::$sutInstallerEnv = [ 'VORTEX_INSTALLER_IS_DEMO' => '1', - 'VORTEX_INSTALLER_PROMPT_MIGRATION' => 'true', - 'VORTEX_INSTALLER_PROMPT_MIGRATION_DOWNLOAD_SOURCE' => 'container_registry', - 'VORTEX_INSTALLER_PROMPT_MIGRATION_IMAGE' => self::VORTEX_DB_IMAGE_TEST, + ]; + static::$sutInstallerPrompts = [ + 'migration' => TRUE, + 'migration_download_source' => 'container_registry', + 'migration_image' => self::VORTEX_DB_IMAGE_TEST, ]; $this->prepareSut(); $this->adjustAhoyForUnmountedVolumes(); diff --git a/.vortex/tests/phpunit/Functional/DeploymentTest.php b/.vortex/tests/phpunit/Functional/DeploymentTest.php index 180fda0ab..983bdf767 100644 --- a/.vortex/tests/phpunit/Functional/DeploymentTest.php +++ b/.vortex/tests/phpunit/Functional/DeploymentTest.php @@ -21,6 +21,7 @@ protected function setUp(): void { parent::setUp(); static::$sutInstallerEnv = []; + static::$sutInstallerPrompts = []; $this->dockerCleanup(); } @@ -205,8 +206,9 @@ public function testDeploymentArtifact(): void { static::$sutInstallerEnv = [ 'VORTEX_INSTALLER_IS_DEMO' => '1', - // Add trailing comma to simulate list input. - 'VORTEX_INSTALLER_PROMPT_DEPLOY_TYPES' => 'artifact,', + ]; + static::$sutInstallerPrompts = [ + 'deploy_types' => ['artifact'], ]; $this->logSubstep('Prepare SUT with full build'); diff --git a/.vortex/tests/phpunit/Functional/DockerComposeWorkflowTest.php b/.vortex/tests/phpunit/Functional/DockerComposeWorkflowTest.php index 71acdba17..c75ed6609 100644 --- a/.vortex/tests/phpunit/Functional/DockerComposeWorkflowTest.php +++ b/.vortex/tests/phpunit/Functional/DockerComposeWorkflowTest.php @@ -19,6 +19,7 @@ protected function setUp(): void { parent::setUp(); static::$sutInstallerEnv = []; + static::$sutInstallerPrompts = []; // Docker Compose tests replicate read-only environments. $this->forceVolumesUnmounted(); @@ -68,7 +69,7 @@ public function testDockerComposeWorkflowFull(): void { #[Group('p0')] public function testDockerComposeWorkflowNoTheme(): void { - static::$sutInstallerEnv = ['VORTEX_INSTALLER_PROMPT_THEME' => 'olivero']; + static::$sutInstallerPrompts = ['theme' => 'olivero']; $this->prepareSut(); $this->logSubstep('Building stack with Docker Compose'); diff --git a/.vortex/tests/phpunit/Functional/InstallerTest.php b/.vortex/tests/phpunit/Functional/InstallerTest.php index 7a6ce5de0..a2fa9b1ea 100644 --- a/.vortex/tests/phpunit/Functional/InstallerTest.php +++ b/.vortex/tests/phpunit/Functional/InstallerTest.php @@ -19,6 +19,7 @@ protected function setUp(): void { parent::setUp(); static::$sutInstallerEnv = []; + static::$sutInstallerPrompts = []; // For test performance, we only export the current codebase without git // history in the parent::setUp(). For these test, though, we need git diff --git a/.vortex/tests/phpunit/Traits/SutTrait.php b/.vortex/tests/phpunit/Traits/SutTrait.php index ffa8aca76..f1b387342 100644 --- a/.vortex/tests/phpunit/Traits/SutTrait.php +++ b/.vortex/tests/phpunit/Traits/SutTrait.php @@ -43,6 +43,15 @@ trait SutTrait { */ protected static $sutInstallerEnv = []; + /** + * Prompt values to pass via --prompts option. + * + * Keyed by handler ID with proper PHP types. + * + * @var array + */ + protected static array $sutInstallerPrompts = []; + protected function prepareSut(string $webroot = 'web'): void { $this->logStepStart(); @@ -86,6 +95,10 @@ protected function runInstaller(array $arguments = []): void { // ProcessTrait::processParseCommand() is fixed. $cmd = sprintf('php .vortex/installer/installer.php --no-interaction --destination=%s', escapeshellarg(static::locationsSut())); + if (!empty(static::$sutInstallerPrompts)) { + $cmd .= ' --prompts=' . escapeshellarg((string) json_encode(static::$sutInstallerPrompts)); + } + $this->logNote('Run the installer script'); $this->cmd( $cmd,