diff --git a/.github/workflows/functional.yml b/.github/workflows/functional.yml
index bfea7dd..a692850 100644
--- a/.github/workflows/functional.yml
+++ b/.github/workflows/functional.yml
@@ -45,7 +45,7 @@ jobs:
- uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # 2.37.2
with:
- php-version: "${{ matrix.php-version }}"
+ php-version: ${{ matrix.php-version }}
coverage: xdebug
- uses: ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda # 4.0.0
@@ -54,10 +54,10 @@ jobs:
- name: Run tests
if: ${{ !matrix.experimental }}
- # Include --fail-on-skipped when min PHP is > 7.2.5
- run: vendor/bin/phpunit --group functional
+ # Include --fail-on-skipped when min PHP is > 7.2.5 (for PHPUnit 9.5+)
+ run: vendor/bin/phpunit --group xdebug-functional
# Show deprecations on latest PHP
- name: Run tests (experimental)
if: ${{ matrix.experimental }}
- run: vendor/bin/phpunit --group functional --fail-on-skipped --display-deprecations
+ run: vendor/bin/phpunit --group xdebug-functional --fail-on-skipped --display-deprecations
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 717aec4..1756508 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -11,7 +11,7 @@
- functional
+ xdebug-functional
diff --git a/tests/App/Framework/AppHelper.php b/tests/App/Framework/AppHelper.php
index b929fab..a80b998 100644
--- a/tests/App/Framework/AppHelper.php
+++ b/tests/App/Framework/AppHelper.php
@@ -16,6 +16,15 @@
use Composer\XdebugHandler\Process;
use Composer\XdebugHandler\XdebugHandler;
+/**
+ * This class runs and provides functionality for the xdebug-handler functional
+ * test apps.
+ *
+ * It sets up the logger and outputs debug and status messages to stdout.
+ *
+ * The test apps can be run from the command-line and will show detailed output
+ * with the --display and --inis options.
+ */
class AppHelper extends AppRunner
{
public const ENV_IS_DISPLAY = 'XDEBUG_HANDLER_TEST_DISPLAY';
@@ -23,16 +32,15 @@ class AppHelper extends AppRunner
/** @var string */
private $appName;
+
/** @var string */
private $envPrefix;
+
/** @var non-empty-list */
private $serverArgv;
+
/** @var class-string|null */
private $className;
- /** @var bool */
- private $display;
- /** @var bool */
- private $showInis;
/** @var Logger */
private $logger;
@@ -41,7 +49,7 @@ class AppHelper extends AppRunner
private $output;
/** @var Status */
- private $status = null;
+ private $status;
public function __construct(string $script)
{
@@ -49,13 +57,11 @@ public function __construct(string $script)
$this->appName = $this->getAppName($script);
$this->envPrefix = $this->getEnvPrefix($script);
- $this->display = $this->getDisplayFromServer();
- $this->showInis = $this->getInisFromServer();
- $this->setServerArgv();
+ [$display, $showInis] = $this->setServerArgvAndOptions();
- $this->output = new Output($this->display);
+ $this->output = new Output($display);
$this->logger = new Logger($this->output);
- $this->status = new Status($this->display, $this->showInis);
+ $this->status = new Status($display, $showInis);
}
/**
@@ -73,9 +79,10 @@ public function getServerArgv0(): string
}
/**
+ * Starts an instance of XdebugHandler
*
- * @param class-string $class
- * @param array $settings
+ * @param class-string $class Extending class name
+ * @param array $settings XdebugHandler settings
*/
public function getXdebugHandler(?string $class = null, ?array $settings = null): XdebugHandler
{
@@ -102,16 +109,40 @@ public function getXdebugHandler(?string $class = null, ?array $settings = null)
return $xdebug;
}
+ /**
+ * Runs a PHP sub-process
+ *
+ * @param string $script The file to run
+ * @param PhpOptions $options
+ */
public function runScript(string $script, ?PhpOptions $options = null): void
{
- parent::runScript($script, $options);
+ $script = $this->checkScript($script);
+
+ if ($options === null) {
+ $options = new PhpOptions();
+ }
+
+ // set passthru in child proccesses so output gets collected
+ $options->setPassthru(true);
+ $this->phpExecutor->run($script, $options, $this->scriptDir);
}
+ /**
+ * Outputs a message prefixed appname[pid] to stdout
+ *
+ * @param string $message
+ */
public function write(string $message): void
{
$this->logger->write($message, $this->appName);
}
+ /**
+ * Outputs the Xdebug loaded status to stdout
+ *
+ * More details can be shown with the --display and --inis options.
+ */
public function writeXdebugStatus(): void
{
$className = $this->className ?? XdebugHandler::class;
@@ -122,10 +153,20 @@ public function writeXdebugStatus(): void
}
}
- private function setServerArgv(): void
+ /**
+ * Checks $_SERVER['argv'] and returns $display and $showInis values
+ *
+ * The flags to display the full status and ini file list are passed on the
+ * command-line, then removed and set in the environment.
+ *
+ * @return array
+ */
+ private function setServerArgvAndOptions(): array
{
$args = [];
$errors = false;
+ $display = false;
+ $showInis = false;
if (isset($_SERVER['argv']) && is_array($_SERVER['argv'])) {
foreach ($_SERVER['argv'] as $value) {
@@ -134,6 +175,18 @@ private function setServerArgv(): void
break;
}
+ if ($value === '--display') {
+ $display = true;
+ Process::setEnv(self::ENV_IS_DISPLAY, '1');
+ continue;
+ }
+
+ if ($value === '--inis') {
+ $showInis = true;
+ Process::setEnv(self::ENV_SHOW_INIS, '1');
+ continue;
+ }
+
$args[] = $value;
}
}
@@ -142,46 +195,12 @@ private function setServerArgv(): void
throw new \RuntimeException('$_SERVER[argv] is not as expected');
}
+ $_SERVER['argv'] = $args;
$this->serverArgv = $args;
- }
-
- private function getDisplayFromServer(): bool
- {
- $result = false;
-
- if (isset($_SERVER['argv']) && is_array($_SERVER['argv'])) {
- $key = array_search('--display', $_SERVER['argv'], true);
-
- if (is_int($key)) {
- $result = true;
- Process::setEnv(self::ENV_IS_DISPLAY, '1');
- // @phpstan-ignore argument.type
- array_splice($_SERVER['argv'], $key, 1);
- } else {
- $result = false !== getenv(self::ENV_IS_DISPLAY);
- }
- }
-
- return $result;
- }
-
- private function getInisFromServer(): bool
- {
- $result = false;
-
- if (isset($_SERVER['argv']) && is_array($_SERVER['argv'])) {
- $key = array_search('--inis', $_SERVER['argv'], true);
-
- if (is_int($key)) {
- $result = true;
- Process::setEnv(self::ENV_SHOW_INIS, '1');
- // @phpstan-ignore argument.type
- array_splice($_SERVER['argv'], $key, 1);
- } else {
- $result = false !== getenv(self::ENV_SHOW_INIS);
- }
- }
- return $result;
+ return [
+ $display || false !== getenv(self::ENV_IS_DISPLAY),
+ $showInis || false !== getenv(self::ENV_SHOW_INIS),
+ ];
}
}
diff --git a/tests/App/Framework/AppRunner.php b/tests/App/Framework/AppRunner.php
index 9e123eb..30f2a44 100644
--- a/tests/App/Framework/AppRunner.php
+++ b/tests/App/Framework/AppRunner.php
@@ -13,12 +13,16 @@
namespace Composer\XdebugHandler\Tests\App\Framework;
+/**
+ * This class runs and provides functionality for the xdebug-handler functional
+ * tests.
+ */
class AppRunner
{
/** @var string */
- private $scriptDir;
+ protected $scriptDir;
/** @var PhpExecutor */
- private $phpExecutor;
+ protected $phpExecutor;
public function __construct(?string $scriptDir = null)
{
@@ -31,6 +35,9 @@ public function __construct(?string $scriptDir = null)
$this->phpExecutor = new PhpExecutor();
}
+ /**
+ * Runs a script and returns its captured output
+ */
public function run(string $script, ?PhpOptions $options = null, bool $allow = false): Logs
{
$script = $this->checkScript($script);
@@ -54,19 +61,6 @@ public function run(string $script, ?PhpOptions $options = null, bool $allow = f
return new Logs($outputLines);
}
- public function runScript(string $script, ?PhpOptions $options = null): void
- {
- $script = $this->checkScript($script);
-
- if ($options === null) {
- $options = new PhpOptions();
- }
-
- // set passthru in child proccesses so output gets collected
- $options->setPassthru(true);
- $this->phpExecutor->run($script, $options, $this->scriptDir);
- }
-
public function getAppName(string $script): string
{
return basename($script, '.php');
@@ -84,7 +78,7 @@ public function getEnvPrefix(string $script): string
return strtoupper(str_replace(array('-', ' '), '_', $name));
}
- private function checkScript(string $script): string
+ protected function checkScript(string $script): string
{
if (file_exists($script)) {
return $script;
diff --git a/tests/App/Framework/Logs.php b/tests/App/Framework/Logs.php
index 4d4974a..9f9f699 100644
--- a/tests/App/Framework/Logs.php
+++ b/tests/App/Framework/Logs.php
@@ -13,6 +13,40 @@
namespace Composer\XdebugHandler\Tests\App\Framework;
+use Composer\Pcre\Preg;
+
+/**
+ * This class provides the log output from processes run by the test framework.
+ *
+ * The following (truncated) output lines:
+ *
+ * app-basic[413] start
+ * logger[413] Checking APP_BASIC_ALLOW_XDEBUG
+ * ...
+ * app-basic[414] start
+ * logger[414] Checking APP_BASIC_ALLOW_XDEBUG
+ * ...
+ * logger[413] Restarted process exited 0
+ *
+ * are stored in the items array as:
+ *
+ * items[0] = [
+ * { pid: 413, name: app-basic, value: start },
+ * { pid: 413, name: logger, value: Checking APP_BASIC_ALLOW_XDEBUG },
+ * { pid: 413, name: logger, value: Restarted process exited 0 },
+ * ]
+ *
+ * items[1] = [
+ * { pid: 414, name: app-basic, value: start },
+ * { pid: 414, name: logger, value: Checking APP_BASIC_ALLOW_XDEBUG },
+ * ]
+ *
+ * The zero-based indexes represent the process order. They are accessed by using
+ * a one-based sequence number in a call to getDefault() or getNamed().
+ *
+ * getDefault(1): returns logger values from process 0 (pid 413)
+ * getNamed(2, 'app-basic'): returns app-basic values from process 1 (pid 414)
+ */
class Logs
{
public const LOGGER_NAME = 'logger';
@@ -21,137 +55,74 @@ class Logs
private $items = [];
/**
- *
* @param list $outputLines
*/
public function __construct(array $outputLines)
{
- $pids = [];
+ $indexes = [];
foreach ($outputLines as $line) {
$line = trim($line);
- // @phpstan-ignore booleanNot.exprNotBoolean
- if (!preg_match('/^(.+)\\[(\\d+)\\](.+)$/', $line, $matches)) {
+ if (!Preg::isMatch('/^(.+)\[(\d+)\]\s(.+)$/', $line, $matches)) {
continue;
}
$pid = (int) $matches[2];
- $item = new LogItem($pid, $matches[1], $matches[3]);
+ $item = new LogItem($pid, (string) $matches[1], (string) $matches[3]);
- if (!isset($pids[$pid])) {
+ if (!isset($indexes[$pid])) {
$this->items[] = [];
- $pids[$pid] = count($this->items) - 1;
+ $indexes[$pid] = count($this->items) - 1;
}
- $index = $pids[$pid];
+ $index = $indexes[$pid];
$this->items[$index][] = $item;
}
}
/**
+ * Provides the debug output from a process
*
- * @return list
- */
- public function getOutputForProcess(int $seqNo): array
- {
- $index = $seqNo - 1;
-
- if (isset($this->items[$index])) {
- return $this->items[$index];
- }
-
- return [];
- }
-
- /**
+ * This is the default xdebug-handler debug output.
*
- * @return list
+ * @param int $sequence The one-based sequence number of the process
+ * @return ProcessLog
*/
- public function getValuesForProcess(int $seqNo, bool $forLogger = true): array
+ public function getDefault(int $sequence): ProcessLog
{
- $items = $this->getOutputForProcess($seqNo);
-
- if ($forLogger) {
- $result = $this->filterValuesForLogger($items);
- } else {
- $result = $this->filterValuesForScript($items);
- }
-
- return $result;
+ return $this->getProcessLog($sequence, 'logger');
}
/**
+ * Provides the log output from a named script in a process
*
- * @return list
- */
- public function getValuesForProcessName(int $seqNo, string $name): array
- {
- $items = $this->getOutputForProcess($seqNo);
-
- return $this->filterValuesForScriptName($items, $name);
- }
-
- /**
+ * This is the output from the script.
*
- * @param list $items
+ * @param int $sequence The one-based sequence number of the process
+ * @param string $name The app name to filter on
+ * @return ProcessLog
*/
- public function getItemFromList(array $items, int $seqNo, bool $complete = false): string
+ public function getNamed(int $sequence, string $name): ProcessLog
{
- $index = $seqNo - 1;
-
- if (!isset($items[$index])) {
- throw new \LogicException('Log item not found at index: '.$index);
- }
-
- $item = $items[$index];
-
- if (!$complete) {
- return $item->value;
- }
-
- return sprintf('%s[%d] %s', $item->name, $item->pid, $item->value);
+ return $this->getProcessLog($sequence, $name);
}
/**
+ * Provides either the default or named log output from a process
*
- * @param list $items
- * @return list
+ * @param int $sequence The one-based sequence number of the process
+ * @param string $name The app name to filter on
+ * @return ProcessLog
*/
- private function filterValuesForScript(array $items): array
+ private function getProcessLog(int $sequence, string $name): ProcessLog
{
- $result = array_filter($items, function($item) {
- return $item->name !== self::LOGGER_NAME;
- });
-
- return array_values($result);
- }
+ $items = $this->items[$sequence - 1] ?? [];
- /**
- *
- * @param list $items
- * @return list
- */
- private function filterValuesForScriptName(array $items, string $name): array
- {
$result = array_filter($items, function($item) use ($name) {
return $item->name === $name;
});
- return array_values($result);
- }
-
- /**
- *
- * @param list $items
- * @return list
- */
- private function filterValuesForLogger(array $items): array
- {
- $result = array_filter($items, function($item) {
- return $item->name === 'logger';
- });
-
- return array_values($result);
+ return new ProcessLog(array_values($result), $sequence);
}
}
diff --git a/tests/App/Framework/MessageProvider.php b/tests/App/Framework/MessageProvider.php
new file mode 100644
index 0000000..f7b7beb
--- /dev/null
+++ b/tests/App/Framework/MessageProvider.php
@@ -0,0 +1,130 @@
+
+ *
+ * For the full copyright and license information, please view
+ * the LICENSE file that was distributed with this source code.
+ */
+
+namespace Composer\XdebugHandler\Tests\App\Framework;
+
+class MessageProvider
+{
+ /** @var array */
+ private $items = [];
+
+ public function __construct(string $envAllow)
+ {
+ // type: array of phrases to check for
+ $this->items = [
+ 'check' => ['Checking ', $envAllow],
+ 'loaded' => ['The Xdebug extension is loaded'],
+ 'not-loaded' => ['The Xdebug extension is not loaded'],
+ 'restarting' => ['Process restarting', $envAllow.'='],
+ 'run-std' => ['Running', PHP_BINARY, '-n', '-c'],
+ 'run-persist' => ['Running', PHP_BINARY],
+ 'exit' => ['Restarted process exited 0'],
+ 'restarted' => ['Restarted (', 'ms). The Xdebug extension is not loaded'],
+ 'existing' => ['Process called with existing restart settings'],
+ 'allow' => ['No restart', $envAllow.'=1'],
+ 'allow-app' => ['No restart', $envAllow.'=', 'Allowed by application'],
+ 'allow-mode' => ['No restart', $envAllow.'=', 'Allowed by xdebug.mode'],
+ 'error' => ['No restart'],
+ ];
+ }
+
+ /**
+ * @param string[] $types
+ * @return array
+ */
+ public function compose(array $types): array
+ {
+ $result = [];
+
+ foreach ($types as $key) {
+ if (!isset($this->items[$key])) {
+ throw new \LogicException('Message type not found: '.$key);
+ }
+ $result[$key] = $this->items[$key];
+ }
+
+ return $result;
+ }
+
+ /**
+ * @return array, array>
+ */
+ public function getRestartMessages(bool $persistent = false): array
+ {
+ [$main, $child] = $this->getRestartTypes($persistent);
+ return [$this->compose($main), $this->compose($child)];
+ }
+
+ /**
+ * @return array
+ */
+ public function getNoRestartMessages(?string $allow = null): array
+ {
+ $types = $this->getNoRestartTypes($allow);
+ return $this->compose($types);
+ }
+
+ /**
+ * @return array
+ */
+ public function getExistingMessages(): array
+ {
+ $types = ['check', 'not-loaded', 'existing'];
+ return $this->compose($types);
+ }
+
+ /**
+ * @return array
+ */
+ public function getErrorMessages(string $error): array
+ {
+ $types = ['check', 'loaded', 'error'];
+ $result = $this->compose($types);
+ $result['error'][] = $error;
+
+ return $result;
+ }
+
+ /**
+ * @return array
+ */
+ public function getRestartTypes(bool $persistent = false): array
+ {
+ $main = [
+ 'check',
+ 'loaded',
+ 'restarting',
+ $persistent ? 'run-persist' : 'run-std',
+ 'exit',
+ ];
+
+ return [$main, ['check', 'restarted']];
+ }
+
+ /**
+ * @return string[]
+ */
+ public function getNoRestartTypes(?string $allow = null): array
+ {
+ $types = ['check'];
+
+ if ($allow === null) {
+ $types[] = 'not-loaded';
+ } else {
+ $types[] = 'loaded';
+ $types[] = $allow;
+ }
+
+ return $types;
+ }
+}
diff --git a/tests/App/Framework/Output.php b/tests/App/Framework/Output.php
index ccb89f8..91b026f 100644
--- a/tests/App/Framework/Output.php
+++ b/tests/App/Framework/Output.php
@@ -18,7 +18,7 @@
class Output
{
- public const ENV_OUTPUT_INDENT = 'XDEBUG_HANDLER_TEST_INDENT';
+ public const ENV_OUTPUT_PIDS = 'XDEBUG_HANDLER_TEST_PID';
/** @var bool */
private $isDisplay;
@@ -32,19 +32,8 @@ class Output
public function __construct(bool $display)
{
$this->isDisplay = $display;
- $this->indent = 0;
$this->pid = (int) getmypid();
-
- if (false === getenv(self::ENV_OUTPUT_INDENT)) {
- Process::setEnv(self::ENV_OUTPUT_INDENT, '0');
- } else {
- $this->indentIncrease();
- }
- }
-
- public function __destruct()
- {
- $this->indentDecrease();
+ $this->indent = $this->calculateIndent();
}
public function write(string $message, string $name): void
@@ -56,6 +45,29 @@ public function write(string $message, string $name): void
print($text);
}
+ private function calculateIndent(): int
+ {
+ $envPids = (string) getenv(self::ENV_OUTPUT_PIDS);
+
+ if ('' === $envPids) {
+ $pids = [];
+ } else {
+ $pids = array_map(function ($item) {
+ return (int) $item;
+ }, explode(',', $envPids));
+ }
+
+ if (!in_array($this->pid, $pids, true)) {
+ $pids[] = $this->pid;
+ } elseif ($pids[count($pids) - 1] !== $this->pid) {
+ array_pop($pids);
+ }
+
+ Process::setEnv(self::ENV_OUTPUT_PIDS, implode(',', $pids));
+
+ return (count($pids) - 1) * 2;
+ }
+
private function format(string $prefix, string $text, bool $color): string
{
if ($color) {
@@ -79,20 +91,4 @@ private function format(string $prefix, string $text, bool $color): string
return $text;
}
-
- private function indentDecrease(): void
- {
- if (false !== ($indent = getenv(self::ENV_OUTPUT_INDENT))) {
- $this->indent = intval($indent) - 2;
- Process::setEnv(self::ENV_OUTPUT_INDENT, (string) $this->indent);
- }
- }
-
- private function indentIncrease(): void
- {
- if (false !== ($indent = getenv(self::ENV_OUTPUT_INDENT))) {
- $this->indent = intval($indent) + 2;
- Process::setEnv(self::ENV_OUTPUT_INDENT, (string) $this->indent);
- }
- }
}
diff --git a/tests/App/Framework/ProcessLog.php b/tests/App/Framework/ProcessLog.php
new file mode 100644
index 0000000..81f6601
--- /dev/null
+++ b/tests/App/Framework/ProcessLog.php
@@ -0,0 +1,75 @@
+
+ *
+ * For the full copyright and license information, please view
+ * the LICENSE file that was distributed with this source code.
+ */
+
+namespace Composer\XdebugHandler\Tests\App\Framework;
+
+class ProcessLog
+{
+ /** @var list */
+ private $items = [];
+
+ /** @var string */
+ private $log;
+
+ /** @var int */
+ private $sequence;
+
+ /**
+ * @param list $items
+ */
+ public function __construct(array $items, int $sequence)
+ {
+ $this->items = $items;
+ $this->sequence = $sequence;
+
+ $list = array_map(function ($item) {
+ /** @var LogItem $item */
+ return sprintf('%s[%d] %s', $item->name, $item->pid, $item->value);
+ }, $items);
+
+ $this->log = implode("\n", $list);
+ }
+
+ public function getItem(int $index): LogItem
+ {
+ if (!isset($this->items[$index])) {
+ throw new \LogicException('Log item not found at index: '.$index);
+ }
+
+ return $this->items[$index];
+ }
+
+ /**
+ * @return list
+ */
+ public function getItems(): array
+ {
+ return $this->items;
+ }
+
+ /**
+ * Returns a string representation of the log output for this process
+ *
+ * @param string|null $prefix
+ * @return string
+ */
+ public function getOutputInfo(?string $prefix = null): string
+ {
+ $parts = $prefix !== null ? [$prefix] : [];
+ $parts[] = sprintf('Output from process #%d: ', $this->sequence);
+ $parts[] = $this->log;
+
+ return sprintf("%s\n", implode("\n", $parts));
+ }
+}
+
diff --git a/tests/App/Framework/Status.php b/tests/App/Framework/Status.php
index 7ffdbd6..c335617 100644
--- a/tests/App/Framework/Status.php
+++ b/tests/App/Framework/Status.php
@@ -16,10 +16,13 @@
use Composer\XdebugHandler\XdebugHandler;
/**
+ * This class provides xdebug-handler settings and values.
+ *
* @phpstan-import-type restartData from \Composer\XdebugHandler\PhpConfig
*/
class Status
{
+ private const AVAILABLE = 'available';
private const INVALID = 'not applicable';
private const MISSING = 'not available';
@@ -37,6 +40,7 @@ public function __construct(bool $display, bool $showInis)
}
/**
+ * Returns a list of xdebug-handler settings and values
*
* @param class-string $className
* @return list
@@ -47,10 +51,20 @@ public function getWorkingsStatus(string $className): array
$result = [];
// status
- [$status, $info] = $this->getXdebugStatus();
- $result[] = sprintf('[%s] %s', $status, $info);
+ $status = $this->getXdebugStatus();
+ $result[] = sprintf('[xdebug] %s', $status);
+
+ /** @var restartData|null $settings */
+ $settings = $className::getRestartSettings();
+
+ if ($settings === null) {
+ $shortSettings = $this->loaded ? self::INVALID : self::MISSING;
+ } else {
+ $shortSettings = self::AVAILABLE;
+ }
if (!$this->isDisplay) {
+ $result[] = sprintf('[settings] %s', $shortSettings);
return $result;
}
@@ -63,35 +77,28 @@ public function getWorkingsStatus(string $className): array
$result[] = sprintf('[skipped] %s', $skipped);
// envs
- foreach($this->getEnvs() as $item) {
+ foreach ($this->getEnvs() as $item) {
$result[] = sprintf('[env] %s', $item);
}
// inis
- foreach($this->getInis($className) as $item) {
+ foreach ($this->getInis($className) as $item) {
$result[] = sprintf('[ini] %s', $item);
}
// settings
- foreach($this->getSettings($className) as $item) {
+ foreach ($this->getSettings($settings) as $item) {
$result[] = sprintf('[settings] %s', $item);
}
return $result;
}
- /**
- *
- * @return array{0: string, 1: string}
- */
- private function getXdebugStatus(): array
+ private function getXdebugStatus(): string
{
- $status = $this->loaded ? 'XDEBUG' : 'NO XDEBUG';
- $text = 'The Xdebug extension is';
- $suffix = $this->loaded ? 'loaded' : 'not loaded';
- $info = sprintf('%s %s', $text, $suffix);
+ $suffix = $this->loaded ? 'loaded' : 'NOT loaded';
- return [$status, $info];
+ return sprintf('extension %s', $suffix);
}
/**
@@ -151,14 +158,13 @@ private function getEnvs(): array
*/
private function getInis(string $className): array
{
- $iniFiles = $this->findIniFiles($className);
-
+ /** @var non-empty-list $iniFiles */
+ $iniFiles = $className::getAllIniFiles();
if ($iniFiles[0] === '') {
- array_shift($iniFiles);
+ $iniFiles[0] = '(none)';
}
$count = count($iniFiles);
-
if ($this->showInis || $count === 1) {
return $iniFiles;
}
@@ -168,41 +174,13 @@ private function getInis(string $className): array
return [$iniFiles[0], $message];
}
- /**
- * @param class-string $className
- * @return list
- */
- private function findIniFiles(string $className): array
- {
- $extended = $className !== XdebugHandler::class;
-
- if ($extended) {
- $iniFiles = $className::getAllIniFiles();
- } elseif (class_exists(XdebugHandler::class)) {
- $iniFiles = $className::getAllIniFiles();
- } else {
- $iniFiles = array((string) php_ini_loaded_file());
- $scanned = php_ini_scanned_files();
-
- if ($scanned !== false) {
- $iniFiles = array_merge($iniFiles, array_map('trim', explode(',', $scanned)));
- }
- }
-
- // @phpstan-ignore-next-line
- return !is_array($iniFiles) ? [self::MISSING] : $iniFiles;
- }
-
/**
*
- * @param class-string $className
+ * @param restartData|null $settings
* @return list
*/
- private function getSettings(string $className): array
+ private function getSettings(?array $settings): array
{
- /** @var restartData|null $settings */
- $settings = $className::getRestartSettings();
-
if ($settings === null) {
return $this->loaded ? [self::INVALID] : [self::MISSING];
}
@@ -223,6 +201,7 @@ private function getSettings(string $className): array
foreach($settings as $key => $value) {
$data[] = sprintf('%s=%s', $key, $value);
}
+
return $data;
}
}
diff --git a/tests/App/Helpers/FunctionalTestCase.php b/tests/App/Helpers/FunctionalTestCase.php
index 2f0be40..3dc5a4a 100644
--- a/tests/App/Helpers/FunctionalTestCase.php
+++ b/tests/App/Helpers/FunctionalTestCase.php
@@ -16,6 +16,8 @@
use Composer\XdebugHandler\Tests\App\Framework\AppRunner;
use Composer\XdebugHandler\Tests\App\Framework\LogItem;
use Composer\XdebugHandler\Tests\App\Framework\Logs;
+use Composer\XdebugHandler\Tests\App\Framework\MessageProvider;
+use Composer\XdebugHandler\Tests\App\Framework\ProcessLog;
use PHPUnit\Framework\TestCase;
abstract class FunctionalTestCase extends TestCase
@@ -38,35 +40,68 @@ protected function compareXdebugVersion(string $version, string $op, ?string &$a
return version_compare($actual, $version, $op);
}
- protected function checkRestart(Logs $logs, ?int $childCount = null): void
+ /**
+ * @param Logs $logs
+ * @param array $mainMessages
+ * @param array $childMessages
+ * @return void
+ */
+ protected function checkRestart(Logs $logs, array $mainMessages, array $childMessages): void
{
- $main = $logs->getValuesForProcess(1);
- $child = $logs->getValuesForProcess(2);
+ $mainLogs = $logs->getDefault(1);
+ $this->checkExpectedMessages($mainMessages, $mainLogs, 'main');
- self::assertCount(5, $main);
+ $childLogs = $logs->getDefault(2);
+ $this->checkExpectedMessages($childMessages, $childLogs, 'child');
+ }
- $count = $childCount === null ? 2 : $childCount;
- self::assertCount($count, $child);
+ /**
+ * @param Logs $logs
+ * @param array $messages
+ * @return void
+ */
+ protected function checkNoRestart(Logs $logs, array $messages): void
+ {
+ $main = $logs->getDefault(1);
+ $this->checkExpectedMessages($messages, $main, 'main');
- if ($childCount === null) {
- $item = $logs->getItemFromList($child, 2);
- self::assertStringContainsString('The Xdebug extension is not loaded', $item);
- }
+ $child = $logs->getDefault(2);
+ self::assertCount(0, $child->getItems());
}
- protected function checkNoRestart(Logs $logs, ?string $extraExpected = null): void
+ /**
+ * @param array $expected
+ * @param ProcessLog $log
+ * @param string $name
+ * @return void
+ */
+ protected function checkExpectedMessages(array $expected, ProcessLog $log, string $name): void
{
- $main = $logs->getValuesForProcess(1);
- $child = $logs->getValuesForProcess(2);
-
- self::assertCount(3, $main);
- self::assertCount(0, $child);
+ $assertMessage = $log->getOutputInfo($name);
+ self::assertCount(count($expected), $log->getItems(), $assertMessage);
+ $index = 0;
- $item = $logs->getItemFromList($main, 3);
- self::assertStringContainsString('No restart', $item);
+ foreach ($expected as $type => $messages) {
+ $item = $log->getItem($index);
+ $assertMessage = $log->getOutputInfo(sprintf('%s: %s', $name, $type));
+ $index += 1;
- if ($extraExpected !== null) {
- self::assertStringContainsString($extraExpected, $item);
+ foreach ($messages as $message) {
+ self::assertStringContainsString($message, $item->value, $assertMessage);
+ }
}
}
-}
\ No newline at end of file
+
+ protected function checkExpectedMessage(ProcessLog $log, int $index, string $expected): void
+ {
+ $message = $log->getOutputInfo();
+ $item = $log->getItem($index);
+ self::assertStringContainsString($expected, $item->value, $message);
+ }
+
+ protected function createMessageProvider(string $script): MessageProvider
+ {
+ $envAllow = $this->runner->getEnvAllow($script);
+ return new MessageProvider($envAllow);
+ }
+}
diff --git a/tests/App/README.md b/tests/App/README.md
index 2415c99..5f228a5 100644
--- a/tests/App/README.md
+++ b/tests/App/README.md
@@ -50,12 +50,12 @@ php app-extend-allow.php -h --display
### app-extend-ini
Demonstrates how an extended class can restart with a specific ini setting, even if xdebug is not
-loaded. The `phar_readonly` ini setting is used in this example.
+loaded. The `phar.readonly` ini setting is used in this example.
```sh
cd tests/App
-php -dphar.read_only=1 app-extend-ini.php --display
+php -dphar.readonly=1 app-extend-ini.php --display
```
### app-extend-mode
@@ -97,11 +97,7 @@ merged, so it is available in the restart.
If stdin is used, it will be read in the restart:
```sh
-# Unixy
-cat app-plain.php | php -dauto_prepend_file=app-prepend.php -- --display
-
-# Windows
-type app-plain.php | php -dauto_prepend_file=app-prepend.php -- --display
+php -dauto_prepend_file=app-prepend.php -- --display < app-plain.php
```
### app-stdin
@@ -114,11 +110,7 @@ Uses xdebug-handler from stdin to remove xdebug from a script. Note that either
```sh
cd tests/App
-# Unixy
-cat app-stdin.php | php -- app-plain.php --display
-
-# Windows
-type app-stdin.php | php -- app-plain.php --display
+php -- app-plain.php --display < app-stdin.php
```
While this works in simple scenarios, it is not recommended because the restart settings are not
diff --git a/tests/App/app-basic.php b/tests/App/app-basic.php
index d8fee4b..a15d2fd 100644
--- a/tests/App/app-basic.php
+++ b/tests/App/app-basic.php
@@ -19,7 +19,7 @@
/**
* Restarts without xdebug
*
- * Usage: php app.php
+ * Usage: php app-basic.php
*/
$app = new AppHelper(__FILE__);
diff --git a/tests/App/app-extend-ini.php b/tests/App/app-extend-ini.php
index ffdac27..79c4139 100644
--- a/tests/App/app-extend-ini.php
+++ b/tests/App/app-extend-ini.php
@@ -18,9 +18,9 @@
use Composer\XdebugHandler\XdebugHandler;
/**
- * Restarts without xdebug with phar.read_only=0, even if xdebug is not loaded
+ * Restarts without xdebug with phar.readonly=0, even if xdebug is not loaded
*
- * Usage: php -dphar.read_only=1 app-extend-ini.php
+ * Usage: php -dphar.readonly=1 app-extend-ini.php
*/
$app = new AppHelper(__FILE__);
diff --git a/tests/App/app-persistent.php b/tests/App/app-persistent.php
index cb1a8d3..79ca271 100644
--- a/tests/App/app-persistent.php
+++ b/tests/App/app-persistent.php
@@ -21,7 +21,7 @@
* Restarts without xdebug in persistent mode, then calls sub-processes:
* - app-plain.php (xdebug not loaded)
* - app-plain.php with original settings (xdebug will be loaded)
- * - app-other.php (xdebug not loaded)
+ * - app-basic.php (xdebug not loaded)
*
* Usage: php app-persistent.php
*/
diff --git a/tests/App/app-plain.php b/tests/App/app-plain.php
index 664e974..600287b 100644
--- a/tests/App/app-plain.php
+++ b/tests/App/app-plain.php
@@ -18,7 +18,7 @@
/**
* A plain php script that does not include xdebug-handler
*
- * Usage: php app-none.php
+ * Usage: php app-plain.php
*/
$app = new AppHelper(__FILE__);
diff --git a/tests/App/app-prepend.php b/tests/App/app-prepend.php
index fa6f172..8ebd534 100644
--- a/tests/App/app-prepend.php
+++ b/tests/App/app-prepend.php
@@ -25,8 +25,7 @@
* ini content is merged, so it is available in the restart.
*
* If stdin is used, it will be read in the restart:
- * Usage (Unixy) : cat app-plain.php | php -dauto_prepend_file=app-prepend.php
- * Usage (Windows) : type app-plain.php | php -dauto_prepend_file=app-prepend.php
+ * Usage: php -dauto_prepend_file=app-prepend.php < app-plain.php
*/
$app = new AppHelper(__FILE__);
diff --git a/tests/App/app-standard.php b/tests/App/app-standard.php
new file mode 100644
index 0000000..b64afc5
--- /dev/null
+++ b/tests/App/app-standard.php
@@ -0,0 +1,53 @@
+
+ *
+ * For the full copyright and license information, please view
+ * the LICENSE file that was distributed with this source code.
+ */
+
+declare(strict_types=1);
+
+require __DIR__.'/../../vendor/autoload.php';
+
+use Composer\XdebugHandler\Tests\App\Framework\AppHelper;
+use Composer\XdebugHandler\Tests\App\Framework\PhpOptions;
+use Composer\XdebugHandler\XdebugHandler;
+use Composer\XdebugHandler\PhpConfig;
+
+/**
+ * Restarts without xdebug in standard mode, then calls sub-processes:
+ * - app-plain.php (xdebug will be loaded)
+ * - app-basic.php with standard settings (xdebug not loaded)
+ *
+ * Usage: php app-standard.php
+ */
+
+$app = new AppHelper(__FILE__);
+
+$app->write('start');
+
+$xdebug = $app->getXdebugHandler(null);
+$xdebug->check();
+
+$app->writeXdebugStatus();
+
+// Simple call to app-plain (xdebug will be loaded)
+$app->write('CALL app-plain.php');
+$app->write('- if we are in a restart, xdebug will be loaded');
+$app->runScript('app-plain.php');
+
+// app-basic with xdebug
+$app->write('CALL app-basic.php with standard settings');
+$app->write('- if we are in a restart, xdebug should not be loaded');
+
+$phpConfig = new PhpConfig();
+$args = $phpConfig->useStandard();
+$options = new PhpOptions();
+$options->addPhpArgs(...$args);
+
+$app->runScript('app-basic.php', $options);
+$app->write('finish');
diff --git a/tests/App/app-stdin.php b/tests/App/app-stdin.php
index 716ef6b..361b87c 100644
--- a/tests/App/app-stdin.php
+++ b/tests/App/app-stdin.php
@@ -19,9 +19,7 @@
/**
* Restarts without xdebug using stdin
*
- * Usage (Unixy) : cat app-stdin.php | php -- app-plain.php
- * Usage (Windows) : type app-stdin.php | php -- app-plain.php
- *
+ * Usage: php -- app-plain.php < app-stdin.php
*/
$app = new AppHelper(__FILE__);
@@ -36,8 +34,8 @@
$settings = null;
if ($mainScript === 'Standard input code' && isset($argv[1])) {
$settings = ['mainScript' => $argv[1]];
- // @phpstan-ignore-next-line
- unset($_SERVER['argv'][1]);
+ // @phpstan-ignore argument.type
+ array_splice($_SERVER['argv'], 1, 1);
}
$xdebug = $app->getXdebugHandler(null, $settings);
diff --git a/tests/AppNoRestartTest.php b/tests/AppNoRestartTest.php
index ab4c757..6e32b8b 100644
--- a/tests/AppNoRestartTest.php
+++ b/tests/AppNoRestartTest.php
@@ -14,12 +14,13 @@
namespace Composer\XdebugHandler\Tests;
use Composer\XdebugHandler\Tests\App\Framework\AppRunner;
+use Composer\XdebugHandler\Tests\App\Framework\Messages;
use Composer\XdebugHandler\Tests\App\Framework\PhpOptions;
use Composer\XdebugHandler\Tests\App\Helpers\FunctionalTestCase;
use PHPUnit\Framework\TestCase;
/**
- * @group functional
+ * @group xdebug-functional
*/
class AppNoRestartTest extends FunctionalTestCase
{
@@ -33,12 +34,10 @@ public function testNoRestartWhenAllowed(): void
$script = 'app-basic.php';
$logs = $this->runner->run($script, null, true);
- $this->checkNoRestart($logs);
- $appName = $this->runner->getAppName($script);
- $child = $logs->getValuesForProcessName(1, $appName);
- $item = $logs->getItemFromList($child, 2);
- self::assertStringContainsString('The Xdebug extension is loaded', $item);
+ $provider = $this->createMessageProvider($script);
+ $expected = $provider->getNoRestartMessages('allow');
+ $this->checkNoRestart($logs, $expected);
}
/**
@@ -58,7 +57,10 @@ public function testNoRestartWhenModeOff(): void
$options->addPhpArgs('-dxdebug.mode=off');
$logs = $this->runner->run($script, $options);
- $this->checkNoRestart($logs, 'Allowed by xdebug.mode');
+
+ $provider = $this->createMessageProvider($script);
+ $expected = $provider->getNoRestartMessages('allow-mode');
+ $this->checkNoRestart($logs, $expected);
}
/**
@@ -74,7 +76,10 @@ function testNoRestartWhenConfigError(): void
$options->addPhpArgs('-ddisable_functions=proc_open');
$logs = $this->runner->run($script, $options);
- $this->checkNoRestart($logs, 'proc_open function is disabled');
+
+ $provider = $this->createMessageProvider($script);
+ $expected = $provider->getErrorMessages('proc_open function is disabled');
+ $this->checkNoRestart($logs, $expected);
}
/**
@@ -90,6 +95,9 @@ function testNoRestartWhenAllowedByApplication(): void
$options->addScriptArgs('--help');
$logs = $this->runner->run($script, $options);
- $this->checkNoRestart($logs, 'Allowed by application');
+
+ $provider = $this->createMessageProvider($script);
+ $expected = $provider->getNoRestartMessages('allow-app');
+ $this->checkNoRestart($logs, $expected);
}
}
diff --git a/tests/AppNoXdebugTest.php b/tests/AppNoXdebugTest.php
new file mode 100644
index 0000000..843179b
--- /dev/null
+++ b/tests/AppNoXdebugTest.php
@@ -0,0 +1,77 @@
+
+ *
+ * For the full copyright and license information, please view
+ * the LICENSE file that was distributed with this source code.
+ */
+
+declare(strict_types=1);
+
+namespace Composer\XdebugHandler\Tests;
+
+use Composer\XdebugHandler\Tests\App\Framework\AppRunner;
+use Composer\XdebugHandler\Tests\App\Framework\Messages;
+use Composer\XdebugHandler\Tests\App\Framework\PhpOptions;
+use Composer\XdebugHandler\Tests\App\Helpers\FunctionalTestCase;
+use PHPUnit\Framework\TestCase;
+
+class AppNoXdebugTest extends FunctionalTestCase
+{
+ /**
+ * Tests no restart when xdebug is not loaded
+ */
+ public function testNoRestartWithNoXdebug(): void
+ {
+ if (extension_loaded('xdebug')) {
+ self::markTestSkipped('xdebug must not be loaded for this test');
+ }
+
+ $script = 'app-basic.php';
+
+ $logs = $this->runner->run($script);
+
+ $provider = $this->createMessageProvider($script);
+ $expected = $provider->compose(['check', 'not-loaded']);
+ $this->checkNoRestart($logs, $expected);
+ }
+
+ /**
+ * Tests a forced restart when xdebug is not loaded
+ */
+ public function testForcedRestartWithNoXdebug(): void
+ {
+ if (extension_loaded('xdebug')) {
+ self::markTestSkipped('xdebug must not be loaded for this test');
+ }
+
+ $script = 'app-extend-ini.php';
+
+ $options = new PhpOptions();
+ $options->addPhpArgs('-dphar.readonly=1');
+
+ $logs = $this->runner->run($script, $options);
+
+ $provider = $this->createMessageProvider($script);
+ [$mainTypes, $childTypes] = $provider->getRestartTypes();
+
+ $index = array_search('loaded', $mainTypes, true);
+ if (is_int($index)) {
+ $mainTypes[$index] = 'not-loaded';
+ }
+
+ $main = $provider->compose($mainTypes);
+ $child = $provider->compose($childTypes);
+ $this->checkRestart($logs, $main, $child);
+
+ // check child
+ $processLog = $logs->getNamed(2, 'app-extend-ini');
+
+ // check ini setting has changed at index 1
+ $expected = 'phar.readonly=0';
+ $this->checkExpectedMessage($processLog, 1, $expected);
+ }
+}
diff --git a/tests/AppRestartTest.php b/tests/AppRestartTest.php
index ab47f57..5456ac6 100644
--- a/tests/AppRestartTest.php
+++ b/tests/AppRestartTest.php
@@ -15,16 +15,18 @@
use Composer\XdebugHandler\Tests\App\Framework\AppRunner;
use Composer\XdebugHandler\Tests\App\Framework\LogItem;
+use Composer\XdebugHandler\Tests\App\Framework\Messages;
use Composer\XdebugHandler\Tests\App\Framework\PhpOptions;
use Composer\XdebugHandler\Tests\App\Helpers\FunctionalTestCase;
use PHPUnit\Framework\TestCase;
/**
- * @group functional
+ * @group xdebug-functional
*/
class AppRestartTest extends FunctionalTestCase
{
/**
+ * Tests basic restart functionality
*
* @requires extension xdebug
*/
@@ -33,10 +35,14 @@ public function testRestart(): void
$script = 'app-basic.php';
$logs = $this->runner->run($script);
- $this->checkRestart($logs);
+
+ $provider = $this->createMessageProvider($script);
+ [$main, $child] = $provider->getRestartMessages();
+ $this->checkRestart($logs, $main, $child);
}
/**
+ * Tests a restart using an auto_prepend_file
*
* @requires extension xdebug
*/
@@ -48,12 +54,21 @@ public function testRestartWithPrependFile(): void
$options->addPhpArgs('-dauto_prepend_file=app-prepend.php');
$logs = $this->runner->run($script, $options);
- $this->checkRestart($logs);
- // check app-plain has run
- $appName = $this->runner->getAppName($script);
- $child = $logs->getValuesForProcessName(2, $appName);
- self::assertNotEmpty($child);
+ $provider = $this->createMessageProvider('app-prepend');
+ [$main, $child] = $provider->getRestartMessages();
+ $this->checkRestart($logs, $main, $child);
+
+ // check app-plain
+ $processLog = $logs->getNamed(2, 'app-plain');
+
+ // check not loaded at index 1
+ $expected = '[xdebug] extension NOT loaded';
+ $this->checkExpectedMessage($processLog, 1, $expected);
+
+ // check settings available at index 2
+ $expected = '[settings] available';
+ $this->checkExpectedMessage($processLog, 2, $expected);
}
/**
@@ -69,12 +84,21 @@ public function testRestartWithPrependFileStdin(): void
$options->setStdin(true);
$logs = $this->runner->run($script, $options);
- $this->checkRestart($logs);
- // check app-plain has run
- $appName = 'Standard input code';
- $child = $logs->getValuesForProcessName(2, $appName);
- self::assertNotEmpty($child);
+ $provider = $this->createMessageProvider('app-prepend.php');
+ [$main, $child] = $provider->getRestartMessages();
+ $this->checkRestart($logs, $main, $child);
+
+ // check app-plain
+ $processLog = $logs->getNamed(2, 'Standard input code');
+
+ // check not loaded at index 1
+ $expected = '[xdebug] extension NOT loaded';
+ $this->checkExpectedMessage($processLog, 1, $expected);
+
+ // check settings available at index 2
+ $expected = '[settings] available';
+ $this->checkExpectedMessage($processLog, 2, $expected);
}
/**
@@ -91,13 +115,22 @@ public function testRestartWithStdin(): void
$options->setStdin(true);
$logs = $this->runner->run($script, $options);
- $this->checkRestart($logs, 0);
- // check not loaded from app-plain
- $appName = $this->runner->getAppName('app-plain.php');
- $child = $logs->getValuesForProcessName(2, $appName);
- $item = $logs->getItemFromList($child, 2);
- self::assertStringContainsString('The Xdebug extension is not loaded', $item);
+ $provider = $this->createMessageProvider('Standard input code');
+ [$main] = $provider->getRestartMessages();
+ // app-plain does not implement xdebug-handler so there is no logger output
+ $this->checkRestart($logs, $main, []);
+
+ // check app-plain
+ $processLog = $logs->getNamed(2, 'app-plain');
+
+ // check not loaded at index 1
+ $expected = '[xdebug] extension NOT loaded';
+ $this->checkExpectedMessage($processLog, 1, $expected);
+
+ // check settings not available at index 2
+ $expected = '[settings] not available';
+ $this->checkExpectedMessage($processLog, 2, $expected);
}
/**
@@ -109,23 +142,27 @@ public function testRestartWithIniChange(): void
$script = 'app-extend-ini.php';
$options = new PhpOptions();
- $options->addPhpArgs('-dphar.read_only=1');
+ $options->addPhpArgs('-dphar.readonly=1');
$logs = $this->runner->run($script, $options);
- $this->checkRestart($logs);
- // check ini setting has changed in child
- $appName = $this->runner->getAppName($script);
- $child = $logs->getValuesForProcessName(2, $appName);
- $item = $logs->getItemFromList($child, 2);
- self::assertStringContainsString('phar.readonly=0', $item);
+ $provider = $this->createMessageProvider($script);
+ [$main, $child] = $provider->getRestartMessages();
+ $this->checkRestart($logs, $main, $child);
+
+ // check child
+ $processLog = $logs->getNamed(2, 'app-extend-ini');
+
+ // check ini setting has changed at index 1
+ $expected = 'phar.readonly=0';
+ $this->checkExpectedMessage($processLog, 1, $expected);
}
/**
*
* @requires extension xdebug
*/
- public function testRestartWithXdebug(): void
+ public function testRestartWithXdebugModeChange(): void
{
$version = (string) phpversion('xdebug');
@@ -139,43 +176,104 @@ public function testRestartWithXdebug(): void
$options->addPhpArgs('-dxdebug.mode=develop');
$logs = $this->runner->run($script, $options);
- $this->checkRestart($logs, 2);
- $child = $logs->getValuesForProcess(2);
- $item = $logs->getItemFromList($child, 2);
- self::assertStringContainsString('The Xdebug extension is loaded', $item);
- self::assertStringContainsString('xdebug.mode=coverage', $item);
+ $provider = $this->createMessageProvider($script);
+ [$main, $child] = $provider->getRestartMessages();
+
+ // Modify restarted messages
+ $child['restarted'][1] = 'The Xdebug extension is loaded';
+ $child['restarted'][2] = 'xdebug.mode=coverage';
+ $this->checkRestart($logs, $main, $child);
}
/**
*
* @requires extension xdebug
*/
- public function testRestartWithProcessPersistent(): void
+ public function testRestartChildInStandardConfig(): void
+ {
+ $script = 'app-standard.php';
+
+ $logs = $this->runner->run($script);
+
+ $provider = $this->createMessageProvider($script);
+ [$main, $child] = $provider->getRestartMessages();
+ $this->checkRestart($logs, $main, $child);
+
+ // first sub-process - app-plain
+ $processLog = $logs->getNamed(3, 'app-plain');
+
+ // check loaded at index 1
+ $expected = 'extension loaded';
+ $this->checkExpectedMessage($processLog, 1, $expected);
+
+ // check settings not applicable at index 2
+ $expected = '[settings] not applicable';
+ $this->checkExpectedMessage($processLog, 2, $expected);
+
+ // second sub-process - app-basic
+ $processLog = $logs->getDefault(4);
+
+ $provider = $this->createMessageProvider('app-basic');
+ $expected = $provider->getExistingMessages();
+ $this->checkExpectedMessages($expected, $processLog, 'app-basic');
+
+ // get app-basic logs
+ $processLog = $logs->getNamed(4, 'app-basic');
+
+ // check settings available at index 2
+ $expected = '[settings] available';
+ $this->checkExpectedMessage($processLog, 2, $expected);
+ }
+
+ /**
+ *
+ * @requires extension xdebug
+ */
+ public function testRestartChildInPersistentConfig(): void
{
$script = 'app-persistent.php';
$logs = $this->runner->run($script);
- $this->checkRestart($logs);
-
- // first sub-process - check not loaded from app-plain
- $appName = $this->runner->getAppName('app-plain.php');
- $child = $logs->getValuesForProcessName(3, $appName);
- $item = $logs->getItemFromList($child, 2);
- self::assertStringContainsString('The Xdebug extension is not loaded', $item);
-
- // second sub-process - check loaded from app-plain
- $appName = $this->runner->getAppName('app-plain.php');
- $child = $logs->getValuesForProcessName(4, $appName);
- $item = $logs->getItemFromList($child, 2);
- self::assertStringContainsString('The Xdebug extension is loaded', $item);
-
- // third sub-process - check not loaded from app-basic
- $child = $logs->getValuesForProcess(5);
- $item = $logs->getItemFromList($child, 2);
- self::assertStringContainsString('The Xdebug extension is not loaded', $item);
-
- $item = $logs->getItemFromList($child, 3);
- self::assertStringContainsString('Process called with existing restart settings', $item);
+
+ $provider = $this->createMessageProvider($script);
+ [$main, $child] = $provider->getRestartMessages(true);
+ $this->checkRestart($logs, $main, $child);
+
+ // first sub-process - app-plain
+ $processLog = $logs->getNamed(3, 'app-plain');
+
+ // check not loaded at index 1
+ $expected = 'extension NOT loaded';
+ $this->checkExpectedMessage($processLog, 1, $expected);
+
+ // check settings available at index 2
+ $expected = '[settings] available';
+ $this->checkExpectedMessage($processLog, 2, $expected);
+
+ // second sub-process - app-plain
+ $processLog = $logs->getNamed(4, 'app-plain');
+
+ // check loaded at index 1
+ $expected = 'extension loaded';
+ $this->checkExpectedMessage($processLog, 1, $expected);
+
+ // check settings not applicable at index 2
+ $expected = '[settings] not applicable';
+ $this->checkExpectedMessage($processLog, 2, $expected);
+
+ // third sub-process - app-basic
+ $processLog = $logs->getDefault(5);
+
+ $provider = $this->createMessageProvider('app-basic');
+ $expected = $provider->getExistingMessages();
+ $this->checkExpectedMessages($expected, $processLog, 'app-basic');
+
+ // get app-basic logs
+ $processLog = $logs->getNamed(5, 'app-basic');
+
+ // check settings available at index 2
+ $expected = '[settings] available';
+ $this->checkExpectedMessage($processLog, 2, $expected);
}
}
diff --git a/tests/Helpers/IniHelper.php b/tests/Helpers/IniHelper.php
index 02bff85..3d75a76 100644
--- a/tests/Helpers/IniHelper.php
+++ b/tests/Helpers/IniHelper.php
@@ -142,7 +142,7 @@ private function setEnvironment(): void
$this->setEnv(CoreMock::ORIGINAL_INIS, implode(PATH_SEPARATOR, $this->files));
if ($this->envOptions !== null) {
- list($scanDir, $phprc) = $this->envOptions;
+ [$scanDir, $phprc] = $this->envOptions;
$this->setEnv('PHP_INI_SCAN_DIR', $scanDir);
$this->setEnv('PHPRC', $phprc);
}
diff --git a/tests/Mocks/CoreMock.php b/tests/Mocks/CoreMock.php
index 94a8894..2cf00b7 100644
--- a/tests/Mocks/CoreMock.php
+++ b/tests/Mocks/CoreMock.php
@@ -67,7 +67,7 @@ public static function createAndCheck($loaded, ?self $parentProcess = null, arra
$mode = null;
if (is_array($loaded)) {
- list($loaded, $mode) = $loaded;
+ [$loaded, $mode] = $loaded;
}
if (is_string($mode) && !$loaded) {