From 766be8db0c74e163436776a8e8d3a77074e6c09e Mon Sep 17 00:00:00 2001 From: Jerry Radwick Date: Wed, 25 Dec 2024 07:33:45 -0500 Subject: [PATCH] Run project-specific Drall during tests --- .docker/main/.profile | 1 + .docker/main/Dockerfile | 8 +- .docker/main/{ => drupal}/composer.json | 8 +- .../{ => drupal}/drush/sites/donnie.site.yml | 0 .../{ => drupal}/drush/sites/leo.site.yml | 0 .../{ => drupal}/drush/sites/mikey.site.yml | 0 .../{ => drupal}/drush/sites/ralph.site.yml | 0 .../{ => drupal}/drush/sites/tmnt.site.yml | 0 .docker/main/drupal/web/sites/sites.bad.php | 9 + .../{ => drupal/web}/sites/sites.bluish.php | 0 .docker/main/{ => drupal/web}/sites/sites.php | 0 .../{ => drupal/web}/sites/sites.reddish.php | 0 .docker/main/empty-drupal/composer.json | 76 ++++ .docker/main/empty-drupal/web/sites/sites.php | 3 + .docker/main/no-drupal/composer.json | 29 ++ .github/workflows/validation.yml | 3 - Makefile | 53 ++- bin/drall-launcher | 17 + docker-compose.yml | 8 +- src/IntegrationTestCase.php | 24 -- src/Service/SiteDetector.php | 12 +- src/TestCase.php | 63 +-- test/Integration/Command/ExecCommandTest.php | 373 ++++++++++++++---- .../Command/SiteAliasesCommandTest.php | 66 +++- .../Command/SiteDirectoriesCommandTest.php | 58 ++- .../Command/SiteKeysCommandTest.php | 58 ++- test/Integration/DrallTest.php | 23 +- test/Unit/Command/ExecCommandTest.php | 177 --------- test/Unit/Command/SiteAliasesCommandTest.php | 100 ----- .../Command/SiteDirectoriesCommandTest.php | 99 ----- test/Unit/Command/SiteKeysCommandTest.php | 114 ------ test/Unit/IntegrationTestCaseTest.php | 23 -- test/Unit/Model/SitesFileTest.php | 14 +- test/Unit/Service/SiteDetectorTest.php | 53 ++- test/Unit/TestCaseTest.php | 41 +- test/fixtures/sites.valid.php | 2 +- 36 files changed, 670 insertions(+), 845 deletions(-) create mode 100644 .docker/main/.profile rename .docker/main/{ => drupal}/composer.json (86%) rename .docker/main/{ => drupal}/drush/sites/donnie.site.yml (100%) rename .docker/main/{ => drupal}/drush/sites/leo.site.yml (100%) rename .docker/main/{ => drupal}/drush/sites/mikey.site.yml (100%) rename .docker/main/{ => drupal}/drush/sites/ralph.site.yml (100%) rename .docker/main/{ => drupal}/drush/sites/tmnt.site.yml (100%) create mode 100644 .docker/main/drupal/web/sites/sites.bad.php rename .docker/main/{ => drupal/web}/sites/sites.bluish.php (100%) rename .docker/main/{ => drupal/web}/sites/sites.php (100%) rename .docker/main/{ => drupal/web}/sites/sites.reddish.php (100%) create mode 100644 .docker/main/empty-drupal/composer.json create mode 100644 .docker/main/empty-drupal/web/sites/sites.php create mode 100644 .docker/main/no-drupal/composer.json create mode 100755 bin/drall-launcher delete mode 100644 src/IntegrationTestCase.php delete mode 100644 test/Unit/Command/ExecCommandTest.php delete mode 100644 test/Unit/Command/SiteAliasesCommandTest.php delete mode 100644 test/Unit/Command/SiteDirectoriesCommandTest.php delete mode 100644 test/Unit/Command/SiteKeysCommandTest.php delete mode 100644 test/Unit/IntegrationTestCaseTest.php diff --git a/.docker/main/.profile b/.docker/main/.profile new file mode 100644 index 0000000..00ec130 --- /dev/null +++ b/.docker/main/.profile @@ -0,0 +1 @@ +PATH=$(echo "$PATH" | sed -e "s/:\/opt\/drupal\/vendor\/bin//") diff --git a/.docker/main/Dockerfile b/.docker/main/Dockerfile index 7542749..50d6664 100644 --- a/.docker/main/Dockerfile +++ b/.docker/main/Dockerfile @@ -13,8 +13,10 @@ RUN cp "$PHP_INI_DIR/php.ini-development" "$PHP_INI_PATH" \ RUN docker-php-ext-configure pcntl --enable-pcntl \ && docker-php-ext-install pcntl -# Provision Drall. COPY . /opt/drall - -# Provision Drupal. COPY Makefile /opt/drupal/Makefile +COPY Makefile /opt/no-drupal/Makefile +COPY Makefile /opt/empty-drupal/Makefile + +RUN echo ". /opt/drall/.docker/main/.profile" >> /root/.profile +RUN echo ". /opt/drall/.docker/main/.profile" >> /root/.bashrc diff --git a/.docker/main/composer.json b/.docker/main/drupal/composer.json similarity index 86% rename from .docker/main/composer.json rename to .docker/main/drupal/composer.json index c1f07ed..eacd408 100644 --- a/.docker/main/composer.json +++ b/.docker/main/drupal/composer.json @@ -1,13 +1,7 @@ { - "name": "jigarius/drall-demo", - "description": "A Drupal demo site for developing and testing Drall.", + "description": "A Drupal multi-site installation for developing and testing Drall.", "type": "project", "license": "GPL-2.0-or-later", - "homepage": "https://www.drupal.org/project/drupal", - "support": { - "docs": "https://www.drupal.org/docs/user_guide/en/index.html", - "chat": "https://www.drupal.org/node/314178" - }, "repositories": [ { "type": "composer", diff --git a/.docker/main/drush/sites/donnie.site.yml b/.docker/main/drupal/drush/sites/donnie.site.yml similarity index 100% rename from .docker/main/drush/sites/donnie.site.yml rename to .docker/main/drupal/drush/sites/donnie.site.yml diff --git a/.docker/main/drush/sites/leo.site.yml b/.docker/main/drupal/drush/sites/leo.site.yml similarity index 100% rename from .docker/main/drush/sites/leo.site.yml rename to .docker/main/drupal/drush/sites/leo.site.yml diff --git a/.docker/main/drush/sites/mikey.site.yml b/.docker/main/drupal/drush/sites/mikey.site.yml similarity index 100% rename from .docker/main/drush/sites/mikey.site.yml rename to .docker/main/drupal/drush/sites/mikey.site.yml diff --git a/.docker/main/drush/sites/ralph.site.yml b/.docker/main/drupal/drush/sites/ralph.site.yml similarity index 100% rename from .docker/main/drush/sites/ralph.site.yml rename to .docker/main/drupal/drush/sites/ralph.site.yml diff --git a/.docker/main/drush/sites/tmnt.site.yml b/.docker/main/drupal/drush/sites/tmnt.site.yml similarity index 100% rename from .docker/main/drush/sites/tmnt.site.yml rename to .docker/main/drupal/drush/sites/tmnt.site.yml diff --git a/.docker/main/drupal/web/sites/sites.bad.php b/.docker/main/drupal/web/sites/sites.bad.php new file mode 100644 index 0000000..deb86af --- /dev/null +++ b/.docker/main/drupal/web/sites/sites.bad.php @@ -0,0 +1,9 @@ +> $GITHUB_PATH - name: Determine Composer Cache Directory id: composer-cache run: | diff --git a/Makefile b/Makefile index 64dac0d..7cb631c 100644 --- a/Makefile +++ b/Makefile @@ -4,18 +4,23 @@ ssh: .PHONY: provision -provision: provision/drall provision/drupal +provision: provision/env provision/drall provision/no-drupal provision/empty-drupal provision/drupal + + +.PHONY: provision/env +provision/env: + cp /opt/drall/bin/drall-launcher /usr/local/bin/drall .PHONY: provision/drupal provision/drupal: mkdir -p /opt/drupal - cp /opt/drall/.docker/main/composer.json /opt/drupal/ || echo "Skipping drupal/composer.json" + + cp /opt/drall/.docker/main/drupal/composer.json /opt/drupal/ || echo "Skipping: drupal/composer.json" rm -f /opt/drupal/composer.lock composer --working-dir=/opt/drupal install --no-progress - - cp -r /opt/drall/.docker/main/drush /opt/drupal/ || echo "Skipping drush directory." - cp -r /opt/drall/.docker/main/sites /opt/drupal/web/ || echo "Skipping sites directory." + cp -r /opt/drall/.docker/main/drupal/drush /opt/drupal/ || echo "Skipping: drupal/drush" + cp -r /opt/drall/.docker/main/drupal/web/sites /opt/drupal/web/ || echo "Skipping: drupal/web/sites" mkdir -p /opt/drupal/web/sites/default mkdir -p /opt/drupal/web/sites/donnie @@ -29,9 +34,27 @@ provision/drupal: cp /opt/drupal/web/sites/default/default.settings.php /opt/drupal/web/sites/mikey/settings.php cp /opt/drupal/web/sites/default/default.settings.php /opt/drupal/web/sites/ralph/settings.php + @echo '' @echo 'Drupal databases can be provisioned with: make provision/drupal/database' +.PHONY: provision/no-drupal +provision/no-drupal: + mkdir -p /opt/no-drupal + cp /opt/drall/.docker/main/no-drupal/composer.json /opt/no-drupal/ || echo "Skipping: no-drupal/composer.json" + rm -f /opt/no-drupal/composer.lock + composer --working-dir=/opt/no-drupal install --no-progress + + +.PHONY: provision/empty-drupal +provision/empty-drupal: + mkdir -p /opt/empty-drupal + cp /opt/drall/.docker/main/empty-drupal/composer.json /opt/empty-drupal/ || echo "Skipping: empty-drupal/composer.json" + rm -f /opt/empty-drupal/composer.lock + composer --working-dir=/opt/empty-drupal install --no-progress + cp /opt/drall/.docker/main/empty-drupal/web/sites/sites.php /opt/empty-drupal/web/sites/sites.php + + .PHONY: provision/drupal/database provision/drupal/database: rm -f web/sites/*/settings.php @@ -56,17 +79,14 @@ provision/drupal/database: provision/drall: composer install --working-dir=/opt/drall --no-progress - # The GitHub Action shivammathur/setup-php@v2 gives higher priority to - # the executables present in /opt/drall/vendor/bin. Thus, we remove - # Drush from this directory to force /opt/drupal/vendor/bin/drush. - rm -f /opt/drall/vendor/bin/drush - # Due to the way Composer works, jigarius/drall cannot be symlinked into # the Drupal setup used for development. Thus, after every change made to # Drall, it must be re-installed inside the Drupal installation. .PHONY: refresh refresh: + rsync -Ervu --inplace --delete --exclude=.coverage --exclude=.phpunit.cache --exclude=.idea --exclude=.git --exclude=vendor /opt/drall/ /opt/no-drupal/vendor/jigarius/drall/ + rsync -Ervu --inplace --delete --exclude=.coverage --exclude=.phpunit.cache --exclude=.idea --exclude=.git --exclude=vendor /opt/drall/ /opt/empty-drupal/vendor/jigarius/drall/ rsync -Ervu --inplace --delete --exclude=.coverage --exclude=.phpunit.cache --exclude=.idea --exclude=.git --exclude=vendor /opt/drall/ /opt/drupal/vendor/jigarius/drall/ @@ -92,17 +112,8 @@ test: .PHONY: info info: - @cd $(DRUPAL_PATH) + @echo "Path: $(PATH)" + @echo "PWD: $(PWD)" @echo "Drupal path: $(DRUPAL_PATH)" - - which php - @php --version - - which composer @composer --version - - which drush - @drush --version - which drall - @drall --version diff --git a/bin/drall-launcher b/bin/drall-launcher new file mode 100755 index 0000000..29b7c05 --- /dev/null +++ b/bin/drall-launcher @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +set -e + +dir=$(pwd) +while [ "$dir" != "/" ]; do + if [ -x "$dir/vendor/bin/drall" ]; then + "$dir/vendor/bin/drall" "$@" + break + fi + dir=$(dirname "$dir") +done + +if [ "$dir" == "/" ]; then + echo "Drall executable not found." + exit 1 +fi diff --git a/docker-compose.yml b/docker-compose.yml index 4645951..a1d8a2f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,11 +11,9 @@ services: - "8080:80" volumes: - .:/opt/drall - - .docker/main/sites/sites.php:/opt/drupal/web/sites/sites.php - - .docker/main/sites/sites.reddish.php:/opt/drupal/web/sites/sites.reddish.php - - .docker/main/sites/sites.bluish.php:/opt/drupal/web/sites/sites.bluish.php - - .docker/main/composer.json:/opt/drupal/composer.json - - .docker/main/drush:/opt/drupal/drush + - .docker/main/drupal/composer.json:/opt/drupal/composer.json + - ./Makefile:/opt/no-drupal/Makefile + - ./Makefile:/opt/empty-drupal/Makefile - ./Makefile:/opt/drupal/Makefile environment: - DRALL_ENVIRONMENT=development diff --git a/src/IntegrationTestCase.php b/src/IntegrationTestCase.php deleted file mode 100644 index d14560b..0000000 --- a/src/IntegrationTestCase.php +++ /dev/null @@ -1,24 +0,0 @@ -assertEquals($expected, $actual, $message); - } - -} diff --git a/src/Service/SiteDetector.php b/src/Service/SiteDetector.php index abebd99..64d334b 100644 --- a/src/Service/SiteDetector.php +++ b/src/Service/SiteDetector.php @@ -105,6 +105,10 @@ public function getSiteAliases( ?string $group = NULL, ?string $filter = NULL, ): array { + // Use Drupal Finder to ensure that the Drupal is installed. This ensures + // consistency in errors raised by methods that depend on sites.*.php. + $this->drupalFinder()->getDrupalRoot(); + $result = array_values($this->siteAliasManager()->getMultiple()); if ($group) { @@ -158,13 +162,7 @@ public function getSiteAliasNames( * Path/to/drush. */ public function getDrushPath(): string { - if (!$vendorDir = $this->drupalFinder->getVendorDir()) { - // This should only happen when drall is installed globally and not in a - // specific Drupal project. - return 'drush'; - } - - return "$vendorDir/bin/drush"; + return $this->drupalFinder->getVendorDir() . "/bin/drush"; } private function getSitesFile($group = NULL): ?SitesFile { diff --git a/src/TestCase.php b/src/TestCase.php index 8051bf4..1bd141b 100644 --- a/src/TestCase.php +++ b/src/TestCase.php @@ -10,51 +10,15 @@ */ abstract class TestCase extends TestCaseBase { - /** - * Original current working directory. - * - * @var string - */ - protected string $cwd = '/'; + const PATH_PROJECT = '/opt/drall'; - protected function setUp(): void { - $this->cwd = getcwd(); - chdir($this->drupalDir()); - } + const PATH_FIXTURES = '/opt/drall/test/fixtures'; - protected function tearDown(): void { - chdir($this->cwd); - } + const PATH_DRUPAL = '/opt/drupal'; - /** - * Get the path to the Drupal project root. - * - * @return string - * /path/to/drupal. - */ - protected function drupalDir(): string { - return getenv('DRUPAL_PATH'); - } - - /** - * Get the path to the project's root directory. - * - * @return string - * /path/to/root. - */ - protected function projectDir(): string { - return dirname(__DIR__); - } + const PATH_NO_DRUPAL = '/opt/no-drupal'; - /** - * Get the path to the fixtures directory. - * - * @return string - * /path/to/fixtures. - */ - protected function fixturesDir(): string { - return dirname(__DIR__) . '/test/fixtures'; - } + const PATH_EMPTY_DRUPAL = '/opt/empty-drupal'; /** * Creates a temporary file path. @@ -85,7 +49,7 @@ protected function createTempFile(string $data): string { } protected function createDrupalFinderStub(?string $root = NULL): DrupalFinderComposerRuntime { - $root ??= $this->drupalDir(); + $root ??= static::PATH_DRUPAL; $drupalFinder = $this->createStub(DrupalFinderComposerRuntime::class); $drupalFinder->method('getComposerRoot')->willReturn($root); $drupalFinder->method('getDrupalRoot')->willReturn("$root/web"); @@ -93,4 +57,19 @@ protected function createDrupalFinderStub(?string $root = NULL): DrupalFinderCom return $drupalFinder; } + /** + * Asserts Shell output ignoring unimportant whitespace. + * + * @param string $expected + * Expected output. + * @param mixed $actual + * Actual output. + * @param string $message + * Error message. + */ + protected function assertOutputEquals(string $expected, mixed $actual, string $message = ''): void { + $actual = preg_replace('@(\s+)\n@', "\n", $actual ?? ''); + $this->assertEquals($expected, $actual, $message); + } + } diff --git a/test/Integration/Command/ExecCommandTest.php b/test/Integration/Command/ExecCommandTest.php index 5c58fcd..58f1585 100644 --- a/test/Integration/Command/ExecCommandTest.php +++ b/test/Integration/Command/ExecCommandTest.php @@ -1,55 +1,92 @@ markTestSkipped('Needs work.'); + $process = Process::fromShellCommandline( + 'drall exec ./vendor/bin/drush --uri=@@dir core:status', + static::PATH_NO_DRUPAL, + ); + $process->run(); + $this->assertStringContainsString('Package "drupal/core" is not installed', $process->getErrorOutput()); + + $process = Process::fromShellCommandline( + 'drall exec ./vendor/bin/drush @@site.local core:status', + static::PATH_NO_DRUPAL, + ); + $process->run(); + $this->assertStringContainsString('Package "drupal/core" is not installed', $process->getErrorOutput()); + } - chdir('/tmp'); - $output = shell_exec('drall exec drush --uri=@@dir core:status'); - $this->assertOutputEquals('[warning] No Drupal sites found.' . PHP_EOL, $output); + /** + * @testdox With an empty Drupal installation. + */ + public function testWithEmptyDrupal(): void { + $process = Process::fromShellCommandline( + 'drall exec ./vendor/bin/drush --uri=@@dir core:status', + static::PATH_EMPTY_DRUPAL, + ); + $process->run(); + $this->assertOutputEquals('[warning] No Drupal sites found.' . PHP_EOL, $process->getOutput()); - $output = shell_exec('drall exec drush @@site.local core:status'); - $this->assertOutputEquals('[warning] No Drupal sites found.' . PHP_EOL, $output); + $process = Process::fromShellCommandline( + 'drall exec ./vendor/bin/drush @@site.local core:status', + static::PATH_EMPTY_DRUPAL, + ); + $process->run(); + $this->assertOutputEquals('[warning] No Drupal sites found.' . PHP_EOL, $process->getOutput()); } /** - * Run a command that has no placeholders. + * @testdox With no placeholders. */ public function testWithNoPlaceholders(): void { - $output = shell_exec('drall exec foo 2>&1'); + $process = Process::fromShellCommandline('drall exec foo', static::PATH_DRUPAL); + $process->run(); $this->assertOutputEquals( '[error] The command contains no placeholders. Please run it directly without Drall.' . PHP_EOL, - $output + $process->getErrorOutput(), ); } + /** + * @testdox Working directory. + */ public function testWorkingDirectory(): void { - $output = shell_exec('drall exec --drall-filter=tmnt "echo \"Site: @@site\" && pwd && which drush"'); + $process = Process::fromShellCommandline( + 'drall exec --drall-filter=tmnt "echo \"Site: @@site\" && pwd"', + static::PATH_DRUPAL, + ); + $process->run(); $this->assertOutputEquals(<<getOutput()); } /** - * Run drush command with @@dir. + * @testdox With @@dir. */ public function testDrushWithUriPlaceholder(): void { - $output = shell_exec('drall exec drush --uri=@@dir core:status --fields=site'); + $process = Process::fromShellCommandline( + 'drall exec ./vendor/bin/drush --uri=@@dir core:status --fields=site', + static::PATH_DRUPAL, + ); + $process->run(); $this->assertOutputEquals(<<getOutput()); } /** - * Run drush command with @@site. + * @testdox With @@site. */ public function testDrushWithSitePlaceholder(): void { - $output = shell_exec('drall exec drush @@site.local core:status --fields=site'); + $process = Process::fromShellCommandline( + 'drall exec ./vendor/bin/drush @@site.local core:status --fields=site', + static::PATH_DRUPAL, + ); + $process->run(); $this->assertOutputEquals(<<getOutput()); } /** - * Run drush command with no placeholders. + * @testdox With no placeholders. */ public function testDrushWithNoPlaceholders(): void { - $output = shell_exec('drall exec drush core:status --fields=site'); + $process = Process::fromShellCommandline( + 'drall exec ./vendor/bin/drush core:status --fields=site', + static::PATH_DRUPAL, + ); + $process->run(); $this->assertOutputEquals(<<getOutput()); } /** - * Run multiple drush commands with no placeholders. + * @testdox With multiple drush commands and no placeholders. */ public function testMultipleDrushWithNoPlaceholders(): void { - $output = shell_exec('drall exec "drush st --fields=site; drush st --fields=uri"'); + $process = Process::fromShellCommandline( + 'drall exec "./vendor/bin/drush st --fields=site; ./vendor/bin/drush st --fields=uri"', + static::PATH_DRUPAL, + ); + $process->run(); $this->assertOutputEquals(<<getOutput()); } /** - * Run drush with no placeholders, but "drush" is present in a path. - * - * Drall only appends --uri to "drush" have a whitespace right after. + * @testdox With no placeholders and "drush" present in a path. */ public function testDrushInPath(): void { - $output = shell_exec('drall exec ls ./vendor/drush/src 2>&1'); + $process = Process::fromShellCommandline( + 'drall exec ls ./vendor/drush/src', + static::PATH_DRUPAL, + ); + $process->run(); $this->assertOutputEquals( '[error] The command contains no placeholders. Please run it directly without Drall.' . PHP_EOL, - $output + $process->getErrorOutput(), ); } /** - * Run command with Drush that's capitalized. + * @testdox With Drush capitalized. * * If for some reason someone needs to write the word Drush, it won't be * appended with --uri if it is capitalized. */ public function testDrushCapitalized(): void { - $output = shell_exec('drall exec "echo \"Drush status\" && drush st --fields=site"'); + $process = Process::fromShellCommandline( + 'drall exec "echo \"Drush status\" && ./vendor/bin/drush st --fields=site"', + static::PATH_DRUPAL, + ); + $process->run(); $this->assertOutputEquals(<<getOutput()); } /** - * A command with mixed placeholders causes an error. + * @testdox With mixed placeholders. */ public function testWithMixedPlaceholders(): void { - chdir('/tmp'); - $output = shell_exec('drall exec "drush --uri=@@dir core:status && drush @@site.local core:status" 2>&1'); + $process = Process::fromShellCommandline( + 'drall exec "./vendor/bin/drush --uri=@@dir st && ./vendor/bin/drush @@site.local st"', + static::PATH_DRUPAL, + ); + $process->run(); $this->assertOutputEquals( '[error] The command contains: @@site, @@dir. Please use only one.' . PHP_EOL, - $output + $process->getErrorOutput(), ); } - public function testWithUriPlaceholder(): void { - $output = shell_exec('drall exec ls web/sites/@@dir/settings.php'); + /** + * @testdox With @@dir placeholder. + */ + public function testWithDirPlaceholder(): void { + $process = Process::fromShellCommandline( + 'drall exec ls web/sites/@@dir/settings.php', + static::PATH_DRUPAL, + ); + $process->run(); $this->assertOutputEquals(<<getOutput()); } + /** + * @testdox With --drall-filter. + */ public function testWithFilter(): void { - $output = shell_exec('drall exec --drall-filter=leo ls web/sites/@@dir/settings.php'); + $process = Process::fromShellCommandline( + 'drall exec --drall-filter=leo ./vendor/bin/drush st --field=site', + static::PATH_DRUPAL, + ); + $process->run(); $this->assertOutputEquals(<<getOutput()); } - public function testWithUriPlaceholderVerbose(): void { - $output = shell_exec('drall exec --drall-debug ls web/sites/@@dir/settings.php'); + /** + * @testdox With @@dir placeholder and --drall-debug. + */ + public function testWithDirPlaceholderAndDebug(): void { + $process = Process::fromShellCommandline( + 'drall exec --drall-debug ls web/sites/@@dir/settings.php', + static::PATH_DRUPAL, + ); + $process->run(); $this->assertOutputEquals(<<getOutput()); } - public function testWithUriPlaceholderAndGroup(): void { - $output = shell_exec('drall exec --drall-group=bluish ls web/sites/@@dir/settings.php'); + /** + * @testdox With --drall-group. + */ + public function testWithGroup(): void { + $process = Process::fromShellCommandline( + 'drall exec --drall-group=bluish ./vendor/bin/drush st --field=site', + static::PATH_DRUPAL, + ); + $process->run(); $this->assertOutputEquals(<<getOutput()); + } + + /** + * @testdox with DRALL_GROUP env var. + */ + public function testWithGroupEnvVar(): void { + $process = Process::fromShellCommandline( + 'drall exec ./vendor/bin/drush st --field=site', + static::PATH_DRUPAL, + ['DRALL_GROUP' => 'bluish'], + ); + $process->run(); + $this->assertOutputEquals(<<getOutput()); } + /** + * @testdox With @@site placeholder. + */ public function testWithSitePlaceholder(): void { - $output = shell_exec('drall exec drush @@site.local core:status --fields=site'); + $process = Process::fromShellCommandline( + 'drall exec ./vendor/bin/drush @@site.local core:status --fields=site', + static::PATH_DRUPAL, + ); + $process->run(); $this->assertOutputEquals(<<getOutput()); } - public function testWithSitePlaceholderVerbose(): void { - $output = shell_exec('drall exec --drall-debug drush @@site.local st --fields=site'); + /** + * @testdox With @@site placeholder and --drall-debug. + */ + public function testWithSitePlaceholderDebug(): void { + $process = Process::fromShellCommandline( + 'drall exec --drall-debug ./vendor/bin/drush @@site.local st --fields=site', + static::PATH_DRUPAL, + ); + $process->run(); $this->assertOutputEquals(<<getOutput()); } + /** + * @testdox With @@site placeholder and --drall-group. + */ public function testWithSitePlaceholderAndGroup(): void { - $output = shell_exec('drall exec drush --drall-group=bluish @@site.local st --fields=site'); + $process = Process::fromShellCommandline( + 'drall exec ./vendor/bin/drush --drall-group=bluish @@site.local st --fields=site', + static::PATH_DRUPAL, + ); + $process->run(); $this->assertOutputEquals(<<getOutput()); } + /** + * @testdox Catch STDERR output. + */ public function testCatchStdErrOutput(): void { - $output = shell_exec('drall exec --drall-filter=default drush version --no-ansi --verbose'); + $process = Process::fromShellCommandline( + 'drall exec --drall-filter=default ./vendor/bin/drush --verbose version', + static::PATH_DRUPAL, + ); + $process->run(); // Ignore the Drush Version. - $output = preg_replace('@(Drush version :) ([\d|\.|-]+)@', '$1 x.y.z', $output); + $output = preg_replace('@(Drush version :) ([\d|\.|-]+)@', '$1 x.y.z', $process->getOutput()); $this->assertOutputEquals(<<&1'); + $process = Process::fromShellCommandline( + 'drall exec ./vendor/bin/drush st --field=site 2>&1', + static::PATH_DRUPAL, + ['DRALL_ENVIRONMENT' => 'unknown'], + ); + $process->run(); $this->assertOutputEquals(<<getOutput()); } + /** + * @testdox With --drall-no-progress. + */ public function testWithProgressBarHidden(): void { - $output = shell_exec('DRALL_ENVIRONMENT=foo drall exec --drall-no-progress drush st --field=site 2>&1'); + $process = Process::fromShellCommandline( + 'drall exec --drall-no-progress ./vendor/bin/drush st --field=site 2>&1', + static::PATH_DRUPAL, + // The progress bar is always hidden in the "test" environment to avoid + // repeating --no-progress in all commands. Thus, for this test, + // an "unknown" environment is used to check whether --no-progress + // actually works. + ['DRALL_ENVIRONMENT' => 'unknown'], + ); + $process->run(); $this->assertOutputEquals(<<getOutput()); } + /** + * @testdox With --drall-no-execute. + */ public function testWithNoExecute(): void { - $output = shell_exec('drall exec --drall-no-execute drush core:status'); + $process = Process::fromShellCommandline( + 'drall exec --drall-no-execute ./vendor/bin/drush core:status', + static::PATH_DRUPAL, + ); + $process->run(); $this->assertOutputEquals(<<getOutput()); } + /** + * @testdox With --drall-no-execute --drall-verbose. + */ public function testWithNoExecuteVerbose(): void { - $output = shell_exec('drall exec --drall-no-execute --drall-verbose drush core:status'); + $process = Process::fromShellCommandline( + 'drall exec --drall-no-execute --drall-verbose drush core:status', + static::PATH_DRUPAL, + ); + $process->run(); $this->assertOutputEquals(<<getOutput()); + } + + /** + * @testdox With --drall-workers=2. + */ + public function testWithWorkers(): void { + $process = Process::fromShellCommandline( + 'drall ex --drall-workers=2 --drall-verbose drush --uri=@@dir core:status --fields=site', + static::PATH_DRUPAL, + ); + $process->run(); + + $this->assertStringStartsWith( + '[notice] Using 2 workers.', + $process->getOutput(), + ); + } + + /** + * @testdox With --drall-workers=17. + * + * Drall caps the maximum workers to a pre-determined limit. + */ + public function testWorkerLimit(): void { + $process = Process::fromShellCommandline( + 'drall ex --drall-workers=17 --drall-verbose drush --uri=@@dir st --fields=site', + static::PATH_DRUPAL, + ); + $process->run(); + $this->assertStringStartsWith( + '[warning] Limiting workers to 16, which is the maximum.' . PHP_EOL, + $process->getOutput(), + ); + } + + /** + * @testdox Non-zero exit code. + */ + public function testNonZeroExitCode(): void { + $process = Process::fromShellCommandline( + 'drall exec --drall-group=bad ./vendor/bin/drush st --field=site', + ); + $process->run(); + $this->assertEquals(1, $process->getExitCode()); } } diff --git a/test/Integration/Command/SiteAliasesCommandTest.php b/test/Integration/Command/SiteAliasesCommandTest.php index 0580b21..f3c56d2 100644 --- a/test/Integration/Command/SiteAliasesCommandTest.php +++ b/test/Integration/Command/SiteAliasesCommandTest.php @@ -1,29 +1,40 @@ markTestSkipped('Needs work.'); - chdir('/tmp'); - $output = shell_exec('drall site:aliases'); - $this->assertOutputEquals("[warning] No site aliases found." . PHP_EOL, $output); + $process = Process::fromShellCommandline('drall site:aliases', static::PATH_NO_DRUPAL); + $process->run(); + $this->assertStringContainsString('Package "drupal/core" is not installed', $process->getErrorOutput()); } /** - * Run site:aliases with a Drupal installation. + * @testdox with an empty Drupal installation. + */ + public function testWithEmptyDrupal(): void { + $process = Process::fromShellCommandline('drall site:aliases', static::PATH_EMPTY_DRUPAL); + $process->run(); + $this->assertStringContainsString('[warning] No site aliases found.', $process->getOutput()); + } + + /** + * @testdox with a valid Drupal installation. */ public function testExecute(): void { - $output = shell_exec('drall site:aliases'); + $process = Process::fromShellCommandline('drall site:aliases', static::PATH_DRUPAL); + $process->run(); $this->assertOutputEquals(<<getOutput()); } /** - * Run site:aliases with --drall-filter. + * @testdox with --drall-filter. */ - public function testExecuteWithFilter(): void { - $output = shell_exec('drall site:aliases --drall-filter="leo||ralph"'); + public function testWithFilter(): void { + $process = Process::fromShellCommandline( + 'drall site:aliases --drall-filter="leo||ralph"', + static::PATH_DRUPAL, + ); + $process->run(); $this->assertOutputEquals(<<getOutput()); } /** - * Run site:aliases with --drall-group. + * @testdox with --drall-group. */ public function testWithGroup(): void { - $output = shell_exec('drall site:aliases --drall-group=reddish'); + $process = Process::fromShellCommandline( + 'drall site:aliases --drall-group=reddish', + static::PATH_DRUPAL + ); + $process->run(); $this->assertOutputEquals(<<getOutput()); } /** - * Run site:aliases with DRALL_GROUP env var. + * @testdox with DRALL_GROUP env var. */ public function testWithGroupEnvVar(): void { - $output = shell_exec('DRALL_GROUP=reddish drall site:aliases'); + $process = Process::fromShellCommandline( + 'drall site:aliases', + static::PATH_DRUPAL, + ['DRALL_GROUP' => 'reddish'] + ); + $process->run(); $this->assertOutputEquals(<<getOutput()); } } diff --git a/test/Integration/Command/SiteDirectoriesCommandTest.php b/test/Integration/Command/SiteDirectoriesCommandTest.php index e82e585..739deeb 100644 --- a/test/Integration/Command/SiteDirectoriesCommandTest.php +++ b/test/Integration/Command/SiteDirectoriesCommandTest.php @@ -1,29 +1,40 @@ markTestSkipped('Needs work.'); - chdir('/tmp'); - $output = shell_exec('drall site:directories'); - $this->assertOutputEquals("[warning] No Drupal sites found." . PHP_EOL, $output); + $process = Process::fromShellCommandline('drall site:directories', static::PATH_NO_DRUPAL); + $process->run(); + $this->assertStringContainsString('Package "drupal/core" is not installed', $process->getErrorOutput()); } /** - * Run site:directories with a Drupal installation. + * @testdox with an empty Drupal installation. + */ + public function testWithEmptyDrupal(): void { + $process = Process::fromShellCommandline('drall site:directories', static::PATH_EMPTY_DRUPAL); + $process->run(); + $this->assertStringContainsString('[warning] No Drupal sites found.', $process->getOutput()); + } + + /** + * @testdox with a valid Drupal installation. */ public function testExecute(): void { - $output = shell_exec('drall site:directories'); + $process = Process::fromShellCommandline('drall site:directories', static::PATH_DRUPAL); + $process->run(); $this->assertOutputEquals(<<getOutput()); } /** - * Run site:directories with --drall-filter. + * @testdox with --drall-filter. */ public function testExecuteWithFilter(): void { - $output = shell_exec('drall site:directories --drall-filter="leo||ralph"'); + $process = Process::fromShellCommandline('drall site:directories --drall-filter="leo||ralph"', static::PATH_DRUPAL); + $process->run(); $this->assertOutputEquals(<<getOutput()); } /** - * Run site:directories with --drall-group. + * @testdox with --drall-group. */ public function testWithGroup(): void { - $output = shell_exec('drall site:directories --drall-group=bluish'); + $process = Process::fromShellCommandline('drall site:directories --drall-group=bluish', static::PATH_DRUPAL); + $process->run(); $this->assertOutputEquals(<<getOutput()); } /** - * Run site:directories with DRALL_GROUP env var. + * @testdox with DRALL_GROUP env var. */ public function testWithGroupEnvVar(): void { - $output = shell_exec('DRALL_GROUP=bluish drall site:directories'); + $process = Process::fromShellCommandline( + 'drall site:directories', + static::PATH_DRUPAL, + ['DRALL_GROUP' => 'bluish'], + ); + $process->run(); $this->assertOutputEquals(<<getOutput()); } } diff --git a/test/Integration/Command/SiteKeysCommandTest.php b/test/Integration/Command/SiteKeysCommandTest.php index fdb8713..225ff65 100644 --- a/test/Integration/Command/SiteKeysCommandTest.php +++ b/test/Integration/Command/SiteKeysCommandTest.php @@ -1,29 +1,40 @@ markTestSkipped('Needs work.'); - chdir('/tmp'); - $output = shell_exec('drall site:keys'); - $this->assertOutputEquals("[warning] No Drupal sites found." . PHP_EOL, $output); + $process = Process::fromShellCommandline('drall site:keys', static::PATH_NO_DRUPAL); + $process->run(); + $this->assertStringContainsString('Package "drupal/core" is not installed', $process->getErrorOutput()); } /** - * Run site:keys with a Drupal installation. + * @testdox with an empty Drupal installation. + */ + public function testWithEmptyDrupal(): void { + $process = Process::fromShellCommandline('drall site:keys', static::PATH_EMPTY_DRUPAL); + $process->run(); + $this->assertStringContainsString('[warning] No Drupal sites found.', $process->getOutput()); + } + + /** + * @testdox with a Drupal installation. */ public function testExecute(): void { - $output = shell_exec('drall site:keys'); + $process = Process::fromShellCommandline('drall site:keys', static::PATH_DRUPAL); + $process->run(); $this->assertOutputEquals(<<getOutput()); } /** - * Run site:keys with --drall-filter. + * @testdox with --drall-filter. */ public function testExecuteWithFilter(): void { - $output = shell_exec('drall site:keys --drall-filter="value~=@.local\$@"'); + $process = Process::fromShellCommandline('drall site:keys --drall-filter="value~=@.local\$@"', static::PATH_DRUPAL); + $process->run(); $this->assertOutputEquals(<<getOutput()); } /** - * Run site:keys with --drall-group. + * @testdox with --drall-group. */ public function testWithGroup(): void { - $output = shell_exec('drall site:keys --drall-group=bluish'); + $process = Process::fromShellCommandline('drall site:keys --drall-group=bluish', static::PATH_DRUPAL); + $process->run(); $this->assertOutputEquals(<<getOutput()); } /** - * Run site:keys with DRALL_GROUP env var. + * @testdox with DRALL_GROUP env var. */ public function testWithGroupEnvVar(): void { - $output = shell_exec('DRALL_GROUP=bluish drall site:keys'); + $process = Process::fromShellCommandline( + 'drall site:keys', + static::PATH_DRUPAL, + ['DRALL_GROUP' => 'bluish'], + ); + $process->run(); $this->assertOutputEquals(<<getOutput()); } } diff --git a/test/Integration/DrallTest.php b/test/Integration/DrallTest.php index f625873..69489b1 100644 --- a/test/Integration/DrallTest.php +++ b/test/Integration/DrallTest.php @@ -4,32 +4,27 @@ use Composer\InstalledVersions; use Drall\Drall; -use Drall\IntegrationTestCase; +use Drall\TestCase; +use Symfony\Component\Process\Process; /** * @covers \Drall\Drall */ -class DrallTest extends IntegrationTestCase { +class DrallTest extends TestCase { public function testVersion() { - $output = shell_exec('drall --version'); + $process = Process::fromShellCommandline('drall --version', static::PATH_DRUPAL); + $process->run(); $version = InstalledVersions::getPrettyVersion('jigarius/drall'); - $this->assertEquals(Drall::NAME . ' ' . $version . PHP_EOL, $output); - } - - public function testWorkingDirectory() { - $output = shell_exec('pwd'); - $this->assertEquals(<<drupalDir()} - -EOT, $output); + $this->assertStringContainsString(Drall::NAME . ' ' . $version, $process->getOutput()); } /** * Run drall with a command it doesn't recognize. */ public function testUnrecognizedCommand() { - $output = shell_exec('drall st 2>&1'); + $process = Process::fromShellCommandline('drall st', static::PATH_DRUPAL); + $process->run(); $this->assertOutputEquals(<<getErrorOutput()); } } diff --git a/test/Unit/Command/ExecCommandTest.php b/test/Unit/Command/ExecCommandTest.php deleted file mode 100644 index 3311431..0000000 --- a/test/Unit/Command/ExecCommandTest.php +++ /dev/null @@ -1,177 +0,0 @@ -markTestSkipped('Replace with integration test.'); - $drupalFinder = $this->createDrupalFinderStub(); - $siteAliasManager = new SiteAliasManager(); - - $siteDetectorMock = $this->getMockBuilder(SiteDetector::class) - ->setConstructorArgs([$drupalFinder, $siteAliasManager]) - ->onlyMethods(['getSiteDirNames']) - ->getMock(); - $siteDetectorMock - ->expects($this->once()) - ->method('getSiteDirNames') - ->willReturn([]); - - $app = new Drall(); - $input = ['cmd' => 'cat @@dir']; - /** @var \Drall\Command\ExecCommand $command */ - $command = $app->find('exec'); - $command->setSiteDetector($siteDetectorMock); - $command->setArgv(self::arrayInputAsArgv($input)); - $tester = new CommandTester($command); - $tester->execute($input); - - $tester->assertCommandIsSuccessful(); - $this->assertEquals( - '[warning] No Drupal sites found.' . PHP_EOL, - $tester->getDisplay(), - ); - } - - public function testNonZeroExitCode() { - $drupalFinder = new DrupalFinderComposerRuntime(); - $siteAliasManager = new SiteAliasManager(); - - $siteDetectorMock = $this->getMockBuilder(SiteDetector::class) - ->setConstructorArgs([$drupalFinder, $siteAliasManager]) - ->onlyMethods(['getSiteAliasNames', 'getDrushPath']) - ->getMock(); - $siteDetectorMock - ->expects($this->once()) - ->method('getSiteAliasNames') - ->willReturn(['@splinter', '@shredder']); - - $app = new Drall(); - $input = ['cmd' => 'drush @@site.dev core:rebuild']; - /** @var \Drall\Command\ExecCommand $command */ - $command = $app->find('exec'); - $command->setSiteDetector($siteDetectorMock); - $command->setArgv(self::arrayInputAsArgv($input)); - $tester = new CommandTester($command); - - $this->assertEquals(1, $tester->execute($input)); - } - - public function testWithNoPlaceholders() { - $app = new Drall(); - $input = ['cmd' => 'ls']; - /** @var ExecCommand $command */ - $command = $app->find('exec') - ->setArgv(self::arrayInputAsArgv($input)); - $tester = new CommandTester($command); - - $this->assertEquals(1, $tester->execute($input)); - $this->assertEquals( - '[error] The command contains no placeholders. Please run it directly without Drall.' . PHP_EOL, - $tester->getDisplay() - ); - } - - public function testWithMixedPlaceholders() { - $app = new Drall(); - $input = ['cmd' => 'drush @@site.local core:status && drush --uri=@@dir core:status']; - /** @var ExecCommand $command */ - $command = $app->find('exec') - ->setArgv(self::arrayInputAsArgv($input)); - $tester = new CommandTester($command); - - $this->assertEquals(1, $tester->execute($input)); - $this->assertEquals( - '[error] The command contains: @@site, @@dir. Please use only one.' . PHP_EOL, - $tester->getDisplay() - ); - } - - /** - * Drall caps the maximum number of workers to pre-determined limit. - */ - public function testWorkerLimit() { - $this->markTestSkipped('Replace with integration test.'); - $input = [ - '--drall-workers' => 17, - '--drall-verbose' => TRUE, - 'cmd' => 'drush --uri=@@dir core:status --fields=site', - ]; - - $app = new Drall(); - /** @var \Drall\Command\ExecCommand $command */ - $command = $app->find('exec'); - $command->setArgv(self::arrayInputAsArgv($input)); - - $tester = new CommandTester($command); - $tester->execute($input); - - $this->assertNotEmpty($tester->getDisplay()); - $this->assertStringStartsWith( - '[warning] Limiting workers to 16, which is the maximum.' . PHP_EOL, - $tester->getDisplay() - ); - } - - public function testWithWorkers() { - $this->markTestSkipped('Replace with integration test.'); - $input = [ - '--drall-workers' => 2, - '--drall-verbose' => TRUE, - 'cmd' => 'drush --uri=@@dir core:status --fields=site', - ]; - - $app = new Drall(NULL, new ArrayInput($input)); - /** @var \Drall\Command\ExecCommand $command */ - $command = $app->find('exec'); - $command->setArgv(self::arrayInputAsArgv($input)); - $tester = new CommandTester($command); - $tester->execute($input, [ - 'verbosity' => OutputInterface::VERBOSITY_VERY_VERBOSE, - ]); - - $this->assertStringStartsWith( - '[notice] Using 2 workers.', - $tester->getDisplay() - ); - } - - /** - * Converts an array of input into an $argv like array. - * - * @param array $input - * Array of input as expected by CommandTester::execute(). - * - * @return array - * Array resembling $argv. - * - * @see \Drall\Command\ExecCommand::setArgv() - */ - private static function arrayInputAsArgv(array $input): array { - array_unshift($input, '/opt/drall/bin/drall', 'exec'); - - $argv = []; - foreach ($input as $key => $value) { - if (is_numeric($key) || $key === 'cmd') { - $argv[] = $value; - continue; - } - - $argv[] = "$key=$value"; - } - - return $argv; - } - -} diff --git a/test/Unit/Command/SiteAliasesCommandTest.php b/test/Unit/Command/SiteAliasesCommandTest.php deleted file mode 100644 index 562b644..0000000 --- a/test/Unit/Command/SiteAliasesCommandTest.php +++ /dev/null @@ -1,100 +0,0 @@ -getMockBuilder(SiteDetector::class) - ->setConstructorArgs([$drupalFinder, $siteAliasManager]) - ->onlyMethods(['getSiteAliases']) - ->getMock(); - $siteDetectorMock - ->expects($this->once()) - ->method('getSiteAliases') - ->willReturn(['@leo.local', '@ralph.local']); - - $app = new Drall(); - /** @var \Drall\Command\SiteAliasesCommand $command */ - $command = $app->find('site:aliases'); - $command->setSiteDetector($siteDetectorMock); - $tester = new CommandTester($command); - $tester->execute([]); - - $tester->assertCommandIsSuccessful(); - - $this->assertEquals( - <<getDisplay() - ); - } - - public function testExecuteWithGroup() { - $drupalFinder = new DrupalFinderComposerRuntime(); - $siteAliasManager = new SiteAliasManager(); - - $siteDetectorMock = $this->getMockBuilder(SiteDetector::class) - ->setConstructorArgs([$drupalFinder, $siteAliasManager]) - ->onlyMethods(['getSiteAliases']) - ->getMock(); - $siteDetectorMock - ->expects($this->once()) - ->method('getSiteAliases') - ->with('bluish') - ->willReturn(['@tmnt.local']); - - $app = new Drall(); - /** @var \Drall\Command\SiteAliasesCommand $command */ - $command = $app->find('site:aliases'); - $command->setSiteDetector($siteDetectorMock); - $tester = new CommandTester($command); - $tester->execute(['--drall-group' => 'bluish']); - - $tester->assertCommandIsSuccessful(); - } - - public function testExecuteWithNoSiteAliases() { - $drupalFinder = new DrupalFinderComposerRuntime(); - $siteAliasManager = new SiteAliasManager(); - - $siteDetectorMock = $this->getMockBuilder(SiteDetector::class) - ->setConstructorArgs([$drupalFinder, $siteAliasManager]) - ->onlyMethods(['getSiteAliases']) - ->getMock(); - $siteDetectorMock - ->expects($this->once()) - ->method('getSiteAliases') - ->willReturn([]); - - $app = new Drall(); - /** @var \Drall\Command\SiteAliasesCommand $command */ - $command = $app->find('site:aliases'); - $command->setSiteDetector($siteDetectorMock); - $tester = new CommandTester($command); - $tester->execute([]); - - $tester->assertCommandIsSuccessful(); - $this->assertEquals( - '[warning] No site aliases found.' . PHP_EOL, - $tester->getDisplay(TRUE) - ); - } - -} diff --git a/test/Unit/Command/SiteDirectoriesCommandTest.php b/test/Unit/Command/SiteDirectoriesCommandTest.php deleted file mode 100644 index fa6d756..0000000 --- a/test/Unit/Command/SiteDirectoriesCommandTest.php +++ /dev/null @@ -1,99 +0,0 @@ -getMockBuilder(SiteDetector::class) - ->setConstructorArgs([$drupalFinder, $siteAliasManager]) - ->onlyMethods(['getSiteDirNames']) - ->getMock(); - $siteDetectorMock - ->expects($this->once()) - ->method('getSiteDirNames') - ->willReturn(['donnie', 'leo']); - - $app = new Drall(); - /** @var \Drall\Command\SiteDirectoriesCommand $command */ - $command = $app->find('site:directories'); - $command->setSiteDetector($siteDetectorMock); - $tester = new CommandTester($app->find('site:directories')); - $tester->execute([]); - - $tester->assertCommandIsSuccessful(); - - $this->assertEquals( - <<getDisplay() - ); - } - - public function testExecuteWithGroup() { - $this->markTestSkipped('Replace with integration test.'); - $siteDetectorMock = $this->getMockBuilder(SiteDetector::class) - ->setConstructorArgs([$drupalFinder, $siteAliasManager]) - ->onlyMethods(['getSiteDirNames']) - ->getMock(); - $siteDetectorMock - ->expects($this->once()) - ->method('getSiteDirNames') - ->with('bluish') - ->willReturn(['default']); - - $app = new Drall(); - /** @var \Drall\Command\SiteDirectoriesCommand $command */ - $command = $app->find('site:directories'); - $command->setSiteDetector($siteDetectorMock); - $tester = new CommandTester($command); - $tester->execute(['--drall-group' => 'bluish']); - - $tester->assertCommandIsSuccessful(); - } - - public function testExecuteWithNoSiteDirectories() { - $drupalFinder = new DrupalFinderComposerRuntime(); - $siteAliasManager = new SiteAliasManager(); - - $siteDetectorMock = $this->getMockBuilder(SiteDetector::class) - ->setConstructorArgs([$drupalFinder, $siteAliasManager]) - ->onlyMethods(['getSiteDirNames']) - ->getMock(); - $siteDetectorMock - ->expects($this->once()) - ->method('getSiteDirNames') - ->willReturn([]); - - $app = new Drall(); - /** @var \Drall\Command\SiteDirectoriesCommand $command */ - $command = $app->find('site:directories'); - $command->setSiteDetector($siteDetectorMock); - $tester = new CommandTester($command); - $tester->execute([]); - - $tester->assertCommandIsSuccessful(); - - $this->assertEquals( - '[warning] No Drupal sites found.' . PHP_EOL, - $tester->getDisplay() - ); - } - -} diff --git a/test/Unit/Command/SiteKeysCommandTest.php b/test/Unit/Command/SiteKeysCommandTest.php deleted file mode 100644 index 3100ad5..0000000 --- a/test/Unit/Command/SiteKeysCommandTest.php +++ /dev/null @@ -1,114 +0,0 @@ -getMockBuilder(SiteDetector::class) - ->setConstructorArgs([$drupalFinder, $siteAliasManager]) - ->onlyMethods(['getSiteKeys']) - ->getMock(); - $siteDetectorMock - ->expects($this->once()) - ->method('getSiteKeys') - ->willReturn(['donatello.com', 'leonardo.com']); - - $app = new Drall(); - /** @var \Drall\Command\SiteKeysCommand $command */ - $command = $app->find('site:keys'); - $command->setSiteDetector($siteDetectorMock); - - $tester = new CommandTester($command); - $tester->execute([]); - - $tester->assertCommandIsSuccessful(); - - $this->assertEquals( - <<getDisplay() - ); - } - - public function testExecuteWithGroup() { - $drupalFinder = new DrupalFinderComposerRuntime(); - $siteAliasManager = new SiteAliasManager(); - - $siteDetectorMock = $this->getMockBuilder(SiteDetector::class) - ->setConstructorArgs([$drupalFinder, $siteAliasManager]) - ->onlyMethods(['getSiteKeys']) - ->getMock(); - $siteDetectorMock - ->expects($this->once()) - ->method('getSiteKeys') - ->with('none') - ->willReturn(['tmnt.com']); - - $app = new Drall(); - - /** @var \Drall\Command\SiteKeysCommand $command */ - $command = $app->find('site:keys'); - $command->setSiteDetector($siteDetectorMock); - - $tester = new CommandTester($command); - $tester->execute(['--drall-group' => 'none']); - - $tester->assertCommandIsSuccessful(); - - $this->assertEquals( - <<getDisplay() - ); - } - - public function testExecuteWithNoSiteDirectories() { - $drupalFinder = new DrupalFinderComposerRuntime(); - $siteAliasManager = new SiteAliasManager(); - - $siteDetectorMock = $this->getMockBuilder(SiteDetector::class) - ->setConstructorArgs([$drupalFinder, $siteAliasManager]) - ->onlyMethods(['getSiteKeys']) - ->getMock(); - $siteDetectorMock - ->expects($this->once()) - ->method('getSiteKeys') - ->willReturn([]); - - $app = new Drall(); - /** @var \Drall\Command\SiteKeysCommand $command */ - $command = $app->find('site:keys'); - $command->setSiteDetector($siteDetectorMock); - - $tester = new CommandTester($command); - $tester->execute([]); - - $tester->assertCommandIsSuccessful(); - - $this->assertEquals( - '[warning] No Drupal sites found.' . PHP_EOL, - $tester->getDisplay() - ); - } - -} diff --git a/test/Unit/IntegrationTestCaseTest.php b/test/Unit/IntegrationTestCaseTest.php deleted file mode 100644 index c893866..0000000 --- a/test/Unit/IntegrationTestCaseTest.php +++ /dev/null @@ -1,23 +0,0 @@ -assertOutputEquals($expected, $actual); - } - -} diff --git a/test/Unit/Model/SitesFileTest.php b/test/Unit/Model/SitesFileTest.php index a1afd4c..3d75c28 100644 --- a/test/Unit/Model/SitesFileTest.php +++ b/test/Unit/Model/SitesFileTest.php @@ -11,19 +11,19 @@ class SitesFileTest extends TestCase { protected SitesFile $subject; public function setUp(): void { - $this->subject = new SitesFile($this->fixturesDir() . '/sites.valid.php'); + $this->subject = new SitesFile(static::PATH_FIXTURES . '/sites.valid.php'); } public function testGetPath() { $this->assertEquals( - $this->fixturesDir() . '/sites.valid.php', + static::PATH_FIXTURES . '/sites.valid.php', $this->subject->getPath() ); } - public function testInvalidPath() { + public function testNonExistentPath() { $this->expectException(\RuntimeException::class); - new SitesFile($this->fixturesDir() . '/sites.invalid.php'); + new SitesFile(static::PATH_FIXTURES . '/sites.non-existent.php'); } public function testSitesNotDefined() { @@ -40,6 +40,12 @@ public function testSitesNotArray() { new SitesFile($path); } + public function testSitesEmptyArray() { + $path = $this->createTempFile('assertEmpty($subject->getDirNames()); + } + public function testGetDirNames() { $this->assertEquals( ['default', 'donnie', 'leo', 'mikey', 'ralph'], diff --git a/test/Unit/Service/SiteDetectorTest.php b/test/Unit/Service/SiteDetectorTest.php index 4c70529..188711c 100644 --- a/test/Unit/Service/SiteDetectorTest.php +++ b/test/Unit/Service/SiteDetectorTest.php @@ -6,7 +6,6 @@ use Consolidation\SiteAlias\Util\YamlDataFileLoader; use Drall\Service\SiteDetector; use Drall\TestCase; -use DrupalFinder\DrupalFinderComposerRuntime; /** * @covers \Drall\Service\SiteDetector @@ -16,13 +15,11 @@ class SiteDetectorTest extends TestCase { protected SiteDetector $subject; protected function setUp(): void { - parent::setUp(); - $siteAliasFileLoader = new SiteAliasFileLoader( - new SiteAliasFileDiscovery(["{$this->drupalDir()}/drush/sites"]) + new SiteAliasFileDiscovery([static::PATH_DRUPAL . "/drush/sites"]) ); $siteAliasFileLoader->addLoader('yml', new YamlDataFileLoader()); - $siteAliasManager = new SiteAliasManager($siteAliasFileLoader, $this->drupalDir()); + $siteAliasManager = new SiteAliasManager($siteAliasFileLoader, static::PATH_DRUPAL); $siteAliasManager->addSearchLocation('drush/sites'); $this->subject = new SiteDetector($this->createDrupalFinderStub(), $siteAliasManager); @@ -50,10 +47,18 @@ public function testGetSiteDirNamesWithFilter() { } public function testGetSiteDirNamesWithNoDrupal() { - $this->markTestSkipped('Needs work.'); - $this->subject = new SiteDetector(new DrupalFinderComposerRuntime(), new SiteAliasManager()); + $subject = new SiteDetector( + $this->createDrupalFinderStub(static::PATH_NO_DRUPAL), + ); + $this->expectException(\RuntimeException::class); + $subject->getSiteDirNames(); + } - $this->assertEquals([], $this->subject->getSiteDirNames()); + public function testGetSiteDirNamesWithEmptyDrupal() { + $subject = new SiteDetector( + $this->createDrupalFinderStub(static::PATH_EMPTY_DRUPAL), + ); + $this->assertEquals([], $subject->getSiteDirNames()); } public function testGetSiteKeys() { @@ -114,10 +119,18 @@ public function testGetUniqueSiteKeysWithFilter() { } public function testGetSiteKeysWithNoDrupal() { - $this->markTestSkipped('Needs work.'); - $this->subject = new SiteDetector(new DrupalFinderComposerRuntime(), new SiteAliasManager()); + $subject = new SiteDetector( + $this->createDrupalFinderStub(static::PATH_NO_DRUPAL), + ); + $this->expectException(\RuntimeException::class); + $subject->getSiteKeys(); + } - $this->assertEquals([], $this->subject->getSiteKeys()); + public function testGetSiteKeysWithEmptyDrupal() { + $subject = new SiteDetector( + $this->createDrupalFinderStub(static::PATH_EMPTY_DRUPAL), + ); + $this->assertEquals([], $subject->getSiteKeys()); } public function testGetSiteAliases() { @@ -182,22 +195,6 @@ public function testGetDrushPath() { ); } - /** - * Drush path is "drush" when a Drupal installation is not found. - */ - public function testGetDrushPathWithoutDrupal() { - $this->markTestSkipped('Needs work.'); - chdir('/'); - - $drupalFinder = new DrupalFinderComposerRuntime(); - $subject = new SiteDetector($drupalFinder, new SiteAliasManager()); - - $this->assertEquals( - 'drush', - $subject->getDrushPath() - ); - } - public function testDetectFromDirectory(): void { $this->assertEquals([ 'default' => 'default', @@ -205,7 +202,7 @@ public function testDetectFromDirectory(): void { 'leo' => 'leo', 'mikey' => 'mikey', 'ralph' => 'ralph', - ], SiteDetector::detectFromDirectory($this->drupalDir() . '/web/sites')); + ], SiteDetector::detectFromDirectory(static::PATH_DRUPAL . '/web/sites')); } public function testDetectFromIncorrectDirectory(): void { diff --git a/test/Unit/TestCaseTest.php b/test/Unit/TestCaseTest.php index 39bd8ff..9c4201c 100644 --- a/test/Unit/TestCaseTest.php +++ b/test/Unit/TestCaseTest.php @@ -5,14 +5,10 @@ use Drall\TestCase; /** - * @covers Drall\TestCase + * @covers \Drall\TestCase */ class TestCaseTest extends TestCase { - public function testDrupalDir() { - $this->assertEquals('/opt/drupal', $this->drupalDir()); - } - public function testCreateTempFilePath() { $path = static::createTempFilePath(); $this->assertEquals(sys_get_temp_dir(), dirname($path)); @@ -25,34 +21,17 @@ public function testCreateTempFile() { $this->assertEquals('Bunny Wabbit', file_get_contents($path)); } - public function testFixturesDir() { - $this->assertEquals( - dirname(__DIR__) . '/fixtures', - $this->fixturesDir() - ); - } - - public function testProjectDir() { - $this->assertEquals( - dirname(dirname(__DIR__)), - $this->projectDir() - ); - } - - public function testCwd() { - chdir('/tmp'); - - $this->assertEquals('/tmp', getcwd()); - - // Takes us to the Drupal directory. - $this->setUp(); - - $this->assertEquals($this->drupalDir(), getcwd()); + public function testAssertOutputEquals() { + $expected = <<tearDown(); +EOF; + // For some reason, drush's output has spaces before EOL. + $actual = "foo \nbar \nbaz \n"; - $this->assertEquals('/tmp', getcwd()); + $this->assertOutputEquals($expected, $actual); } } diff --git a/test/fixtures/sites.valid.php b/test/fixtures/sites.valid.php index ec59c43..ad67ab6 100644 --- a/test/fixtures/sites.valid.php +++ b/test/fixtures/sites.valid.php @@ -2,7 +2,7 @@ /** * @file - * A valid sites.php file. + * A sites.php with valid entries. */ $sites['tmnt.com'] = 'default';