Skip to content

Commit

Permalink
Merge pull request #759 from lucatume/v35-transpile-758
Browse files Browse the repository at this point in the history
transpile #758
  • Loading branch information
lucatume authored Oct 18, 2024
2 parents 9f78e69 + bab88a7 commit a1e4969
Show file tree
Hide file tree
Showing 10 changed files with 142 additions and 9 deletions.
43 changes: 43 additions & 0 deletions .github/workflows/php-compatibility.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow

name: PHP Compatibility

on: # yamllint disable-line rule:truthy
pull_request:
paths:
- 'src/**'
- 'includes/**'
- 'tests/**'
- 'composer.json'
- '.github/workflows/test.yaml'
push:
paths:
- 'src/**'
- 'includes/**'
- 'tests/**'
- 'composer.json'
- '.github/workflows/test.yaml'
branches:
- "v3.5"
workflow_dispatch: # yamllint disable-line rule:truthy

permissions:
contents: "read"

concurrency:
group: "${{ github.workflow }}-${{ github.ref }}"
cancel-in-progress: true

jobs:
php-compatibility:
name: "PHP 7.1-7.4 compatibility"
runs-on: "ubuntu-22.04"
timeout-minutes: 10
steps:
- name: "Checkout"
uses: "actions/checkout@v3"
- name: "Analyze for PHP 7.1 compatibility"
uses: pantheon-systems/phpcompatibility-action@v1
with:
test-versions: 7.1-7.4
paths: ${{ github.workspace }}/src
4 changes: 2 additions & 2 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ jobs:
matrix:
php_version: [
# '7.1', # Disabled since WordPress minimum requirement is 7.2.
'7.2',
'7.3',
# '7.2', # Disabled since this version of PHP is not compatible with MySQL 8.0.
# '7.3', # Disabled since this version of PHP is not compatible with MySQL 8.0.
'7.4'
]
name: v3.5 unit php@${{ matrix.php_version }}
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).

## [unreleased] Unreleased

### Changed

- Improve `LoadSandbox` error and messaging (used by the `WPLoader` module when `loadOnly: true`) around Codeception early exits. (thanks @andronocean)

## [3.7.5] 2024-09-13;

