Skip to content

Commit

Permalink
test(build) update per extension removal
Browse files Browse the repository at this point in the history
  • Loading branch information
lucatume committed Aug 18, 2023
1 parent 95eabad commit d63160e
Show file tree
Hide file tree
Showing 17 changed files with 2,435 additions and 2,584 deletions.
1 change: 0 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Removed the `bordoni/phpass` dependency, internalized the `Hautelook\Phpass` portable password hashing library.
- Removed the `mikemclin/laravel-wp-password` dependency.
- Removed the `WordPress` module and related support classes.
- Removed the `mode` configuration parameter from the `Symlinker` extension.
- Removed the `StubProphecy` and `FunctionProphecy` classes.
- Removed the `WPHealthcheck` class in favor of reports provided by the `WordPress\Installation` class.
- Removed the `tad\WPBrowser\Utils\Map` class
Expand Down
2 changes: 2 additions & 0 deletions bin/stack
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,8 @@ function build() {
ensure_twentytwenty_theme
ensure_test_plugins
ensure_externals_blocked
cp -R tests/_data/themes/dummy var/wordpress/wp-content/themes/dummy
cp -R tests/_data/plugins/mu-plugin-1 var/wordpress/wp-content/plugins/mu-plugin-1
}

function clean() {
Expand Down
2 changes: 2 additions & 0 deletions codeception.dist.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ coverage:
- src/*
wpFolder: '%WORDPRESS_ROOT_DIR%'
extensions:
enabled:
- "lucatume\\WPBrowser\\Extension\\EventDispatcherBridge"
commands:
- "lucatume\\WPBrowser\\Command\\RunOriginal"
- "lucatume\\WPBrowser\\Command\\RunAll"
Expand Down
3 changes: 1 addition & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@
"szepeviktor/phpstan-wordpress": "^1.3",
"phpstan/extension-installer": "^1.3",
"phpstan/phpstan-symfony": "^1.3",
"squizlabs/php_codesniffer": "^3.7",
"webdriver-binary/binary-chromedriver": "*"
"squizlabs/php_codesniffer": "^3.7"
},
"autoload": {
"psr-4": {
Expand Down
101 changes: 37 additions & 64 deletions src/Events/Dispatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,105 +5,78 @@

use Closure;
use lucatume\WPBrowser\Exceptions\RuntimeException;
use ReflectionException;
use Symfony\Component\Console\Command\Command;
use Codeception\Codecept;
use lucatume\WPBrowser\Utils\Property;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use ReflectionException;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;

class Dispatcher
{
private static ?Codecept $codecept = null;
private static ?EventDispatcherInterface $codeceptDispatcher = null;
private static ?EventDispatcherInterface $eventDispatcher = null;

private static function getCodecept(): ?Codecept
public static function setEventDispatcher(EventDispatcherInterface $eventDispatcher = null): void
{
if (self::$codecept !== null) {
return self::$codecept;
}
$previousEventDispatcher = self::$eventDispatcher;

$reverseBacktraceHead = array_reverse(
array_slice(
array_reverse(
debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT)
),
0,
20
)
);
if ($previousEventDispatcher === $eventDispatcher) {
return;
}

foreach ($reverseBacktraceHead as $backtraceEntry) {
$object = $backtraceEntry['object'] ?? null;
if ($eventDispatcher === null) {
self::$eventDispatcher = null;
return;
}

if (!$object instanceof Command) {
continue;
try {
if ($previousEventDispatcher instanceof EventDispatcherInterface) {
$listeners = Property::readPrivate($previousEventDispatcher, 'listeners');
} else {
$listeners = [];
}

try {
$codeceptInstance = Property::readPrivate($object, 'codecept');

if (!$codeceptInstance instanceof Codecept) {
continue;
if ($listeners && is_array($listeners)) {
foreach ($listeners as $event => $priorities) {
foreach ($priorities as $priority => $callback) {
$eventDispatcher->addListener($event, $callback, $priority);
}
}

self::$codecept = $codeceptInstance;
return self::$codecept;
} catch (ReflectionException) {
}
} catch (ReflectionException) {
// Do nothing.
}

return self::$codecept;
self::$eventDispatcher = $eventDispatcher;
}

private static function getCodeceptionEventDispatcher(): EventDispatcherInterface
public static function getEventDispatcher(): EventDispatcherInterface
{
if (self::$codeceptDispatcher !== null) {
return self::$codeceptDispatcher;
}

$codeceptInstance = self::getCodecept();

if ($codeceptInstance === null) {
// Create a one local to the Dispatcher.
self::$codeceptDispatcher = new EventDispatcher();
return self::$codeceptDispatcher;
}

try {
$dispatcher = Property::readPrivate($codeceptInstance, 'dispatcher');
if (!$dispatcher instanceof EventDispatcherInterface) {
$message = 'The Codeception dispatcher is not an instance of ' . EventDispatcherInterface::class . '.';
throw new RuntimeException($message);
}
self::$codeceptDispatcher = $dispatcher;
} catch (ReflectionException) {
if (self::$eventDispatcher === null) {
// Create a one local to the Dispatcher.
self::$codeceptDispatcher = new EventDispatcher();
self::$eventDispatcher = new EventDispatcher();
}

return self::$codeceptDispatcher;
return self::$eventDispatcher;
}

/**
* Adds a callback to be performed on a global runner event, or on a local one if the global one cannot be found.
*
* The method name recalls the WordPress framework `add_action` function as it works pretty much the same.
*
* @param string $eventName The event to run the callback on.
* @param string $eventName The event to run the callback on.
* @param callable $listener The callback to run on the event.
* @param int $priority The priority that will be assigned to the callback in the context of the event.
* @param int $priority The priority that will be assigned to the callback in the context of the event.
*
* @return Closure The callback to remove the listener from the event.
*
* @throws RuntimeException If the event dispatcher cannot be found or built.
*/
public static function addListener(string $eventName, callable $listener, int $priority = 0): Closure
{
self::getCodeceptionEventDispatcher()->addListener($eventName, $listener, $priority);
self::getEventDispatcher()->addListener($eventName, $listener, $priority);

return static function () use ($eventName, $listener): void {
self::getCodeceptionEventDispatcher()->removeListener($eventName, $listener);
self::getEventDispatcher()->removeListener($eventName, $listener);
};
}

Expand All @@ -112,9 +85,9 @@ public static function addListener(string $eventName, callable $listener, int $p
*
* The method name recalls the WordPress framework `do_action` function as it works pretty much the same.
*
* @param string $name The name of the event to dispatch.
* @param mixed|null $origin The event origin: an object, a string or null.
* @param array<string,mixed> $context A map of the event context that will set as context of the dispatched
* @param string $name The name of the event to dispatch.
* @param mixed|null $origin The event origin: an object, a string or null.
* @param array<string,mixed> $context A map of the event context that will set as context of the dispatched
* event.
*
* @return object The dispatched event.
Expand All @@ -123,6 +96,6 @@ public static function dispatch(string $name, mixed $origin = null, array $conte
{
$event = new Event($name, $context, $origin);

return self::getCodeceptionEventDispatcher()->dispatch($event, $name);
return self::getEventDispatcher()->dispatch($event, $name);
}
}
72 changes: 72 additions & 0 deletions src/Extension/EventDispatcherBridge.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php

namespace lucatume\WPBrowser\Extension;

use Codeception\Event\SuiteEvent;
use Codeception\Events;
use Codeception\Exception\ExtensionException;
use Codeception\Extension;
use lucatume\WPBrowser\Events\Dispatcher;
use Symfony\Component\EventDispatcher\EventDispatcherInterface as SymfonyEventDispatcher;

class EventDispatcherBridge extends Extension
{
/**
* @var array<string,string>
*/
public static array $events = [
Events::MODULE_INIT => 'onModuleInit',
Events::SUITE_INIT => 'onSuiteInit',
Events::SUITE_BEFORE => 'onSuiteBefore',
];
private bool $eventDispatcherCaptured = false;

public function onModuleInit(SuiteEvent $event): void
{
$this->captureEventDispatcher($event, Events::MODULE_INIT);
}

public function onSuiteInit(SuiteEvent $event): void
{
$this->captureEventDispatcher($event, Events::SUITE_INIT);
}

public function onSuiteBefore(SuiteEvent $event): void
{
$this->captureEventDispatcher($event, Events::SUITE_BEFORE);
}

private function captureEventDispatcher(SuiteEvent $event, string $eventName): void
{
if ($this->eventDispatcherCaptured) {
return;
}

$eventDispatcher = null;
$trace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 5);
foreach ($trace as $traceEntry) {
if (!(isset($traceEntry['object']) && $traceEntry['object'] instanceof SymfonyEventDispatcher)) {
continue;
}
$eventDispatcher = $traceEntry['object'];
break;
}

if ($eventDispatcher === null) {
throw new ExtensionException($this, 'Could not find the application event dispatcher.');
}

$previousDispatcher = Dispatcher::getEventDispatcher();
/** @var callable[] $listeners */
$listeners = $previousDispatcher->getListeners($eventName);

// Call the listeners for this event now,remove them from the previous dispatcher.
foreach ($listeners as $listener) {
$listener($event, $eventName, $eventDispatcher);
$previousDispatcher->removeListener($eventName, $listener);
}

Dispatcher::setEventDispatcher($eventDispatcher);
$this->eventDispatcherCaptured = true;
}
}
9 changes: 9 additions & 0 deletions tests/_bootstrap.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
<?php
// This is global bootstrap for autoloading.
use Codeception\Event\SuiteEvent;
use Codeception\Events;
use Codeception\Util\Autoload;
use lucatume\WPBrowser\Events\Dispatcher;
use lucatume\WPBrowser\Utils\Db;
use lucatume\WPBrowser\Utils\Env;

Expand Down Expand Up @@ -29,3 +32,9 @@ function createTestDatabasesIfNotExist(): void
if (function_exists('uopz_allow_exit')) {
uopz_allow_exit(true);
}

// This is here to test the EventDispatcherBridge extension.
Dispatcher::addListener(Events::MODULE_INIT, function (SuiteEvent $suiteEvent) {
$suiteName = $suiteEvent->getSuite()?->getName();
codecept_debug('Suite name: ' . $suiteName);
});
6 changes: 0 additions & 6 deletions tests/_data/themes/isolated/functions.php

This file was deleted.

13 changes: 0 additions & 13 deletions tests/_data/themes/isolated/index.php

This file was deleted.

6 changes: 0 additions & 6 deletions tests/_data/themes/isolated/style.css

This file was deleted.

Loading

0 comments on commit d63160e

Please sign in to comment.