Skip to content

Commit

Permalink
Add more tests (#232)
Browse files Browse the repository at this point in the history
  • Loading branch information
xepozz committed Jan 5, 2024
1 parent d5232f6 commit 8b0585a
Show file tree
Hide file tree
Showing 25 changed files with 779 additions and 107 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Expand Up @@ -29,4 +29,4 @@ jobs:
os: >-
['ubuntu-latest', 'windows-latest']
php: >-
['8.0', '8.1']
['8.1', '8.2', '8.3']
2 changes: 1 addition & 1 deletion .github/workflows/composer-require-checker.yml
Expand Up @@ -30,4 +30,4 @@ jobs:
os: >-
['ubuntu-latest']
php: >-
['8.0']
['8.1']
2 changes: 1 addition & 1 deletion .github/workflows/rector.yml
Expand Up @@ -18,4 +18,4 @@ jobs:
os: >-
['ubuntu-latest']
php: >-
['8.0']
['8.1']
2 changes: 1 addition & 1 deletion .github/workflows/static.yml
Expand Up @@ -28,4 +28,4 @@ jobs:
os: >-
['ubuntu-latest']
php: >-
['8.0', '8.1']
['8.1', '8.2', '8.3']
2 changes: 1 addition & 1 deletion composer.json
Expand Up @@ -19,7 +19,7 @@
"minimum-stability": "dev",
"prefer-stable": true,
"require": {
"php": "^8.0",
"php": "^8.1",
"ext-mbstring": "*",
"guzzlehttp/psr7": "^2.4",
"jetbrains/phpstorm-attributes": "^1.0",
Expand Down
8 changes: 4 additions & 4 deletions config/di.php
Expand Up @@ -17,16 +17,16 @@
use Yiisoft\Yii\Debug\Storage\StorageInterface;

/**
* @var $params array
* @var array $params
*/

$common = [
StorageInterface::class => static function (ContainerInterface $container) use ($params) {
StorageInterface::class => static function (ContainerInterface $container, Aliases $aliases) use ($params) {
$params = $params['yiisoft/yii-debug'];
$debuggerIdGenerator = $container->get(DebuggerIdGenerator::class);
$aliases = $container->get(Aliases::class);
$excludedClasses = $params['dumper.excludedClasses'];
$fileStorage = new FileStorage($params['path'], $debuggerIdGenerator, $aliases, $excludedClasses);
$fileStorage = new FileStorage($aliases->get($params['path']), $debuggerIdGenerator, $excludedClasses);

if (isset($params['historySize'])) {
$fileStorage->setHistorySize((int) $params['historySize']);
}
Expand Down
9 changes: 3 additions & 6 deletions phpunit.xml.dist
@@ -1,16 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.6/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true"
verbose="true"
failOnRisky="true"
failOnWarning="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
stopOnFailure="false"
executionOrder="random"
resolveDependencies="true"
>
<php>
<ini name="error_reporting" value="-1"/>
Expand All @@ -24,7 +21,7 @@

<coverage>
<include>
<directory>./src</directory>
<directory>src</directory>
</include>
</coverage>
</phpunit>
4 changes: 1 addition & 3 deletions src/Collector/ContainerInterfaceProxy.php
Expand Up @@ -127,12 +127,10 @@ private function getServiceProxyFromCallable(callable $callback): ?object
private function getCommonMethodProxy(string $service, object $instance, array $callbacks): ?object
{
$methods = [];
while ($callback = current($callbacks)) {
$method = key($callbacks);
foreach ($callbacks as $method => $callback) {
if (is_string($method) && is_callable($callback)) {
$methods[$method] = $callback;
}
next($callbacks);
}

return $this->proxyManager->createObjectProxy(
Expand Down
4 changes: 4 additions & 0 deletions src/Collector/Stream/FilesystemStreamProxy.php
Expand Up @@ -44,13 +44,17 @@ public function __call(string $name, array $arguments)

public function __destruct()
{
if (self::$collector === null) {
return;
}
foreach ($this->operations as $name => $operation) {
self::$collector->collect(
operation: $name,
path: $operation['path'],
args: $operation['args'],
);
}
self::unregister();
}

public function __get(string $name)
Expand Down
4 changes: 4 additions & 0 deletions src/Collector/Stream/HttpStreamProxy.php
Expand Up @@ -47,13 +47,17 @@ public function __call(string $name, array $arguments)

public function __destruct()
{
if (self::$collector === null) {
return;
}
foreach ($this->operations as $name => $operation) {
self::$collector->collect(
operation: $name,
path: $operation['path'],
args: $operation['args'],
);
}
self::unregister();
}

public function __get(string $name)
Expand Down
79 changes: 50 additions & 29 deletions src/Dumper.php
Expand Up @@ -5,20 +5,19 @@
namespace Yiisoft\Yii\Debug;

use Closure;
use JetBrains\PhpStorm\Pure;
use Yiisoft\VarDumper\ClosureExporter;

final class Dumper
{
private array $objects = [];

private static ?ClosureExporter $closureExporter = null;
private array $excludedClasses = [];
private array $excludedClasses;

/**
* @param mixed $variable Variable to dump.
*/
private function __construct(private mixed $variable, array $excludedClasses = [])
private function __construct(private mixed $variable, array $excludedClasses)
{
$this->excludedClasses = array_flip($excludedClasses);
}
Expand All @@ -28,7 +27,6 @@ private function __construct(private mixed $variable, array $excludedClasses = [
*
* @return self An instance containing variable to dump.
*/
#[Pure]
public static function create(mixed $variable, array $excludedClasses = []): self
{
return new self($variable, $excludedClasses);
Expand All @@ -44,7 +42,8 @@ public static function create(mixed $variable, array $excludedClasses = []): sel
*/
public function asJson(int $depth = 50, bool $format = false): string|bool
{
return $this->asJsonInternal($this->variable, $format, $depth, 0, false, true);
$this->buildObjectsCache($this->variable, $depth);
return $this->asJsonInternal($this->variable, $format, $depth, 0, false);
}

/**
Expand All @@ -58,8 +57,7 @@ public function asJson(int $depth = 50, bool $format = false): string|bool
public function asJsonObjectsMap(int $depth = 50, bool $prettyPrint = false): string|bool
{
$this->buildObjectsCache($this->variable, $depth);

return $this->asJsonInternal($this->objects, $prettyPrint, $depth, 1, true, false);
return $this->asJsonInternal($this->objects, $prettyPrint, $depth, 1, true);
}

private function buildObjectsCache($variable, int $depth, int $level = 0): void
Expand All @@ -74,11 +72,18 @@ private function buildObjectsCache($variable, int $depth, int $level = 0): void
return;
}
$this->objects[$objectDescription] = $variable;
if ($depth <= $level + 1) {
return;
}
$variable = $this->getObjectProperties($variable);
}
if (is_array($variable)) {
$nextLevel = $level + 1;
if ($depth <= $nextLevel) {
return;
}
foreach ($variable as $value) {
$this->buildObjectsCache($value, $depth, $level + 1);
$this->buildObjectsCache($value, $depth, $nextLevel);
}
}
}
Expand All @@ -89,16 +94,12 @@ private function asJsonInternal(
int $depth,
int $objectCollapseLevel,
bool $inlineObject,
bool $buildCache,
): string|bool {
$options = JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE;

if ($format) {
$options |= JSON_PRETTY_PRINT;
}
if ($buildCache) {
$this->buildObjectsCache($variable, $depth);
}

return json_encode(
$this->dumpNestedInternal($variable, $depth, 0, $objectCollapseLevel, $inlineObject),
Expand All @@ -112,23 +113,36 @@ private function getObjectProperties(object $var): array
$var = $var->__debugInfo();
}

return (array)$var;
return (array) $var;
}

private function dumpNestedInternal($var, int $depth, int $level, int $objectCollapseLevel, bool $inlineObject): mixed
{
$output = $var;

private function dumpNestedInternal(
$var,
int $depth,
int $level,
int $objectCollapseLevel,
bool $inlineObject
): mixed {
switch (gettype($var)) {
case 'array':
if ($depth <= $level) {
return 'array [...]';
$valuesCount = count($var);
if ($valuesCount === 0) {
return [];
}
return sprintf('array (%d %s) [...]', $valuesCount, $valuesCount === 1 ? 'item' : 'items');
}

$output = [];
foreach ($var as $key => $value) {
$keyDisplay = str_replace("\0", '::', trim((string)$key));
$output[$keyDisplay] = $this->dumpNestedInternal($value, $depth, $level + 1, $objectCollapseLevel, $inlineObject);
$keyDisplay = str_replace("\0", '::', trim((string) $key));
$output[$keyDisplay] = $this->dumpNestedInternal(
$value,
$depth,
$level + 1,
$objectCollapseLevel,
$inlineObject
);
}

break;
Expand All @@ -140,7 +154,9 @@ private function dumpNestedInternal($var, int $depth, int $level, int $objectCol
}

if ($var instanceof Closure) {
$output = [$objectDescription => $this->exportClosure($var)];
$output = $inlineObject
? $this->exportClosure($var)
: [$objectDescription => $this->exportClosure($var)];
break;
}

Expand All @@ -149,14 +165,18 @@ private function dumpNestedInternal($var, int $depth, int $level, int $objectCol
break;
}

$output = [];
$properties = $this->getObjectProperties($var);
if (empty($properties)) {
$output[$objectDescription] = '{stateless object}';
if ($inlineObject) {
$output = '{stateless object}';
break;
}
$output = [$objectDescription => '{stateless object}'];
break;
}
$output = [];
foreach ($properties as $key => $value) {
$keyDisplay = $this->normalizeProperty((string)$key);
$keyDisplay = $this->normalizeProperty((string) $key);
/**
* @psalm-suppress InvalidArrayOffset
*/
Expand All @@ -176,13 +196,18 @@ private function dumpNestedInternal($var, int $depth, int $level, int $objectCol
case 'resource (closed)':
$output = $this->getResourceDescription($var);
break;
default:
$output = $var;
}

return $output;
}

private function getObjectDescription(object $object): string
{
if (str_contains($object::class, '@anonymous')) {
return 'class@anonymous#' . spl_object_id($object);
}
return $object::class . '#' . spl_object_id($object);
}

Expand Down Expand Up @@ -227,10 +252,6 @@ private function getResourceDescription($resource): array|string
*/
private function exportClosure(Closure $closure): string
{
if (self::$closureExporter === null) {
self::$closureExporter = new ClosureExporter();
}

return self::$closureExporter->export($closure);
return (self::$closureExporter ??= new ClosureExporter())->export($closure);
}
}
8 changes: 6 additions & 2 deletions src/Helper/StreamWrapper/StreamWrapper.php
Expand Up @@ -88,7 +88,9 @@ public function stream_open(string $path, string $mode, int $options, ?string &$
{
$this->filename = realpath($path) ?: $path;

if ((self::STREAM_OPEN_FOR_INCLUDE & $options) === self::STREAM_OPEN_FOR_INCLUDE && function_exists('opcache_invalidate')) {
if ((self::STREAM_OPEN_FOR_INCLUDE & $options) === self::STREAM_OPEN_FOR_INCLUDE && function_exists(
'opcache_invalidate'
)) {
opcache_invalidate($path, false);
}
$this->stream = fopen(
Expand Down Expand Up @@ -182,7 +184,9 @@ public function stream_close(): void
/**
* @psalm-suppress InvalidPropertyAssignmentValue
*/
fclose($this->stream);
if ($this->stream !== null) {
fclose($this->stream);
}
$this->stream = null;
}

Expand Down

0 comments on commit 8b0585a

Please sign in to comment.