## Fixed
Expand Down
1 change: 1 addition & 0 deletions config/typos.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ ignore-hidden = false
[default.extend-words]
# To handle the hipster default blog content about bike messengers gettin' caught in the rain.
"gettin" = "gettin"
"Automattic" = "Automattic"
6 changes: 3 additions & 3 deletions src/Process/SerializableThrowable.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public function __construct(Throwable $throwable)
* trace: array<int,array<string,mixed>>
* }
*/
public function __serialize(): array
public function __serialize(): array // phpcs:ignore
{
return [
'colorize' => $this->colorize,
Expand All @@ -92,7 +92,7 @@ public function __serialize(): array
*
* @throws ReflectionException
*/
public function __unserialize(array $data): void
public function __unserialize(array $data): void // phpcs:ignore
{
$this->throwable = $data['throwable'];
$this->colorize = $data['colorize'];
Expand Down Expand Up @@ -133,7 +133,7 @@ private function prettyPrintTrace(array $trace): array
$updatedTrace = [];
$streamIsatty = function ($stream) {
if (\function_exists('stream_isatty')) {
return stream_isatty($stream);
return stream_isatty($stream); // phpcs:ignore
}
if (!\is_resource($stream)) {
trigger_error('stream_isatty() expects parameter 1 to be resource, ' . \gettype($stream) . ' given', \E_USER_WARNING);
Expand Down
2 changes: 1 addition & 1 deletion src/Utils/Env.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ static function (array $lines, $line) use ($pattern): array {
*/
public static function os(): string
{
$osSlug = strtolower(substr(PHP_OS_FAMILY, 0, 3));
$osSlug = strtolower(substr(PHP_OS, 0, 3));

$map = [
'win' => 'Windows',
Expand Down
6 changes: 3 additions & 3 deletions src/WordPress/FileRequests/FileRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public function execute(): array
{
if (count($this->presetGlobalVars) > 0) {
foreach ($this->presetGlobalVars as $key => $value) {
global $$key;
global $$key; // phpcs:ignore
$$key = $value;
}
}
Expand Down Expand Up @@ -223,7 +223,7 @@ public function execute(): array
* targetFile: string
* }
*/
public function __serialize(): array
public function __serialize(): array // phpcs:ignore
{
return [
'afterLoadClosures' => $this->afterLoadClosures,
Expand Down Expand Up @@ -259,7 +259,7 @@ public function __serialize(): array
*
* @throws FileRequestException
*/
public function __unserialize(array $data): void
public function __unserialize(array $data): void // phpcs:ignore
{
$this->afterLoadClosures = $data['afterLoadClosures'] ?? [];
$this->constants = $data['constants'] ?? [];
Expand Down
11 changes: 11 additions & 0 deletions src/WordPress/InstallationException.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class InstallationException extends Exception
public const SQLITE_PLUGIN_NOT_FOUND = 37;
public const DB_DROPIN_ALREADY_EXISTS = 38;
public const WORDPRESS_NOT_FOUND = 39;
public const COMMAND_DID_NOT_FINISH_PROPERLY = 40;

public static function becauseWordPressFailedToLoad(string $bodyContent): self
{
Expand Down Expand Up @@ -71,4 +72,14 @@ public static function becauseWordPressMultsiteIsNotInstalled(bool $isSubdomainI

return new self('WordPress multisite (sub-folder) is not installed.', self::MULTISITE_SUBFOLDER_NOT_INSTALLED);
}

public static function becauseCodeceptionCommandDidNotFinish(): self
{
return new self(
"The current Codeception command did not finish properly. WordPress exited early while loading. "
."A plugin, theme, or WP-CLI package may have exited before the wp_loaded action could be fired. " .
"If there is error output above, it may provide clues.",
self::COMMAND_DID_NOT_FINISH_PROPERLY
);
}
}
7 changes: 7 additions & 0 deletions src/WordPress/LoadSandbox.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,13 @@ class_exists(InstallationException::class);
}
}

if ($bodyContent === 'COMMAND DID NOT FINISH PROPERLY.') {
// We got here from \Codeception\Subscriber\ErrorHandler::shutdownHandler().
// We'll try to provide some clues to the user in the exception message.
codecept_debug('Codeception error: ' . $bodyContent . ' Check logs for details.');
throw InstallationException::becauseCodeceptionCommandDidNotFinish();
}

// We do not know what happened, throw and try to be helpful.
throw InstallationException::becauseWordPressFailedToLoad($bodyContent ?: $reason);
}
Expand Down
67 changes: 67 additions & 0 deletions tests/unit/lucatume/WPBrowser/WordPress/LoadSandboxTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@

use Codeception\Test\Unit;
use Exception;
use lucatume\WPBrowser\Tests\Traits\Fork;
use lucatume\WPBrowser\Tests\Traits\LoopIsolation;
use lucatume\WPBrowser\Tests\Traits\TmpFilesCleanup;
use lucatume\WPBrowser\Traits\UopzFunctions;
use lucatume\WPBrowser\Utils\Env;
use lucatume\WPBrowser\Utils\Filesystem as FS;
use lucatume\WPBrowser\Utils\Random;
Expand All @@ -24,6 +26,7 @@ class LoadSandboxTest extends Unit
{
use LoopIsolation;
use TmpFilesCleanup;
use UopzFunctions;

/**
* It should correctly load installed WordPress
Expand Down Expand Up @@ -322,4 +325,68 @@ public function should_handle_wp_die_called_during_loading(): void
$loadSandbox->load();
});
}

/**
* It should handle an unexpected early exit if something interferes with Codeception
*
* @test
*/
public function should_handle_codeception_command_not_finished_error(): void {
$wpRootDir = FS::tmpDir('sandbox_');
$dbName = Random::dbName();
$dbHost = Env::get('WORDPRESS_DB_HOST');
$dbUser = Env::get('WORDPRESS_DB_USER');
$dbPassword = Env::get('WORDPRESS_DB_PASSWORD');
$db = new MysqlDatabase($dbName, $dbUser, $dbPassword, $dbHost, 'wp_');
$installation = Installation::scaffold($wpRootDir, '6.1.1')
->configure($db)
->install(
'http://wordpress.test',
'admin',
'admin',
'admin@wordpress.test',
'Sandbox'
);

$exitingPluginCode = <<<'PHP'
<?php
/**
* Plugin Name: Codeception Early Shutdown Mock
*
* Suppose a plugin or CLI package messes up and exits early, e.g. `exit(1)`, prior to `wp_loaded`.
* That will trigger Codeception's shutdown handler. If the suite is not finished running, and an error has not occurred,
* Codeception echoes a message and exits. LoadSandbox's output buffer will catch this.
* This plugin mocks the Codeception behavior.
*
* @see \Codeception\Subscriber\ErrorHandler::shutdownHandler()
*/
add_action('after_setup_theme', function () {
// Output and exit from \Codeception\Subscriber\ErrorHandler::shutdownHandler.
echo "\n\n\nCOMMAND DID NOT FINISH PROPERLY.\n";
exit(125);
});
PHP;

$muPluginsDir = $installation->getMuPluginsDir();
if (
!is_dir($muPluginsDir)
&& !(
mkdir($muPluginsDir, 0755, true)
&& is_dir($muPluginsDir)
)
) {
throw new \RuntimeException('Could not create mu-plugins directory.');
}
if(!file_put_contents($muPluginsDir . '/exiting-mu-plugin.php', $exitingPluginCode)){
throw new \RuntimeException('Could not write exiting-mu-plugin.php.');
}

$this->expectException(InstallationException::class);
$this->expectExceptionMessage(InstallationException::becauseCodeceptionCommandDidNotFinish()->getMessage());

$this->assertInIsolation(static function () use ($wpRootDir) {
$loadSandbox = new LoadSandbox($wpRootDir, 'wordpress.test');
$loadSandbox->load();
});
}
}

0 comments on commit a1e4969

Please sign in to comment.