diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index a8cd097..b980e19 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -19,6 +19,23 @@ permissions:
contents: read
jobs:
+ quality:
+ name: Mago formatter, linter and analyzer
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ steps:
+ - uses: actions/checkout@v3
+ - uses: shivammathur/setup-php@v2
+ with:
+ php-version: '8.2'
+ coverage: none
+ - name: Install development dependencies
+ run: composer install --prefer-dist --no-progress --no-interaction
+ - name: Run formatter, linter and analyzer without a baseline
+ run: composer check
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
run:
runs-on: ${{ matrix.operating-system }}
diff --git a/MAGO.md b/MAGO.md
new file mode 100644
index 0000000..f336389
--- /dev/null
+++ b/MAGO.md
@@ -0,0 +1,64 @@
+# Mago checks
+
+Install development dependencies with `composer install`, then run:
+
+```sh
+composer check # formatting, linter, analyzer for source and tests
+composer format # apply formatting
+composer lint
+composer analyze
+```
+
+Mago is pinned to **1.47.4**, the newest published version verified for this upgrade.
+Update the pin deliberately and run the full checks before upgrading. Composer installs the
+platform-specific launcher; its first invocation downloads the matching binary.
+CI provides `GITHUB_TOKEN` for that download. Scripts invoke the project-local PHP
+launcher explicitly so an older system-wide binary cannot be used accidentally.
+There is no baseline.
+
+The formatter, linter, and analyzer have been run successfully with 1.47.4 against
+both configurations. On Windows, the Composer launcher needs PHP's ZIP extension
+and a configured trusted CA certificate bundle to download and extract its binary.
+
+`mago.toml` targets PHP 8.1 for library code. `mago-tests.toml` targets PHP 8.2 because
+some fixtures intentionally exercise readonly classes and traits; PHPUnit skips
+the applicable tests on PHP 8.1. Both configurations read dependency declarations
+without checking vendor code. Generated AOP cache and coverage files are excluded.
+
+The linter uses its default correctness, consistency, and maintainability checks.
+Exceptions in configuration are explicit design choices: mandatory strict types
+would change coercion behavior; named arguments and boolean flags are existing API
+choices; `isset` intentionally distinguishes null; aggregate complexity metrics
+are left to review. Analyzer missing-type checks are enabled. CI fails on all
+reported severities. No analyzer issue codes are ignored globally.
+
+The vendor type patch in `tools/mago/patches/CodeTransformerKernel.php` models its
+dependency injection callback as a generic extension point. The default remains
+the original one-argument callback returning a Transformer. AopKernel specializes
+it to its established two-argument callback returning an aspect or transformer.
+This replaces the previous callback suppression without changing runtime code or
+loosening TransformerManager's contract. `composer check-mago-types` checks valid
+callbacks and rejects scalar returns and incorrect default transformer callbacks.
+It runs as part of `composer check`, including in CI. Its deliberately invalid
+fixtures live in `tools/mago/tests` and are checked separately from library code.
+
+Two narrow `@mago-expect` annotations still cover four property-access diagnostics.
+These are explicit analyzer exceptions, not fixes to the analyzer's limitations:
+
+- Two property-access closures operate on a declaration validated through reflection.
+ Mago cannot prove a runtime property name exists on the subject. Reference, scope,
+ uninitialized-property, and unset behavior have runtime regression tests.
+
+These expectations name individual diagnostics at the affected operations. Mago
+reports an unfulfilled expectation if a future release stops producing a diagnostic,
+so stale exceptions fail CI. No baseline, file exclusions for these operations, or
+global analyzer diagnostic suppressions are used.
+
+An extension experiment confirmed that Mago 1.47.4 does not dispatch property type
+providers for these unresolved runtime operations. The experiment was discarded;
+no custom extension or issue filter is installed.
+
+Performance fixture generation now uses a shared service interface and validates
+generated service instantiation through reflection. Its construction work is part
+of the class-loading measurement; compare loading results only against runs using
+the same harness. The timed method-execution loop is unchanged.
diff --git a/README.md b/README.md
index c8196c6..e216841 100644
--- a/README.md
+++ b/README.md
@@ -759,6 +759,8 @@ $firstLog = $logs[0];
## Testing
+
+Development quality checks: see [Mago setup and commands](MAGO.md).
- Run `composer run-script test`
or
- Run `composer run-script test-coverage`
diff --git a/composer.json b/composer.json
index 523c88d..88c443d 100644
--- a/composer.json
+++ b/composer.json
@@ -20,7 +20,13 @@
"scripts": {
"test": "phpunit --testsuite=Tests --display-notices",
"test-performance": "phpunit --testsuite=Performance --display-notices",
- "test-coverage": "phpunit --testsuite=Tests --coverage-html tests/coverage --display-notices"
+ "test-coverage": "phpunit --testsuite=Tests --coverage-html tests/coverage --display-notices",
+ "format": ["@php vendor/bin/mago format", "@php vendor/bin/mago --config mago-tests.toml format"],
+ "format-check": ["@php vendor/bin/mago format --check", "@php vendor/bin/mago --config mago-tests.toml format --check"],
+ "lint": ["@php vendor/bin/mago lint --minimum-fail-level note", "@php vendor/bin/mago --config mago-tests.toml lint --minimum-fail-level note"],
+ "analyze": ["@php vendor/bin/mago analyze --minimum-fail-level note", "@php vendor/bin/mago --config mago-tests.toml analyze --minimum-fail-level note"],
+ "check-mago-types": "@php tools/mago/check.php",
+ "check": ["@format-check", "@lint", "@analyze", "@check-mago-types"]
},
"require": {
"php": ">=8.1",
@@ -30,7 +36,8 @@
"okapi/singleton": "^1.0",
"php-di/php-di": "^7.0"
},
- "require-dev": {
+ "require-dev": {
+ "carthage-software/mago": "1.47.4",
"phpunit/phpunit": "^10.3",
"symfony/var-dumper": "^6.3",
"symfony/console": "^6.3"
diff --git a/mago-tests.toml b/mago-tests.toml
new file mode 100644
index 0000000..f4b7ad0
--- /dev/null
+++ b/mago-tests.toml
@@ -0,0 +1,35 @@
+php-version = "8.2"
+
+[source]
+paths = ["tests"]
+includes = ["src", "vendor"]
+patches = ["tools/mago/patches"]
+excludes = ["tests/cache", "tests/coverage"]
+
+[linter]
+integrations = ["phpunit"]
+
+# Preserve the library's coercion contract and existing public call signatures.
+[linter.rules.strict-types]
+enabled = false
+[linter.rules.literal-named-argument]
+enabled = false
+[linter.rules.no-boolean-flag-parameter]
+enabled = false
+# isset intentionally distinguishes null from a usable value throughout this code.
+[linter.rules.no-isset]
+enabled = false
+# Complexity metrics are review aids, not correctness gates for a weaving engine.
+[linter.rules.halstead]
+enabled = false
+[linter.rules.kan-defect]
+enabled = false
+[linter.rules.cyclomatic-complexity]
+enabled = false
+[linter.rules.too-many-methods]
+enabled = false
+[linter.rules.excessive-parameter-list]
+threshold = 10
+
+[analyzer]
+check-missing-type-hints = true
diff --git a/mago.toml b/mago.toml
new file mode 100644
index 0000000..6744327
--- /dev/null
+++ b/mago.toml
@@ -0,0 +1,35 @@
+php-version = "8.1"
+
+[source]
+paths = ["src", "tools/mago/check.php"]
+includes = ["vendor"]
+patches = ["tools/mago/patches"]
+excludes = ["tests/cache", "tests/coverage"]
+
+[linter]
+integrations = ["phpunit"]
+
+# Preserve the library's coercion contract and existing public call signatures.
+[linter.rules.strict-types]
+enabled = false
+[linter.rules.literal-named-argument]
+enabled = false
+[linter.rules.no-boolean-flag-parameter]
+enabled = false
+# isset intentionally distinguishes null from a usable value throughout this code.
+[linter.rules.no-isset]
+enabled = false
+# Complexity metrics are review aids, not correctness gates for a weaving engine.
+[linter.rules.halstead]
+enabled = false
+[linter.rules.kan-defect]
+enabled = false
+[linter.rules.cyclomatic-complexity]
+enabled = false
+[linter.rules.too-many-methods]
+enabled = false
+[linter.rules.excessive-parameter-list]
+threshold = 10
+
+[analyzer]
+check-missing-type-hints = true
diff --git a/src/Advice/AdviceType.php b/src/Advice/AdviceType.php
index 132693a..e41aa5b 100644
--- a/src/Advice/AdviceType.php
+++ b/src/Advice/AdviceType.php
@@ -12,8 +12,8 @@ enum AdviceType
case Before;
case Around;
case After;
- // TODO: implement
+ // Reserved for future after-returning advice support.
case AfterReturning;
- // TODO: implement
+ // Reserved for future after-throwing advice support.
case AfterThrowing;
}
diff --git a/src/AopKernel.php b/src/AopKernel.php
index 1a79ea5..ff7fe55 100644
--- a/src/AopKernel.php
+++ b/src/AopKernel.php
@@ -1,149 +1,137 @@
-Default: ROOT_DIR/cache/aop
- *
- * @var string|null
- */
- protected ?string $cacheDir = null;
-
- /**
- * The exclude paths. Paths/directories in this array will be excluded
- *
- * @var array
- */
- protected array $excludePaths = [];
-
- // endregion
-
- /**
- * List of aspects to be applied.
- *
- * Class should be annotated with #[{@link Aspect}] attribute.
- *
- * @var class-string[]
- */
- protected array $aspects = [];
-
- /**
- * @inheritDoc
- */
- protected static function registerDependencyInjection(): void
- {
- parent::registerDependencyInjection();
-
- // Overload classes for extending the functionality
- DI::set(CodeTransformerOptions::class, decorate(function () {
- return DI::get(Options::class);
- }));
- DI::set(CodeTransformerCachePaths::class, decorate(function () {
- return DI::get(CachePaths::class);
- }));
- DI::set(
- CodeTransformerClassLoader::class,
- decorate(function (CodeTransformerClassLoader $previous) {
- return DI::make(ClassLoader::class, [
- 'originalClassLoader' => $previous->originalClassLoader,
- ]);
- }),
- );
- DI::set(TransformerProcessor::class, decorate(function () {
- return DI::get(AspectProcessor::class);
- }));
- DI::set(CodeTransformerCacheStateFactory::class, decorate(function () {
- return DI::get(CacheStateFactory::class);
- }));
- DI::set(CodeTransformerCacheStateManager::class, decorate(function () {
- return DI::get(CacheStateManager::class);
- }));
- DI::set(CodeTransformerTransformerManager::class, decorate(function () {
- return DI::get(TransformerManager::class);
- }));
- }
-
- /**
- * @inheritdoc
- */
- protected function preInit(): void
- {
- // Add the aspects
- $this->aspectManager->addAspects($this->aspects);
-
- parent::preInit();
- }
-
- /**
- * Custom dependency injection handler.
- *
- * Pass a closure that takes an aspect/transformer class name as the
- * argument and returns an aspect/transformer instance.
- *
- * @return null|Closure(class-string, ComponentType): object
- */
- protected function dependencyInjectionHandler(): ?Closure
- {
- // Override this method to configure the dependency injection handler
-
- return null;
- }
-
- protected function registerServices(): void
- {
- $this->aspectManager->registerCustomDependencyInjectionHandler(
- $this->dependencyInjectionHandler(),
- );
- $this->aspectManager->register();
-
- parent::registerServices();
- }
-}
+
+ */
+abstract class AopKernel extends CodeTransformerKernel
+{
+ // region DI
+
+ #[Inject]
+ private AspectManager $aspectManager;
+
+ // endregion
+
+ // region Settings
+
+ /**
+ * The cache directory.
+ *
Default: ROOT_DIR/cache/aop
+ *
+ * @var string|null
+ */
+ protected ?string $cacheDir = null;
+
+ /**
+ * The exclude paths. Paths/directories in this array will be excluded
+ *
+ * @var array
+ */
+ protected array $excludePaths = [];
+
+ // endregion
+
+ /**
+ * List of aspects to be applied.
+ *
+ * Class should be annotated with #[{@link Aspect}] attribute.
+ *
+ * @var class-string[]
+ */
+ protected array $aspects = [];
+
+ /**
+ * @inheritDoc
+ */
+ protected static function registerDependencyInjection(): void
+ {
+ parent::registerDependencyInjection();
+
+ // Overload classes for extending the functionality
+ DI::set(CodeTransformerOptions::class, decorate(static fn() => DI::get(Options::class)));
+ DI::set(CodeTransformerCachePaths::class, decorate(static fn() => DI::get(CachePaths::class)));
+ DI::set(CodeTransformerClassLoader::class, decorate(static fn(CodeTransformerClassLoader $previous) => DI::make(ClassLoader::class, [
+ 'originalClassLoader' => $previous->originalClassLoader,
+ ])));
+ DI::set(TransformerProcessor::class, decorate(static fn() => DI::get(AspectProcessor::class)));
+ DI::set(CodeTransformerCacheStateFactory::class, decorate(static fn() => DI::get(CacheStateFactory::class)));
+ DI::set(CodeTransformerCacheStateManager::class, decorate(static fn() => DI::get(CacheStateManager::class)));
+ DI::set(CodeTransformerTransformerManager::class, decorate(static fn() => DI::get(TransformerManager::class)));
+ }
+
+ /**
+ * @inheritdoc
+ */
+ protected function preInit(): void
+ {
+ // Add the aspects
+ $this->aspectManager->addAspects($this->aspects);
+
+ parent::preInit();
+ }
+
+ /**
+ * Custom dependency injection handler.
+ *
+ * Pass a closure that takes an aspect/transformer class name as the
+ * argument and returns an aspect/transformer instance.
+ *
+ * @return null|Closure(class-string, ComponentType): object
+ */
+ protected function dependencyInjectionHandler(): ?Closure
+ {
+ // Override this method to configure the dependency injection handler
+
+ return null;
+ }
+
+ protected function registerServices(): void
+ {
+ $this->aspectManager->registerCustomDependencyInjectionHandler($this->dependencyInjectionHandler());
+ $this->aspectManager->register();
+
+ parent::registerServices();
+ }
+}
diff --git a/src/Attributes/After.php b/src/Attributes/After.php
index 3ec09cd..8089dff 100644
--- a/src/Attributes/After.php
+++ b/src/Attributes/After.php
@@ -1,16 +1,14 @@
-class = $class ? Regex::fromWildcard($class) : null;
diff --git a/src/Core/Attributes/Base/BaseAttribute.php b/src/Core/Attributes/Base/BaseAttribute.php
index bae4f8c..caa676e 100644
--- a/src/Core/Attributes/Base/BaseAttribute.php
+++ b/src/Core/Attributes/Base/BaseAttribute.php
@@ -7,6 +7,4 @@
*
* Base attribute for all AOP attributes.
*/
-abstract class BaseAttribute
-{
-}
+abstract class BaseAttribute {}
diff --git a/src/Core/AutoloadInterceptor/ClassLoader.php b/src/Core/AutoloadInterceptor/ClassLoader.php
index 7b2ccbf..4c42fc5 100644
--- a/src/Core/AutoloadInterceptor/ClassLoader.php
+++ b/src/Core/AutoloadInterceptor/ClassLoader.php
@@ -1,4 +1,5 @@
originalClassLoader->findFile($namespacedClass);
@@ -57,9 +59,15 @@ public function findFile($namespacedClass): false|string
}
$filePath = Path::resolve($filePath);
+ if (!is_string($filePath)) {
+ return false;
+ }
- foreach ($this->options->getExcludePaths() as $path) {
- if (str_starts_with($filePath, Path::resolve($path))) {
+ /** @var string[] $excludePaths */
+ $excludePaths = $this->options->getExcludePaths();
+ foreach ($excludePaths as $path) {
+ $resolvedPath = Path::resolve($path);
+ if (is_string($resolvedPath) && str_starts_with($filePath, $resolvedPath)) {
return $filePath;
}
}
@@ -67,63 +75,30 @@ public function findFile($namespacedClass): false|string
// Query cache state
$cacheState = $this->cacheStateManager->queryCacheState($filePath);
- // When debugging, bypass the caching mechanism
- if ($this->options->isDebug()) {
- // ...
- }
-
- // In production mode, use the cache without checking if it is fresh
- elseif ($this->options->getEnvironment() === Environment::PRODUCTION
- && $cacheState
- ) {
- // Use the cached file if aspects have been applied
- if ($cacheFilePath = $cacheState->getFilePath()) {
- $this->classContainer->addClassContext(
- $filePath,
- $namespacedClass,
- $cacheFilePath,
- );
-
- // For cached files, the debugger will have trouble finding the
- // original file, that's why we rewrite the file path with a PHP
- // stream filter
- /** @see CachedStreamFilter::filter() */
- return $this->filterInjector->rewriteCached($filePath);
- }
-
- // Or return the original file if no aspects have been applied
- return $filePath;
- }
-
- // In development mode, check if the cache is fresh
- elseif ($this->options->getEnvironment() === Environment::DEVELOPMENT
- && $cacheState
- && $cacheState->isFresh()
- ) {
- if ($cacheFilePath = $cacheState->getFilePath()) {
- $this->classContainer->addClassContext(
- $filePath,
- $namespacedClass,
- $cacheFilePath,
- );
-
+ // Production trusts the cache; development checks freshness.
+ $useCache =
+ !$this->options->isDebug()
+ && $cacheState !== null
+ && (
+ $this->options->getEnvironment() === Environment::PRODUCTION
+ || $this->options->getEnvironment() === Environment::DEVELOPMENT
+ && $cacheState->isFresh()
+ );
+ if ($useCache) {
+ $cacheFilePath = $cacheState->getFilePath();
+ if ($cacheFilePath) {
+ $this->classContainer->addClassContext($filePath, $namespacedClass, $cacheFilePath);
+ // Preserve the original source path for debuggers.
return $this->filterInjector->rewriteCached($filePath);
}
-
return $filePath;
}
-
// Match the aspects
- $matchedAspects = $this->aspectMatcher->matchByClassLoaderAndStore(
- $namespacedClass,
- );
+ $matchedAspects = $this->aspectMatcher->matchByClassLoaderAndStore($namespacedClass);
// Match the transformer
- $matchedTransformers = $this->transformerMatcher->matchAndStore(
- $namespacedClass,
- $filePath,
- );
+ $matchedTransformers = $this->transformerMatcher->matchAndStore($namespacedClass, $filePath);
// No aspects or transformers matched
if (!($matchedAspects || $matchedTransformers)) {
@@ -167,7 +142,7 @@ protected function isInternal(string $namespacedClass): bool
'Okapi\Aop\AopKernel',
'Okapi\Aop\Tests\\',
'Nette\PhpGenerator\Factory',
- 'Nette\Utils\Reflection'
+ 'Nette\Utils\Reflection',
],
);
}
diff --git a/src/Core/Cache/CacheState/WovenCacheState.php b/src/Core/Cache/CacheState/WovenCacheState.php
index 744461f..a3ae847 100644
--- a/src/Core/Cache/CacheState/WovenCacheState.php
+++ b/src/Core/Cache/CacheState/WovenCacheState.php
@@ -1,4 +1,5 @@
proxyFilePath)) {
// @codeCoverageIgnoreStart
return false;
+
// @codeCoverageIgnoreEnd
}
@@ -78,17 +82,16 @@ public function isFresh(): bool
if (!file_exists($this->wovenFilePath)) {
// @codeCoverageIgnoreStart
return false;
+
// @codeCoverageIgnoreEnd
}
- $transformerAndAspectFilePaths = array_merge(
- $this->transformerFilePaths,
- $this->aspectFilePaths,
- );
+ $transformerAndAspectFilePaths = array_merge($this->transformerFilePaths, $this->aspectFilePaths);
foreach ($transformerAndAspectFilePaths as $filePath) {
if (!file_exists($filePath)) {
// @codeCoverageIgnoreStart
return false;
+
// @codeCoverageIgnoreEnd
}
}
@@ -107,10 +110,7 @@ public function getFilePath(): ?string
}
// Add the cached advice containers to the aspect matcher
- $this->aspectMatcher->addMatchedAdviceContainers(
- $this->namespacedClass,
- $this->getAdviceContainers(),
- );
+ $this->aspectMatcher->addMatchedAdviceContainers($this->namespacedClass, $this->getAdviceContainers());
return $this->proxyFilePath;
}
@@ -118,12 +118,10 @@ public function getFilePath(): ?string
/**
* Get the advice containers for the given advice names.
*
- * @return array
+ * @return \Okapi\Aop\Core\Container\AdviceContainer[]
*/
private function getAdviceContainers(): array
{
- return $this->aspectManager->getAdviceContainersByAdviceNames(
- $this->adviceNames,
- );
+ return $this->aspectManager->getAdviceContainersByAdviceNames($this->adviceNames);
}
}
diff --git a/src/Core/Cache/CacheStateManager.php b/src/Core/Cache/CacheStateManager.php
index 5ac1cf7..ab434f6 100644
--- a/src/Core/Cache/CacheStateManager.php
+++ b/src/Core/Cache/CacheStateManager.php
@@ -1,4 +1,5 @@
newInstance();
// Check if the aspect are implicit or class/method-level explicit
- $isExplicit = (bool)$aspectRefClass->getAttributes(Attribute::class);
+ $isExplicit = (bool) $aspectRefClass->getAttributes(Attribute::class);
if ($adviceAttributeInstance instanceof MethodAdvice) {
$methodAdviceContainer = DI::make(MethodAdviceContainer::class, [
- 'aspectClassName' => $aspectClassName,
- 'aspectInstance' => $aspectInstance,
- 'aspectRefClass' => $aspectRefClass,
- 'adviceAttribute' => $adviceAttribute,
+ 'aspectClassName' => $aspectClassName,
+ 'aspectInstance' => $aspectInstance,
+ 'aspectRefClass' => $aspectRefClass,
+ 'adviceAttribute' => $adviceAttribute,
'adviceAttributeInstance' => $adviceAttributeInstance,
- 'adviceRefMethod' => $adviceRefMethod,
- 'isExplicit' => $isExplicit,
+ 'adviceRefMethod' => $adviceRefMethod,
+ 'isExplicit' => $isExplicit,
]);
// If the aspect is implicit,
// check if the class and method names are set
if (!$isExplicit) {
if (!$adviceAttributeInstance->class) {
- throw new MissingClassNameException(
- $methodAdviceContainer->getName(),
- );
+ throw new MissingClassNameException($methodAdviceContainer->getName());
}
if (!$adviceAttributeInstance->method) {
- throw new MissingMethodNameException(
- $methodAdviceContainer->getName(),
- );
+ throw new MissingMethodNameException($methodAdviceContainer->getName());
}
}
return $methodAdviceContainer;
}
+ throw new \LogicException('Unsupported advice type.');
}
}
diff --git a/src/Core/Container/AdviceType/MethodAdviceContainer.php b/src/Core/Container/AdviceType/MethodAdviceContainer.php
index c22c1fa..49359d5 100644
--- a/src/Core/Container/AdviceType/MethodAdviceContainer.php
+++ b/src/Core/Container/AdviceType/MethodAdviceContainer.php
@@ -16,7 +16,7 @@
*
* This class is used to store method advice information.
*
- * @property-read MethodAdvice $adviceAttributeInstance
+ * @extends AdviceContainer
*/
class MethodAdviceContainer extends AdviceContainer
{
@@ -39,13 +39,13 @@ class MethodAdviceContainer extends AdviceContainer
* @param bool $isExplicit
*/
public function __construct(
- string $aspectClassName,
- object $aspectInstance,
- BaseReflectionClass $aspectRefClass,
- BaseReflectionAttribute $adviceAttribute,
- MethodAdvice $adviceAttributeInstance,
+ string $aspectClassName,
+ object $aspectInstance,
+ BaseReflectionClass $aspectRefClass,
+ BaseReflectionAttribute $adviceAttribute,
+ MethodAdvice $adviceAttributeInstance,
public readonly BaseReflectionMethod $adviceRefMethod,
- private readonly bool $isExplicit,
+ private readonly bool $isExplicit,
) {
parent::__construct(
$aspectClassName,
@@ -63,9 +63,8 @@ public function __construct(
*
* @return void
*/
- public function addMatchedMethod(
- BetterReflectionMethod $matchedRefMethod,
- ): void {
+ public function addMatchedMethod(BetterReflectionMethod $matchedRefMethod): void
+ {
$this->matchedMethods[] = DI::make(MatchedMethod::class, [
'matchedRefMethod' => $matchedRefMethod,
]);
diff --git a/src/Core/Container/AspectManager.php b/src/Core/Container/AspectManager.php
index 43eaf67..c7d7137 100644
--- a/src/Core/Container/AspectManager.php
+++ b/src/Core/Container/AspectManager.php
@@ -1,11 +1,10 @@
aspects = array_merge(
- $this->aspects,
- $aspectClasses,
- );
+ $this->aspects = array_merge($this->aspects, $aspectClasses);
}
// endregion
@@ -84,9 +79,8 @@ public function addAspects(array $aspectClasses): void
/**
* @param null|(Closure(class-string, ComponentType): object) $dependencyInjectionHandler
*/
- public function registerCustomDependencyInjectionHandler(
- ?Closure $dependencyInjectionHandler
- ): void {
+ public function registerCustomDependencyInjectionHandler(?Closure $dependencyInjectionHandler): void
+ {
$this->dependencyInjectionHandler = $dependencyInjectionHandler;
}
@@ -130,46 +124,36 @@ public function loadAspect(mixed $aspectClassName): void
if (array_key_exists($aspectClassName, $this->aspectAdviceContainers)) {
// @codeCoverageIgnoreStart
return;
+
// @codeCoverageIgnoreEnd
}
// Validate the aspect
if (gettype($aspectClassName) !== 'string') {
- throw new InvalidAspectClassNameException;
+ throw new InvalidAspectClassNameException();
}
- // Instantiate the aspect
- if ($this->dependencyInjectionHandler) {
- $aspectInstance = ($this->dependencyInjectionHandler)(
- $aspectClassName,
- ComponentType::ASPECT,
- );
- } else {
- try {
- $aspectInstance = DI::make($aspectClassName);
- } catch (Error|Exception) {
- throw new AspectNotFoundException($aspectClassName);
- }
- }
+ // Instantiate the aspect.
+ $aspectInstance = $this->instantiateAspect($aspectClassName);
// Create a reflection of the aspect
$aspectRefClass = new BaseReflectionClass($aspectInstance);
// Validate the aspect attribute
- $attributes = $aspectRefClass->getAttributes(
- Aspect::class,
- BaseReflectionAttribute::IS_INSTANCEOF,
- );
+ $attributes = $aspectRefClass->getAttributes(Aspect::class, BaseReflectionAttribute::IS_INSTANCEOF);
if (!$attributes) {
throw new MissingAspectAttributeException($aspectClassName);
}
// Iterate over the aspect methods and properties
- $methods = $aspectRefClass->getMethods();
+ $methods = $aspectRefClass->getMethods();
$properties = $aspectRefClass->getProperties();
/** @var (BaseReflectionMethod|BaseReflectionProperty)[] $adviceRefMembers */
$adviceRefMembers = array_merge($methods, $properties);
foreach ($adviceRefMembers as $adviceRefMember) {
+ if (!$adviceRefMember instanceof BaseReflectionMethod) {
+ continue;
+ }
// Get the advices
$adviceAttributes = $adviceRefMember->getAttributes(
BaseAdvice::class,
@@ -186,12 +170,25 @@ public function loadAspect(mixed $aspectClassName): void
$adviceRefMember,
);
- $this->aspectAdviceContainers[$aspectClassName][] = $adviceContainer;
+ $this->aspectAdviceContainers[$aspectClassName][] = $adviceContainer;
$this->adviceContainers[$adviceContainer->getName()][] = $adviceContainer;
}
}
}
+ /** @param class-string $aspectClassName */
+ private function instantiateAspect(string $aspectClassName): object
+ {
+ if ($this->dependencyInjectionHandler !== null) {
+ return ($this->dependencyInjectionHandler)($aspectClassName, ComponentType::ASPECT);
+ }
+ try {
+ return DI::make($aspectClassName);
+ } catch (Throwable) {
+ throw new AspectNotFoundException($aspectClassName);
+ }
+ }
+
/**
* Get the aspects.
*
@@ -237,13 +234,10 @@ public function getAspectAdviceNames(): array
*/
public function getAdviceContainersByAdviceNames(array $adviceNames): array
{
- return array_reduce(
- $adviceNames,
- fn (array $carry, string $adviceName) => array_merge(
- $carry,
- $this->adviceContainers[$adviceName] ?? [],
- ),
- [],
- );
+ $containers = [];
+ foreach ($adviceNames as $adviceName) {
+ $containers = array_merge($containers, $this->adviceContainers[$adviceName] ?? []);
+ }
+ return $containers;
}
}
diff --git a/src/Core/Container/JoinPoint/MethodJoinPointContainer.php b/src/Core/Container/JoinPoint/MethodJoinPointContainer.php
index 9724363..65e5b16 100644
--- a/src/Core/Container/JoinPoint/MethodJoinPointContainer.php
+++ b/src/Core/Container/JoinPoint/MethodJoinPointContainer.php
@@ -5,7 +5,7 @@
use Okapi\Aop\Core\Intercept\Interceptor;
use Okapi\CodeTransformer\Core\DI;
-// TODO: docs
+/** Converts method join points into an interceptor callback. */
class MethodJoinPointContainer
{
private Interceptor $interceptor;
@@ -18,18 +18,19 @@ class MethodJoinPointContainer
* @param string[] $joinPoints
*/
public function __construct(
- string $className,
+ string $className,
public readonly string $methodName,
- array $joinPoints,
+ array $joinPoints,
) {
$this->interceptor = DI::make(Interceptor::class, [
- 'className' => $className,
+ 'className' => $className,
'methodName' => $methodName,
'joinPoints' => $joinPoints,
]);
}
- // TODO: docs
+ /** Converts method join points into an interceptor callback. */
+ /** @return array{Interceptor, string} */
public function getValue(): array
{
return [
diff --git a/src/Core/Container/JoinPointContainer.php b/src/Core/Container/JoinPointContainer.php
index 33b8e17..1cb1f1a 100644
--- a/src/Core/Container/JoinPointContainer.php
+++ b/src/Core/Container/JoinPointContainer.php
@@ -23,24 +23,21 @@ class JoinPointContainer
* JoinPointContainer constructor.
*
* @param class-string $className
- * @param array<'method', array> $joinPointPropertyValue
+ * @param array> $joinPointPropertyValue
*/
- public function __construct(
- string $className,
- array $joinPointPropertyValue,
- ) {
+ public function __construct(string $className, array $joinPointPropertyValue)
+ {
foreach ($joinPointPropertyValue as $joinPointType => $joinPointValue) {
- if ($joinPointType === JoinPoint::TYPE_METHOD) {
- foreach ($joinPointValue as $methodName => $joinPoints) {
- $this->methodJoinPointContainers[] = DI::make(
- MethodJoinPointContainer::class,
- [
- 'className' => $className,
- 'methodName' => $methodName,
- 'joinPoints' => $joinPoints,
- ],
- );
- }
+ if ($joinPointType !== JoinPoint::TYPE_METHOD) {
+ continue;
+ }
+
+ foreach ($joinPointValue as $methodName => $joinPoints) {
+ $this->methodJoinPointContainers[] = DI::make(MethodJoinPointContainer::class, [
+ 'className' => $className,
+ 'methodName' => $methodName,
+ 'joinPoints' => $joinPoints,
+ ]);
}
}
}
@@ -48,14 +45,14 @@ public function __construct(
/**
* Get the value of the join point container.
*
- * @return array<'method', array>
+ * @return array<'method', array>
*/
public function getValue(): array
{
$value = [];
foreach ($this->methodJoinPointContainers as $methodJoinPointContainer) {
- $methodName = $methodJoinPointContainer->methodName;
+ $methodName = $methodJoinPointContainer->methodName;
$joinPointValue = $methodJoinPointContainer->getValue();
$value[JoinPoint::TYPE_METHOD][$methodName] = $joinPointValue;
diff --git a/src/Core/Container/TransformerManager.php b/src/Core/Container/TransformerManager.php
index 7091685..359ae01 100644
--- a/src/Core/Container/TransformerManager.php
+++ b/src/Core/Container/TransformerManager.php
@@ -7,6 +7,7 @@
class TransformerManager extends CodeTransformerTransformerManager
{
+ /** @return list */
protected function getAdditionalDependencyInjectionParams(): array
{
return [ComponentType::TRANSFORMER];
diff --git a/src/Core/Exception/Advice/MissingClassNameException.php b/src/Core/Exception/Advice/MissingClassNameException.php
index b82d7f9..d7b2f59 100644
--- a/src/Core/Exception/Advice/MissingClassNameException.php
+++ b/src/Core/Exception/Advice/MissingClassNameException.php
@@ -16,9 +16,6 @@ class MissingClassNameException extends AdviceException
*/
public function __construct(string $adviceName)
{
- parent::__construct(
- "Advice \"$adviceName\" is being used explicitly and is " .
- "missing the class name.",
- );
+ parent::__construct("Advice \"{$adviceName}\" is being used explicitly and is " . 'missing the class name.');
}
}
diff --git a/src/Core/Exception/Advice/MissingMethodNameException.php b/src/Core/Exception/Advice/MissingMethodNameException.php
index 63c4443..325e9f1 100644
--- a/src/Core/Exception/Advice/MissingMethodNameException.php
+++ b/src/Core/Exception/Advice/MissingMethodNameException.php
@@ -17,10 +17,10 @@ class MissingMethodNameException extends AdviceException
public function __construct(string $adviceName)
{
parent::__construct(
- "Advice \"$adviceName\" is being used explicitly and is missing the method name. \n" .
- "Implicit Aspects: Aspects are applied without any modification to the target classes. \n" .
- "Explicit Aspects: Aspects are applied to the target class or method directly " .
- "by using the aspect as an attribute.",
+ "Advice \"{$adviceName}\" is being used explicitly and is missing the method name. \n"
+ . "Implicit Aspects: Aspects are applied without any modification to the target classes. \n"
+ . 'Explicit Aspects: Aspects are applied to the target class or method directly '
+ . 'by using the aspect as an attribute.',
);
}
}
diff --git a/src/Core/Exception/AdviceException.php b/src/Core/Exception/AdviceException.php
index 9688439..c1b21c9 100644
--- a/src/Core/Exception/AdviceException.php
+++ b/src/Core/Exception/AdviceException.php
@@ -7,6 +7,4 @@
*
* This exception is thrown when an advice is not valid.
*/
-abstract class AdviceException extends AopException
-{
-}
+abstract class AdviceException extends AopException {}
diff --git a/src/Core/Exception/AopException.php b/src/Core/Exception/AopException.php
index 9880b1b..fe31ad8 100644
--- a/src/Core/Exception/AopException.php
+++ b/src/Core/Exception/AopException.php
@@ -9,6 +9,4 @@
*
* Base exception for all AOP exceptions.
*/
-abstract class AopException extends RuntimeException
-{
-}
+abstract class AopException extends RuntimeException {}
diff --git a/src/Core/Exception/Aspect/AspectNotFoundException.php b/src/Core/Exception/Aspect/AspectNotFoundException.php
index c29ecdd..ddc3666 100644
--- a/src/Core/Exception/Aspect/AspectNotFoundException.php
+++ b/src/Core/Exception/Aspect/AspectNotFoundException.php
@@ -18,8 +18,6 @@ class AspectNotFoundException extends AspectException
*/
public function __construct(string $aspectName)
{
- parent::__construct(
- 'Aspect "' . $aspectName . '" not found.',
- );
+ parent::__construct('Aspect "' . $aspectName . '" not found.');
}
}
diff --git a/src/Core/Exception/Aspect/InvalidAspectClassNameException.php b/src/Core/Exception/Aspect/InvalidAspectClassNameException.php
index a6a8d22..c491ccd 100644
--- a/src/Core/Exception/Aspect/InvalidAspectClassNameException.php
+++ b/src/Core/Exception/Aspect/InvalidAspectClassNameException.php
@@ -16,8 +16,6 @@ class InvalidAspectClassNameException extends AspectException
*/
public function __construct()
{
- parent::__construct(
- 'Aspect class name in Kernel must be a string.',
- );
+ parent::__construct('Aspect class name in Kernel must be a string.');
}
}
diff --git a/src/Core/Exception/Aspect/MissingAspectAttributeException.php b/src/Core/Exception/Aspect/MissingAspectAttributeException.php
index 0924dfe..f3beaae 100644
--- a/src/Core/Exception/Aspect/MissingAspectAttributeException.php
+++ b/src/Core/Exception/Aspect/MissingAspectAttributeException.php
@@ -20,8 +20,6 @@ class MissingAspectAttributeException extends AspectException
*/
public function __construct(string $aspectName)
{
- parent::__construct(
- 'Aspect "' . $aspectName . '" is missing the #[Aspect] attribute.'
- );
+ parent::__construct('Aspect "' . $aspectName . '" is missing the #[Aspect] attribute.');
}
}
diff --git a/src/Core/Exception/AspectException.php b/src/Core/Exception/AspectException.php
index 7b23f93..e3b60c3 100644
--- a/src/Core/Exception/AspectException.php
+++ b/src/Core/Exception/AspectException.php
@@ -7,6 +7,4 @@
*
* This exception is thrown when an aspect is not valid.
*/
-abstract class AspectException extends AopException
-{
-}
+abstract class AspectException extends AopException {}
diff --git a/src/Core/Factory/InvocationFactory.php b/src/Core/Factory/InvocationFactory.php
index d667768..55f1b28 100644
--- a/src/Core/Factory/InvocationFactory.php
+++ b/src/Core/Factory/InvocationFactory.php
@@ -2,7 +2,9 @@
namespace Okapi\Aop\Core\Factory;
-use Okapi\Aop\Attributes\{After, Around, Before};
+use Okapi\Aop\Attributes\After;
+use Okapi\Aop\Attributes\Around;
+use Okapi\Aop\Attributes\Before;
use Okapi\Aop\Core\Container\AdviceType\MethodAdviceContainer;
use Okapi\Aop\Invocation\AfterMethodInvocation;
use Okapi\Aop\Invocation\AroundMethodInvocation;
@@ -33,42 +35,43 @@ class InvocationFactory
*/
public function getInvocation(
MethodAdviceContainer $adviceContainer,
- ?object $subject,
- string $className,
- string $methodName,
- mixed $result,
- array &$arguments,
+ ?object $subject,
+ string $className,
+ string $methodName,
+ mixed $result,
+ array &$arguments,
): MethodInvocation {
switch (true) {
// Before
case $adviceContainer->adviceAttributeInstance instanceof Before:
return DI::make(BeforeMethodInvocation::class, [
- 'subject' => $subject,
- 'className' => $className,
+ 'subject' => $subject,
+ 'className' => $className,
'methodName' => $methodName,
- 'result' => $result,
- 'arguments' => &$arguments,
+ 'result' => $result,
+ 'arguments' => &$arguments,
]);
// Around
case $adviceContainer->adviceAttributeInstance instanceof Around:
return DI::make(AroundMethodInvocation::class, [
- 'subject' => $subject,
- 'className' => $className,
+ 'subject' => $subject,
+ 'className' => $className,
'methodName' => $methodName,
- 'result' => $result,
- 'arguments' => &$arguments,
+ 'result' => $result,
+ 'arguments' => &$arguments,
]);
// After
case $adviceContainer->adviceAttributeInstance instanceof After:
return DI::make(AfterMethodInvocation::class, [
- 'subject' => $subject,
- 'className' => $className,
+ 'subject' => $subject,
+ 'className' => $className,
'methodName' => $methodName,
- 'result' => $result,
- 'arguments' => &$arguments,
+ 'result' => $result,
+ 'arguments' => &$arguments,
]);
}
+ throw new \LogicException('Unsupported advice type.');
}
}
diff --git a/src/Core/Intercept/Interceptor.php b/src/Core/Intercept/Interceptor.php
index aebf1ee..9512c55 100644
--- a/src/Core/Intercept/Interceptor.php
+++ b/src/Core/Intercept/Interceptor.php
@@ -1,4 +1,5 @@
$className,
+ 'className' => $className,
'joinPoints' => $joinPoints,
]);
- $joinPointHandler->handle(
- $this->beforeInterceptors,
- $this->aroundInterceptors,
- $this->afterInterceptors,
- );
+ $joinPointHandler->handle($this->beforeInterceptors, $this->aroundInterceptors, $this->afterInterceptors);
$this->targetRefClass = new BaseReflectionClass($className);
}
@@ -87,7 +84,7 @@ public function __construct(
public function intercept(?object $subject, array $arguments = []): mixed
{
foreach ($this->beforeInterceptors as $beforeInterceptor) {
- $aspectInstance = $beforeInterceptor->aspectInstance;
+ $aspectInstance = $beforeInterceptor->aspectInstance;
$adviceRefMethod = $beforeInterceptor->adviceRefMethod;
$invocation = $this->invocationFactory->getInvocation(
@@ -104,36 +101,41 @@ className: $this->className,
$arguments = $invocation->getArguments();
}
+ $aroundAdviceChain = null;
if ($this->aroundInterceptors) {
$aroundAdviceChain = DI::make(AdviceChain::class, [
- 'interceptors' => $this->aroundInterceptors,
- 'subject' => $subject,
- 'className' => $this->className,
- 'methodName' => $this->methodName,
- 'arguments' => &$arguments,
+ 'interceptors' => $this->aroundInterceptors,
+ 'subject' => $subject,
+ 'className' => $this->className,
+ 'methodName' => $this->methodName,
+ 'arguments' => &$arguments,
'originalMethod' => function () use ($subject, &$arguments) {
+ /** @var array $arguments */
return $this->callParentMethod($subject, $arguments);
},
]);
-
- $result = $aroundAdviceChain->proceed();
- } else {
- $result = $this->callParentMethod($subject, $arguments);
}
+ /** @var array $arguments */
+ /** @var mixed $result */
+ $result = $aroundAdviceChain !== null
+ ? $aroundAdviceChain->proceed()
+ : $this->callParentMethod($subject, $arguments);
if ($this->afterInterceptors) {
$afterAdviceChain = DI::make(AdviceChain::class, [
- 'interceptors' => $this->afterInterceptors,
- 'subject' => $subject,
- 'className' => $this->className,
- 'methodName' => $this->methodName,
- 'arguments' => &$arguments,
- 'originalMethod' => function () use ($subject, &$arguments) {
+ 'interceptors' => $this->afterInterceptors,
+ 'subject' => $subject,
+ 'className' => $this->className,
+ 'methodName' => $this->methodName,
+ 'arguments' => &$arguments,
+ 'originalMethod' => function () use ($subject, &$arguments) {
+ /** @var array $arguments */
return $this->callParentMethod($subject, $arguments);
},
'resultFromOriginalMethod' => $result,
]);
+ /** @var mixed $result */
$result = $afterAdviceChain->proceed();
}
@@ -155,6 +157,9 @@ private function callParentMethod(?object $subject, array $args): mixed
{
$parentClass = $this->targetRefClass->getParentClass();
+ if ($parentClass === false) {
+ throw new \LogicException('An intercepted class must have a woven parent.');
+ }
$parentMethod = $parentClass->getMethod($this->methodName);
$this->unwrapVariadicParameters($parentMethod, $args);
@@ -179,7 +184,12 @@ private function unwrapVariadicParameters(ReflectionMethod $method, array &$args
if ($lastParameter && $lastParameter->isVariadic()) {
$lastParameterName = $lastParameter->getName();
- $variadicParameterValues = array_values($args[$lastParameterName]);
+ /** @var mixed $variadicArguments */
+ $variadicArguments = $args[$lastParameterName];
+ if (!is_array($variadicArguments)) {
+ throw new \LogicException('Variadic arguments must be an array.');
+ }
+ $variadicParameterValues = array_values($variadicArguments);
unset($args[$lastParameterName]);
diff --git a/src/Core/Invocation/AdviceChain.php b/src/Core/Invocation/AdviceChain.php
index 69f0026..f9815df 100644
--- a/src/Core/Invocation/AdviceChain.php
+++ b/src/Core/Invocation/AdviceChain.php
@@ -1,7 +1,9 @@
originalMethod = $originalMethod === null ? null : Closure::fromCallable($originalMethod);
if ($this->interceptors[0]->adviceAttributeInstance instanceof After) {
$this->setResult($this->resultFromOriginalMethod);
}
@@ -81,7 +86,7 @@ public function proceed(bool $allowRepeatedCalls = false): mixed
$interceptor = $this->interceptors[$this->currentInterceptorIndex];
$this->currentInterceptorIndex++;
- $aspectInstance = $interceptor->aspectInstance;
+ $aspectInstance = $interceptor->aspectInstance;
$adviceRefMethod = $interceptor->adviceRefMethod;
// Get invocation
@@ -99,6 +104,7 @@ className: $this->className,
$invocation->setAdviceChain($this);
// Call the advice method
+ /** @var mixed $result */
$result = $adviceRefMethod->invoke($aspectInstance, $invocation);
// Check if the advice method will return a value
@@ -124,13 +130,14 @@ className: $this->className,
// 3. Return the result from the original method
if ($this->resultHasBeenSet && !$allowRepeatedCalls) {
return $this->result;
- } elseif ($this->originalMethod) {
+ }
+ if ($this->originalMethod) {
+ /** @var mixed $result */
$result = ($this->originalMethod)(...array_values($this->arguments));
$this->setResult($result);
return $result;
- } else {
- return $this->resultFromOriginalMethod;
}
+ return $this->resultFromOriginalMethod;
}
/**
diff --git a/src/Core/JoinPoint/JoinPointHandler.php b/src/Core/JoinPoint/JoinPointHandler.php
index 1e02a51..5c25fd2 100644
--- a/src/Core/JoinPoint/JoinPointHandler.php
+++ b/src/Core/JoinPoint/JoinPointHandler.php
@@ -1,4 +1,5 @@
joinPoints as $joinPoint) {
$adviceContainers = $this->aspectMatcher->getMatchedAdviceContainersByJoinPoint(
$this->className,
diff --git a/src/Core/JoinPoint/JoinPointInjector.php b/src/Core/JoinPoint/JoinPointInjector.php
index 032f490..e3400ba 100644
--- a/src/Core/JoinPoint/JoinPointInjector.php
+++ b/src/Core/JoinPoint/JoinPointInjector.php
@@ -30,20 +30,16 @@ public function injectJoinPoints(string $className): void
$refClass = new BaseReflectionClass($className);
// Read the join points
- $staticPropertyValue = $refClass->getStaticPropertyValue(
- JoinPoint::JOIN_POINTS_PARAMETER_NAME,
- );
+ /** @var array<'method', array> $staticPropertyValue */
+ $staticPropertyValue = $refClass->getStaticPropertyValue(JoinPoint::JOIN_POINTS_PARAMETER_NAME, null);
// Convert to JoinPointContainer
$joinPointContainer = DI::make(JoinPointContainer::class, [
- 'className' => $className,
+ 'className' => $className,
'joinPointPropertyValue' => $staticPropertyValue,
]);
// Set the join points
- $refClass->setStaticPropertyValue(
- JoinPoint::JOIN_POINTS_PARAMETER_NAME,
- $joinPointContainer->getValue(),
- );
+ $refClass->setStaticPropertyValue(JoinPoint::JOIN_POINTS_PARAMETER_NAME, $joinPointContainer->getValue());
}
}
diff --git a/src/Core/Matcher/AdviceMatcher.php b/src/Core/Matcher/AdviceMatcher.php
index d2d1db4..ffd243a 100644
--- a/src/Core/Matcher/AdviceMatcher.php
+++ b/src/Core/Matcher/AdviceMatcher.php
@@ -1,4 +1,5 @@
methodMatcher->match(
- $adviceContainer,
- $refClass,
- );
+ return $this->methodMatcher->match($adviceContainer, $refClass);
}
+ return null;
}
}
diff --git a/src/Core/Matcher/AdviceMatcher/MethodMatcher.php b/src/Core/Matcher/AdviceMatcher/MethodMatcher.php
index bcc8827..8c1be55 100644
--- a/src/Core/Matcher/AdviceMatcher/MethodMatcher.php
+++ b/src/Core/Matcher/AdviceMatcher/MethodMatcher.php
@@ -35,29 +35,15 @@ public function match(
// Basically the same as $refClassToMatch->getImmediateMethods(),
// but this also includes the methods from traits, because traits
// cannot be woven
- $declaringClass = $refMethodToMatch->getDeclaringClass();
+ $declaringClass = $refMethodToMatch->getDeclaringClass();
$declaringClassName = $declaringClass->getName();
- if (!$declaringClass->isTrait()
- && $declaringClassName !== $refClassToMatchName
- ) {
+ if (!$declaringClass->isTrait() && $declaringClassName !== $refClassToMatchName) {
continue;
}
- // Match explicit aspects
- if ($methodAdviceContainer->isExplicit()) {
- $newMethodAdviceContainer = $this->matchExplicit(
- $methodAdviceContainer,
- $refMethodToMatch,
- $newMethodAdviceContainer,
- );
- } else {
- // Match implicit aspects
- $newMethodAdviceContainer = $this->matchImplicit(
- $methodAdviceContainer,
- $refMethodToMatch,
- $newMethodAdviceContainer,
- );
- }
+ $newMethodAdviceContainer = $methodAdviceContainer->isExplicit()
+ ? $this->matchExplicit($methodAdviceContainer, $refMethodToMatch, $newMethodAdviceContainer)
+ : $this->matchImplicit($methodAdviceContainer, $refMethodToMatch, $newMethodAdviceContainer);
}
return $newMethodAdviceContainer;
@@ -79,46 +65,35 @@ protected function matchExplicit(
): ?MethodAdviceContainer {
$aspectClassName = $methodAdviceContainer->aspectClassName;
- // Match class attributes
+ // Match class attributes.
$declaringClass = $refMethodToMatch->getDeclaringClass();
foreach ($declaringClass->getAttributes() as $refAttribute) {
- if ($refAttribute->getName() === $aspectClassName) {
- $adviceAttributeInstance = $methodAdviceContainer->adviceAttributeInstance;
-
- // Advices without method are applied to all methods
- if ($adviceAttributeInstance->method === null) {
- $newMethodAdviceContainer = $this->createNewMethodAdviceContainer(
- $methodAdviceContainer,
- $newMethodAdviceContainer,
- );
-
- $newMethodAdviceContainer->addMatchedMethod($refMethodToMatch);
- } else {
- $methodNameToMatch = $refMethodToMatch->getName();
- $methodRegex = $adviceAttributeInstance->method;
-
- if ($methodRegex->matches($methodNameToMatch)) {
- $newMethodAdviceContainer = $this->createNewMethodAdviceContainer(
- $methodAdviceContainer,
- $newMethodAdviceContainer,
- );
-
- $newMethodAdviceContainer->addMatchedMethod($refMethodToMatch);
- }
- }
+ if ($refAttribute->getName() !== $aspectClassName) {
+ continue;
+ }
+
+ $methodRegex = $methodAdviceContainer->adviceAttributeInstance->method;
+ // Advices without a method pattern apply to all methods.
+ if ($methodRegex !== null && !$methodRegex->matches($refMethodToMatch->getName())) {
+ continue;
}
+ $newMethodAdviceContainer = $this->createNewMethodAdviceContainer(
+ $methodAdviceContainer,
+ $newMethodAdviceContainer,
+ );
+ $newMethodAdviceContainer->addMatchedMethod($refMethodToMatch);
}
- // Match method attributes
+ // Match method attributes.
foreach ($refMethodToMatch->getAttributes() as $refAttribute) {
- if ($refAttribute->getName() === $aspectClassName) {
- $newMethodAdviceContainer = $this->createNewMethodAdviceContainer(
- $methodAdviceContainer,
- $newMethodAdviceContainer,
- );
-
- $newMethodAdviceContainer->addMatchedMethod($refMethodToMatch);
+ if ($refAttribute->getName() !== $aspectClassName) {
+ continue;
}
+ $newMethodAdviceContainer = $this->createNewMethodAdviceContainer(
+ $methodAdviceContainer,
+ $newMethodAdviceContainer,
+ );
+ $newMethodAdviceContainer->addMatchedMethod($refMethodToMatch);
}
return $newMethodAdviceContainer;
@@ -141,20 +116,22 @@ protected function matchImplicit(
$methodNameToMatch = $refMethodToMatch->getName();
// Only public methods
- if ($methodAdviceContainer->adviceAttributeInstance->onlyPublicMethods
+ if (
+ $methodAdviceContainer->adviceAttributeInstance->onlyPublicMethods
&& !($refMethodToMatch->getModifiers() & BaseReflectionMethod::IS_PUBLIC)
) {
return $newMethodAdviceContainer;
}
// Intercept trait methods
- if (!$methodAdviceContainer->adviceAttributeInstance->interceptTraitMethods
+ if (
+ !$methodAdviceContainer->adviceAttributeInstance->interceptTraitMethods
&& $refMethodToMatch->getDeclaringClass()->isTrait()
) {
return $newMethodAdviceContainer;
}
- if ($methodAdviceContainer->adviceAttributeInstance->method->matches($methodNameToMatch)) {
+ if ($methodAdviceContainer->adviceAttributeInstance->method?->matches($methodNameToMatch)) {
$newMethodAdviceContainer = $this->createNewMethodAdviceContainer(
$methodAdviceContainer,
$newMethodAdviceContainer,
diff --git a/src/Core/Matcher/AspectMatcher.php b/src/Core/Matcher/AspectMatcher.php
index 77736fa..031ca4c 100644
--- a/src/Core/Matcher/AspectMatcher.php
+++ b/src/Core/Matcher/AspectMatcher.php
@@ -1,4 +1,5 @@
isInterface() || $refClass->isTrait()) {
- $this->cacheEmptyResult(
- $namespacedClass,
- $refClass->getFileName(),
- );
+ $this->cacheEmptyResult($namespacedClass, $refClass->getFileName());
return false;
}
@@ -107,16 +105,13 @@ public function matchByClassLoaderAndStore(string $namespacedClass): bool
$refClass,
$adviceContainer,
$this->explicitClassAspectTargets[$namespacedClass] ?? false,
- (bool)($this->explicitMethodAspectTargets[$namespacedClass] ?? false),
+ (bool) ($this->explicitMethodAspectTargets[$namespacedClass] ?? false),
)) {
continue;
}
// Match advices
- $matchedAdviceContainer = $this->adviceMatcher->match(
- $adviceContainer,
- $refClass,
- );
+ $matchedAdviceContainer = $this->adviceMatcher->match($adviceContainer, $refClass);
if ($matchedAdviceContainer) {
$matchedAdviceContainers[] = $matchedAdviceContainer;
}
@@ -128,13 +123,10 @@ public function matchByClassLoaderAndStore(string $namespacedClass): bool
// Cache the result
if (!$matchedAdviceContainers) {
- $this->cacheEmptyResult(
- $namespacedClass,
- $refClass->getFileName(),
- );
+ $this->cacheEmptyResult($namespacedClass, $refClass->getFileName());
}
- return (bool)$matchedAdviceContainers;
+ return (bool) $matchedAdviceContainers;
}
/**
@@ -147,9 +139,8 @@ public function matchByClassLoaderAndStore(string $namespacedClass): bool
*
* @return void
*/
- protected function checkForExplicitAdvices(
- BetterReflectionClass $refClass,
- ): void {
+ protected function checkForExplicitAdvices(BetterReflectionClass $refClass): void
+ {
$this->checkForExplicitClassAspects($refClass);
$this->checkForExplicitMethodAspects($refClass);
}
@@ -161,14 +152,15 @@ protected function checkForExplicitAdvices(
*
* @return void
*/
- protected function checkForExplicitClassAspects(
- BetterReflectionClass $refClass,
- ): void {
+ protected function checkForExplicitClassAspects(BetterReflectionClass $refClass): void
+ {
foreach ($refClass->getAttributes() as $refAttribute) {
- if ($this->hasAspectAndAttribute($refAttribute)) {
- $this->aspectManager->loadAspect($refAttribute->getClass()->getName());
- $this->explicitClassAspectTargets[$refClass->getName()] = true;
+ if (!$this->hasAspectAndAttribute($refAttribute)) {
+ continue;
}
+
+ $this->aspectManager->loadAspect($refAttribute->getClass()->getName());
+ $this->explicitClassAspectTargets[$refClass->getName()] = true;
}
}
@@ -179,15 +171,16 @@ protected function checkForExplicitClassAspects(
*
* @return void
*/
- protected function checkForExplicitMethodAspects(
- BetterReflectionClass $refClass,
- ): void {
+ protected function checkForExplicitMethodAspects(BetterReflectionClass $refClass): void
+ {
foreach ($refClass->getImmediateMethods() as $refMethod) {
foreach ($refMethod->getAttributes() as $refAttribute) {
- if ($this->hasAspectAndAttribute($refAttribute)) {
- $this->aspectManager->loadAspect($refAttribute->getClass()->getName());
- $this->explicitMethodAspectTargets[$refClass->getName()][] = $refMethod->getName();
+ if (!$this->hasAspectAndAttribute($refAttribute)) {
+ continue;
}
+
+ $this->aspectManager->loadAspect($refAttribute->getClass()->getName());
+ $this->explicitMethodAspectTargets[$refClass->getName()][] = $refMethod->getName();
}
}
}
@@ -199,9 +192,8 @@ protected function checkForExplicitMethodAspects(
*
* @return bool
*/
- protected function hasAspectAndAttribute(
- BetterReflectionAttribute $refAttribute,
- ): bool {
+ protected function hasAspectAndAttribute(BetterReflectionAttribute $refAttribute): bool
+ {
try {
$attributeClass = $refAttribute->getClass();
} catch (IdentifierNotFound) {
@@ -211,12 +203,8 @@ protected function hasAspectAndAttribute(
return false;
}
- $hasAspectAttribute = (bool)$attributeClass->getAttributesByInstance(
- Aspect::class,
- );
- $hasAttributeAttribute = (bool)$attributeClass->getAttributesByInstance(
- Attribute::class,
- );
+ $hasAspectAttribute = (bool) $attributeClass->getAttributesByInstance(Aspect::class);
+ $hasAttributeAttribute = (bool) $attributeClass->getAttributesByInstance(Attribute::class);
return $hasAspectAttribute && $hasAttributeAttribute;
}
@@ -229,24 +217,25 @@ protected function hasAspectAndAttribute(
*
* @return void
*/
- private function cacheEmptyResult(
- string $namespacedClass,
- string $filePath,
- ): void {
- $filePath = Path::resolve($filePath);
+ private function cacheEmptyResult(string $namespacedClass, ?string $filePath): void
+ {
+ if ($filePath === null) {
+ return;
+ }
+ $filePath = Path::resolve($filePath);
+ if (!is_string($filePath)) {
+ return;
+ }
$cacheState = DI::make(EmptyResultCacheState::class, [
CacheState::DATA => [
CacheState::ORIGINAL_FILE_PATH_KEY => $filePath,
- CacheState::NAMESPACED_CLASS_KEY => $namespacedClass,
- CacheState::MODIFICATION_TIME_KEY => filemtime($filePath),
+ CacheState::NAMESPACED_CLASS_KEY => $namespacedClass,
+ CacheState::MODIFICATION_TIME_KEY => filemtime($filePath),
],
]);
// Set the cache state
- $this->cacheStateManager->setCacheState(
- $filePath,
- $cacheState,
- );
+ $this->cacheStateManager->setCacheState($filePath, $cacheState);
}
/**
@@ -257,10 +246,8 @@ private function cacheEmptyResult(
*
* @return void
*/
- public function addMatchedAdviceContainers(
- string $namespacedClass,
- array $adviceContainers,
- ): void {
+ public function addMatchedAdviceContainers(string $namespacedClass, array $adviceContainers): void
+ {
$this->matchedAdviceContainers[$namespacedClass] = $adviceContainers;
}
@@ -284,14 +271,12 @@ public function getMatchedAdviceContainers(string $namespacedClass): array
*
* @return MethodAdviceContainer[]
*/
- public function getMatchedAdviceContainersByJoinPoint(
- string $targetClassName,
- string $joinPoint,
- ): array {
+ public function getMatchedAdviceContainersByJoinPoint(string $targetClassName, string $joinPoint): array
+ {
$matchedAdviceContainers = [];
foreach ($this->matchedAdviceContainers[$targetClassName] as $adviceContainer) {
- if (!($adviceContainer instanceof MethodAdviceContainer)) {
+ if (!$adviceContainer instanceof MethodAdviceContainer) {
continue;
}
diff --git a/src/Core/Matcher/ClassMatcher.php b/src/Core/Matcher/ClassMatcher.php
index 19e7e3d..eea6128 100644
--- a/src/Core/Matcher/ClassMatcher.php
+++ b/src/Core/Matcher/ClassMatcher.php
@@ -1,4 +1,5 @@
adviceAttributeInstance;
- $classRegex = $adviceAttributeInstance->class;
- $namespacedClass = $refClass->getName();
+ $classRegex = $adviceAttributeInstance->class;
+ if ($classRegex === null) {
+ return false;
+ }
+ $namespacedClass = $refClass->getName();
$classMatches = $classRegex->matches($namespacedClass);
- $interfacesMatches = $this->matchInterfaces(
- $classRegex,
- $refClass,
- );
+ $interfacesMatches = $this->matchInterfaces($classRegex, $refClass);
- $parentClassesMatches = $this->matchParentClasses(
- $classRegex,
- $refClass,
- );
+ $parentClassesMatches = $this->matchParentClasses($classRegex, $refClass);
- $traitsMatches = $this->matchTraits(
- $classRegex,
- $refClass,
- );
+ $traitsMatches = $this->matchTraits($classRegex, $refClass);
- return $classMatches
- || $interfacesMatches
- || $parentClassesMatches
- || $traitsMatches;
+ return $classMatches || $interfacesMatches || $parentClassesMatches || $traitsMatches;
}
/**
@@ -76,15 +68,9 @@ public function match(
*
* @return bool
*/
- protected function matchInterfaces(
- Regex $classRegex,
- BetterReflectionClass $reflectionClass,
- ): bool {
- return $this->matchType(
- 'InterfaceNames',
- $classRegex,
- $reflectionClass,
- );
+ protected function matchInterfaces(Regex $classRegex, BetterReflectionClass $reflectionClass): bool
+ {
+ return $this->matchType('InterfaceNames', $classRegex, $reflectionClass);
}
/**
@@ -95,15 +81,9 @@ protected function matchInterfaces(
*
* @return bool
*/
- protected function matchParentClasses(
- Regex $classRegex,
- BetterReflectionClass $reflectionClass,
- ): bool {
- return $this->matchType(
- 'ParentClassNames',
- $classRegex,
- $reflectionClass,
- );
+ protected function matchParentClasses(Regex $classRegex, BetterReflectionClass $reflectionClass): bool
+ {
+ return $this->matchType('ParentClassNames', $classRegex, $reflectionClass);
}
/**
@@ -114,15 +94,9 @@ protected function matchParentClasses(
*
* @return bool
*/
- protected function matchTraits(
- Regex $classRegex,
- BetterReflectionClass $reflectionClass,
- ): bool {
- return $this->matchType(
- 'Traits',
- $classRegex,
- $reflectionClass,
- );
+ protected function matchTraits(Regex $classRegex, BetterReflectionClass $reflectionClass): bool
+ {
+ return $this->matchType('Traits', $classRegex, $reflectionClass);
}
/**
@@ -134,26 +108,24 @@ protected function matchTraits(
*
* @return bool
*/
- protected function matchType(
- string $type,
- Regex $classRegex,
- BetterReflectionClass $reflectionClass,
- ): bool {
+ protected function matchType(string $type, Regex $classRegex, BetterReflectionClass $reflectionClass): bool
+ {
try {
- $method = 'get' . $type;
- /** @var (BetterReflection|string)[] $reflections */
- $reflections = $reflectionClass->$method();
+ $reflections = match ($type) {
+ 'InterfaceNames' => $reflectionClass->getInterfaceNames(),
+ 'ParentClassNames' => $reflectionClass->getParentClassNames(),
+ 'Traits' => $reflectionClass->getTraits(),
+ default => throw new \InvalidArgumentException('Unsupported reflection type.'),
+ };
foreach ($reflections as $reflection) {
if ($classRegex->matches(
- $reflection instanceof BetterReflection
- ? $reflection->getName()
- : $reflection,
+ $reflection instanceof BetterReflection ? $reflection->getName() : $reflection,
)) {
return true;
}
}
} catch (IdentifierNotFound) {
- // Do nothing
+ return false;
}
return false;
diff --git a/src/Core/Processor/AspectProcessor.php b/src/Core/Processor/AspectProcessor.php
index 1d6a0c3..19ac429 100644
--- a/src/Core/Processor/AspectProcessor.php
+++ b/src/Core/Processor/AspectProcessor.php
@@ -1,4 +1,5 @@
uri;
- $proxyFilePath = $this->cachePaths->getProxyCachePath($originalFilePath);
- $wovenFilePath = $this->cachePaths->getWovenCachePath($originalFilePath);
- $transformed = $metadata->code->hasChanges();
+ $cachePaths = $this->cachePaths;
+ if (!$cachePaths instanceof \Okapi\Aop\Core\Cache\CachePaths) {
+ throw new \LogicException('Aspect processing requires AOP cache paths.');
+ }
+ $proxyFilePath = $cachePaths->getProxyCachePath($originalFilePath);
+ $wovenFilePath = $cachePaths->getWovenCachePath($originalFilePath);
+ $transformed = $metadata->code->hasChanges();
// Save the transformed code
if ($transformed) {
// Proxy
- Filesystem::writeFile(
- $proxyFilePath,
- $metadata->code->getNewSource(),
- );
+ Filesystem::writeFile($proxyFilePath, $metadata->code->getNewSource());
// Weaving
if ($wovenFile) {
- Filesystem::writeFile(
- $wovenFilePath,
- $wovenFile,
- );
+ Filesystem::writeFile($wovenFilePath, $wovenFile);
}
}
@@ -100,38 +100,42 @@ public function transform(Metadata $metadata): void
$cacheState = DI::make(WovenCacheState::class, [
CacheState::DATA => [
- CacheState::ORIGINAL_FILE_PATH_KEY => $originalFilePath,
- CacheState::NAMESPACED_CLASS_KEY => $namespacedClass,
- CacheState::MODIFICATION_TIME_KEY => $modificationTime,
- WovenCacheState::PROXY_FILE_PATH_KEY => $proxyFilePath,
- WovenCacheState::WOVEN_FILE_PATH_KEY => $wovenFilePath,
+ CacheState::ORIGINAL_FILE_PATH_KEY => $originalFilePath,
+ CacheState::NAMESPACED_CLASS_KEY => $namespacedClass,
+ CacheState::MODIFICATION_TIME_KEY => $modificationTime,
+ WovenCacheState::PROXY_FILE_PATH_KEY => $proxyFilePath,
+ WovenCacheState::WOVEN_FILE_PATH_KEY => $wovenFilePath,
WovenCacheState::TRANSFORMER_FILE_PATHS_KEY => $transformerFilePaths,
- WovenCacheState::ADVICE_NAMES_KEY => $adviceNames,
- WovenCacheState::ASPECT_FILE_PATHS_KEY => $aspectFilePaths,
- WovenCacheState::ASPECT_CLASS_NAMES_KEY => $aspectClassNames,
+ WovenCacheState::ADVICE_NAMES_KEY => $adviceNames,
+ WovenCacheState::ASPECT_FILE_PATHS_KEY => $aspectFilePaths,
+ WovenCacheState::ASPECT_CLASS_NAMES_KEY => $aspectClassNames,
],
]);
- } elseif ($transformed) {
+ $this->cacheStateManager->setCacheState($originalFilePath, $cacheState);
+ return;
+ }
+ if ($transformed) {
$transformerFilePaths = $this->getTransformerFilePaths($transformerContainers);
$cacheState = DI::make(TransformedCacheState::class, [
- CacheState::DATA => [
- CacheState::ORIGINAL_FILE_PATH_KEY => $originalFilePath,
- CacheState::NAMESPACED_CLASS_KEY => $namespacedClass,
- CacheState::MODIFICATION_TIME_KEY => $modificationTime,
- TransformedCacheState::TRANSFORMED_FILE_PATH_KEY => $proxyFilePath,
- TransformedCacheState::TRANSFORMER_FILE_PATHS_KEY => $transformerFilePaths,
- ],
- ]);
- } else {
- $cacheState = DI::make(NoTransformationsCacheState::class, [
CacheState::DATA => [
CacheState::ORIGINAL_FILE_PATH_KEY => $originalFilePath,
- CacheState::NAMESPACED_CLASS_KEY => $namespacedClass,
- CacheState::MODIFICATION_TIME_KEY => $modificationTime,
+ CacheState::NAMESPACED_CLASS_KEY => $namespacedClass,
+ CacheState::MODIFICATION_TIME_KEY => $modificationTime,
+ TransformedCacheState::TRANSFORMED_FILE_PATH_KEY => $proxyFilePath,
+ TransformedCacheState::TRANSFORMER_FILE_PATHS_KEY => $transformerFilePaths,
],
]);
+ $this->cacheStateManager->setCacheState($originalFilePath, $cacheState);
+ return;
}
+ $cacheState = DI::make(NoTransformationsCacheState::class, [
+ CacheState::DATA => [
+ CacheState::ORIGINAL_FILE_PATH_KEY => $originalFilePath,
+ CacheState::NAMESPACED_CLASS_KEY => $namespacedClass,
+ CacheState::MODIFICATION_TIME_KEY => $modificationTime,
+ ],
+ ]);
$this->cacheStateManager->setCacheState($originalFilePath, $cacheState);
}
@@ -144,20 +148,15 @@ public function transform(Metadata $metadata): void
*
* @return string The woven code
*/
- private function processAdvices(
- Metadata $metadata,
- array $adviceContainers,
- ): string {
+ private function processAdvices(Metadata $metadata, array $adviceContainers): string
+ {
// Sort the advices by priority
- usort(
- $adviceContainers,
- function (AdviceContainer $a, AdviceContainer $b) {
- $orderA = $a->adviceAttributeInstance->order;
- $orderB = $b->adviceAttributeInstance->order;
+ usort($adviceContainers, static function (AdviceContainer $a, AdviceContainer $b) {
+ $orderA = $a->adviceAttributeInstance->order;
+ $orderB = $b->adviceAttributeInstance->order;
- return $orderA <=> $orderB;
- },
- );
+ return $orderA <=> $orderB;
+ });
$proxiedClassModifier = DI::make(ProxiedClassModifier::class, [
'metadata' => $metadata,
@@ -166,10 +165,7 @@ function (AdviceContainer $a, AdviceContainer $b) {
$proxiedClassModifier->modify();
// Create the weaving file
- return $this->processAdviceContainers(
- $adviceContainers,
- $metadata->code,
- );
+ return $this->processAdviceContainers($adviceContainers, $metadata->code);
}
/**
@@ -180,12 +176,10 @@ function (AdviceContainer $a, AdviceContainer $b) {
*
* @return string
*/
- private function processAdviceContainers(
- array $adviceContainers,
- Code $code,
- ): string {
+ private function processAdviceContainers(array $adviceContainers, Code $code): string
+ {
$weavingClassBuilder = DI::make(WovenClassBuilder::class, [
- 'code' => $code,
+ 'code' => $code,
'adviceContainers' => $adviceContainers,
]);
@@ -202,9 +196,7 @@ private function processAdviceContainers(
protected function getAdviceNames(array $adviceContainers): array
{
return array_unique(array_map(
- function (AdviceContainer $adviceContainer) {
- return $adviceContainer->getName();
- },
+ static fn(AdviceContainer $adviceContainer) => $adviceContainer->getName(),
$adviceContainers,
));
}
@@ -218,12 +210,13 @@ function (AdviceContainer $adviceContainer) {
*/
protected function getAspectFilePaths(array $adviceContainers): array
{
- return array_unique(array_map(
- function (AdviceContainer $adviceContainer) {
- return $adviceContainer->aspectRefClass->getFileName();
- },
- $adviceContainers,
- ));
+ return array_unique(array_map(static function (AdviceContainer $adviceContainer) {
+ $filePath = $adviceContainer->aspectRefClass->getFileName();
+ if ($filePath === false) {
+ throw new \LogicException('An aspect must have a source file.');
+ }
+ return $filePath;
+ }, $adviceContainers));
}
/**
@@ -236,9 +229,7 @@ function (AdviceContainer $adviceContainer) {
protected function getAspectClassNames(array $adviceContainers): array
{
return array_unique(array_map(
- function (AdviceContainer $adviceContainer) {
- return $adviceContainer->aspectClassName;
- },
+ static fn(AdviceContainer $adviceContainer) => $adviceContainer->aspectClassName,
$adviceContainers,
));
}
diff --git a/src/Core/Transform/ProxiedClassModifier.php b/src/Core/Transform/ProxiedClassModifier.php
index affde9f..406f91d 100644
--- a/src/Core/Transform/ProxiedClassModifier.php
+++ b/src/Core/Transform/ProxiedClassModifier.php
@@ -1,4 +1,5 @@
[]
+ * @var list
*/
private array $tokenCallbacks = [];
/**
* Callbacks to process nodes.
*
- * @var callable[]
+ * @var list
*/
private array $nodeCallbacks = [];
@@ -75,19 +76,15 @@ public function __construct(
) {
$cachePaths = DI::get(CachePaths::class);
- $this->code = $this->metadata->code;
- $this->sourceFileNode = $this->code->getSourceFileNode();
+ $this->code = $this->metadata->code;
+ $this->sourceFileNode = $this->code->getSourceFileNode();
$this->proxiedClassName = $this->code->getClassName() . $cachePaths::PROXIED_SUFFIX;
}
/** @noinspection PhpUnused Is used at runtime for proxied classes */
public static function resolveStaticClass(string $staticClass): string
{
- return str_replace(
- CachePaths::PROXIED_SUFFIX,
- '',
- $staticClass,
- );
+ return str_replace(CachePaths::PROXIED_SUFFIX, '', $staticClass);
}
/**
@@ -107,32 +104,31 @@ public function modify(): void
$sourceFileNode = $this->metadata->code->getSourceFileNode();
// Iterate over the nodes
- foreach ($sourceFileNode->getDescendantNodes() as $node) {
+ /** @var iterable $nodes The parser yields nodes; its vendor PHPDoc uses an untyped Generator union. */
+ $nodes = $sourceFileNode->getDescendantNodes();
+ foreach ($nodes as $node) {
foreach ($this->nodeCallbacks as $callback) {
$callback($node);
}
}
// Iterate over the tokens
- foreach ($sourceFileNode->getDescendantTokens() as $token) {
+ /** @var iterable $tokens */
+ $tokens = $sourceFileNode->getDescendantTokens();
+ foreach ($tokens as $token) {
foreach ($this->tokenCallbacks as $callback) {
$callback($token);
}
}
}
- private function edit(
- Node|Token $nodeOrToken,
- string $replacement,
- ): void {
+ private function edit(Node|Token $nodeOrToken, string $replacement): void
+ {
if (in_array($nodeOrToken, $this->alreadyProcessed, true)) {
return;
}
- $this->code->edit(
- $nodeOrToken,
- $replacement,
- );
+ $this->code->edit($nodeOrToken, $replacement);
$this->alreadyProcessed[] = $nodeOrToken;
}
@@ -146,18 +142,15 @@ private function convertToProxy(): void
{
// Find the class declaration
$node = $this->sourceFileNode->getFirstDescendantNode(Node\Statement\ClassDeclaration::class);
- assert($node instanceof Node\Statement\ClassDeclaration);
+ assert($node instanceof Node\Statement\ClassDeclaration, 'The transformed source must declare a class.');
// Replace the class name
- $this->edit(
- $node->name,
- $this->proxiedClassName,
- );
+ $this->edit($node->name, $this->proxiedClassName);
// Append the child class
$childClassPath = $this->cachePaths->getWovenCachePath($this->metadata->uri);
// language=PHP
- $codeToAppend = "\ninclude_once '$childClassPath';";
+ $codeToAppend = "\ninclude_once '{$childClassPath}';";
$this->code->append($codeToAppend);
}
@@ -193,9 +186,11 @@ private function changeVisibility(): void
{
// A descendant may be loaded after this class. Keep every private property
// in its declaring scope, even when no same-name property is known yet.
- foreach ($this->sourceFileNode->getDescendantNodes() as $node) {
+ /** @var iterable $nodes */
+ $nodes = $this->sourceFileNode->getDescendantNodes();
+ foreach ($nodes as $node) {
$modifiers = match (true) {
- $node instanceof Node\PropertyDeclaration => $node->modifiers ?? [],
+ $node instanceof Node\PropertyDeclaration => $node->modifiers,
$node instanceof Node\Parameter => array_filter([
$node->visibilityToken,
...($node->modifiers ?? []),
@@ -203,20 +198,17 @@ private function changeVisibility(): void
default => [],
};
foreach ($modifiers as $modifier) {
- if ($modifier->kind === TokenKind::PrivateKeyword) {
- $this->alreadyProcessed[] = $modifier;
+ if ($modifier->kind !== TokenKind::PrivateKeyword) {
+ continue;
}
+
+ $this->alreadyProcessed[] = $modifier;
}
}
$this->tokenCallbacks[] = function (Token $token) {
- if ($token->kind === TokenKind::PrivateKeyword
- || $token->kind === TokenKind::ProtectedKeyword
- ) {
- $this->edit(
- $token,
- 'public',
- );
+ if ($token->kind === TokenKind::PrivateKeyword || $token->kind === TokenKind::ProtectedKeyword) {
+ $this->edit($token, 'public');
}
};
}
@@ -232,13 +224,16 @@ private function replaceSelfType(): void
{
$this->nodeCallbacks[] = function (Node $node) {
// Replace return object types with the proxied class name
- if ($node instanceof Node\MethodDeclaration
+ if (
+ $node instanceof Node\MethodDeclaration
&& $node->returnTypeList instanceof Node\DelimitedList\QualifiedNameList
) {
foreach ($node->returnTypeList->children as $returnType) {
- if ($returnType instanceof Node\QualifiedName) {
- $this->replaceReturnSelfType($returnType);
+ if (!$returnType instanceof Node\QualifiedName) {
+ continue;
}
+
+ $this->replaceReturnSelfType($returnType);
}
}
@@ -258,15 +253,11 @@ private function replaceSelfType(): void
*
* @return void
*/
- private function replaceReturnSelfType(
- Node\QualifiedName $qualifiedName,
- ): void {
+ private function replaceReturnSelfType(Node\QualifiedName $qualifiedName): void
+ {
// Self
if ($qualifiedName->getText() === 'self') {
- $this->edit(
- $qualifiedName,
- $this->proxiedClassName,
- );
+ $this->edit($qualifiedName, $this->proxiedClassName);
}
}
@@ -277,13 +268,9 @@ private function replaceReturnSelfType(
*
* @return void
*/
- private function replaceObjectCreationSelfType(
- Node\Expression\ObjectCreationExpression $objectCreationExpression,
- ): void {
- $this->edit(
- $objectCreationExpression->classTypeDesignator,
- '\\' . $this->code->getNamespacedClass(),
- );
+ private function replaceObjectCreationSelfType(Node\Expression\ObjectCreationExpression $objectCreationExpression): void
+ {
+ $this->edit($objectCreationExpression->classTypeDesignator, '\\' . $this->code->getNamespacedClass());
}
// endregion
@@ -305,19 +292,19 @@ private function replaceMagicConstants(): void
case '__DIR__':
$originalParentDir = dirname($this->getOriginalFileDir());
- $this->edit($node, "'$originalParentDir'");
+ $this->edit($node, "'{$originalParentDir}'");
break;
case '__FILE__':
$originalFileDir = $this->getOriginalFileDir();
- $this->edit($node, "'$originalFileDir'");
+ $this->edit($node, "'{$originalFileDir}'");
break;
case '__CLASS__':
$originalNamespacedClassName = $this->code->getNamespacedClass();
- $this->edit($node, "'$originalNamespacedClassName'");
+ $this->edit($node, "'{$originalNamespacedClassName}'");
break;
case '__METHOD__':
@@ -325,34 +312,25 @@ private function replaceMagicConstants(): void
if (!$methodNode) {
break;
}
- assert($methodNode instanceof Node\MethodDeclaration);
+ assert($methodNode instanceof Node\MethodDeclaration, 'The enclosing node must be a method.');
$originalNamespacedClassName = $this->code->getNamespacedClass();
$originalMethodName = $methodNode->getName();
- $this->edit(
- $node,
- "'$originalNamespacedClassName::$originalMethodName'",
- );
+ $this->edit($node, "'{$originalNamespacedClassName}::{$originalMethodName}'");
break;
case 'self':
$originalClassName = $this->code->getClassName();
- $this->edit(
- $node,
- $originalClassName,
- );
+ $this->edit($node, $originalClassName);
break;
}
}
if ($node instanceof Node\Expression\ScopedPropertyAccessExpression) {
if ($node->getText() === 'static::class') {
- $this->edit(
- $node,
- '\\' . self::class . '::resolveStaticClass(static::class)',
- );
+ $this->edit($node, '\\' . self::class . '::resolveStaticClass(static::class)');
}
}
};
diff --git a/src/Core/Transform/WovenClassBuilder.php b/src/Core/Transform/WovenClassBuilder.php
index 31f0b0a..0d81971 100644
--- a/src/Core/Transform/WovenClassBuilder.php
+++ b/src/Core/Transform/WovenClassBuilder.php
@@ -1,4 +1,5 @@
addUse(JoinPointInjector::class);
// Build the file
- $file = (string)$phpNamespace;
+ $file = (string) $phpNamespace;
// Inject the JoinPoints
$this->injectJoinPoints($file);
@@ -93,7 +94,7 @@ public function build(): string
private function buildNamespace(): PhpNamespace
{
$reflectionClass = $this->code->getReflectionClass();
- return new PhpNamespace($reflectionClass->getNamespaceName());
+ return new PhpNamespace($reflectionClass->getNamespaceName() ?? '');
}
/**
@@ -114,7 +115,7 @@ private function buildClass(PhpNamespace $phpNamespace): ClassType
$class->setName($shortClassName);
// Add the use statement
- $className = $reflectionClass->getName();
+ $className = $reflectionClass->getName();
$proxyClassName = $className . $this->cachePaths::PROXIED_SUFFIX;
$phpNamespace->addUse($proxyClassName);
@@ -151,18 +152,20 @@ private function buildJoinPoints(): Property
// Add interceptors
foreach ($this->adviceContainers as $adviceContainer) {
- if ($adviceContainer instanceof MethodAdviceContainer) {
- $methodType = JoinPoint::TYPE_METHOD;
+ if (!$adviceContainer instanceof MethodAdviceContainer) {
+ continue;
+ }
- foreach ($adviceContainer->getMatchedMethods() as $matchedMethod) {
- $matchedRefMethod = $matchedMethod->matchedRefMethod;
- $matchedMethodName = $matchedRefMethod->getName();
+ $methodType = JoinPoint::TYPE_METHOD;
- $adviceContainerName = $adviceContainer->getName();
+ foreach ($adviceContainer->getMatchedMethods() as $matchedMethod) {
+ $matchedRefMethod = $matchedMethod->matchedRefMethod;
+ $matchedMethodName = $matchedRefMethod->getName();
- if (!in_array($adviceContainerName, $value[$methodType][$matchedMethodName] ?? [])) {
- $value[$methodType][$matchedMethodName][] = $adviceContainerName;
- }
+ $adviceContainerName = $adviceContainer->getName();
+
+ if (!in_array($adviceContainerName, $value[$methodType][$matchedMethodName] ?? [], true)) {
+ $value[$methodType][$matchedMethodName][] = $adviceContainerName;
}
}
}
@@ -182,25 +185,27 @@ private function buildMethods(): array
$methods = [];
foreach ($this->adviceContainers as $adviceContainer) {
- if ($adviceContainer instanceof MethodAdviceContainer) {
- foreach ($adviceContainer->getMatchedMethods() as $matchedMethod) {
- $refMethod = $matchedMethod->matchedRefMethod;
- $methodName = $refMethod->getName();
-
- // Internal methods cannot be woven,
- // so we skip them
- if ($refMethod->getDeclaringClass()->isInternal()) {
- continue;
- }
-
- // Check if the method was already built
- if (array_key_exists($methodName, $methods)) {
- continue;
- }
-
- // Build the method
- $methods[$methodName] = $this->buildMethod($refMethod);
+ if (!$adviceContainer instanceof MethodAdviceContainer) {
+ continue;
+ }
+
+ foreach ($adviceContainer->getMatchedMethods() as $matchedMethod) {
+ $refMethod = $matchedMethod->matchedRefMethod;
+ $methodName = $refMethod->getName();
+
+ // Internal methods cannot be woven,
+ // so we skip them
+ if ($refMethod->getDeclaringClass()->isInternal()) {
+ continue;
}
+
+ // Check if the method was already built
+ if (array_key_exists($methodName, $methods)) {
+ continue;
+ }
+
+ // Build the method
+ $methods[$methodName] = $this->buildMethod($refMethod);
}
}
@@ -220,48 +225,52 @@ private function buildMethod(BetterReflectionMethod $refMethod): Method
{
$refMethod = new ReflectionMethod($refMethod);
/** @noinspection PhpUnhandledExceptionInspection */
- $method = (new Factory)->fromMethodReflection(
- $refMethod,
- );
+ $method = (new Factory())->fromMethodReflection($refMethod);
$methodName = $refMethod->getName();
$parameters = $method->getParameters();
foreach ($parameters as $name => $parameter) {
- if ($parameter instanceof PromotedParameter) {
- // Promotion belongs to the original constructor, which the
- // interceptor invokes. A forwarding method must not own a second slot.
- $plain = new Parameter($parameter->getName());
- $plain->setType($parameter->getType());
- $plain->setNullable($parameter->isNullable());
- $plain->setReference($parameter->isReference());
- $plain->setAttributes($parameter->getAttributes());
- if ($parameter->hasDefaultValue()) {
- $plain->setDefaultValue($parameter->getDefaultValue());
- }
- $parameters[$name] = $plain;
+ if (!$parameter instanceof PromotedParameter) {
+ continue;
}
+
+ $plain = new Parameter($parameter->getName());
+ $plain->setType($parameter->getType());
+ $plain->setNullable($parameter->isNullable());
+ $plain->setReference($parameter->isReference());
+ $plain->setAttributes($parameter->getAttributes());
+ if ($parameter->hasDefaultValue()) {
+ $plain->setDefaultValue($parameter->getDefaultValue());
+ }
+ $parameters[$name] = $plain;
}
- $method->setParameters($parameters);
+ $method->setParameters(array_values($parameters));
// Add "return" if the method has a return type
- $return = (string)$method->getReturnType() !== 'void' ? 'return ' : '';
+ $return = (string) $method->getReturnType() !== 'void' ? 'return ' : '';
// Add parameters as an array with the parameter name as key
$parametersArray = $this->getParametersArray($refMethod);
- $parameters = $parametersArray ? ", $parametersArray" : '';
+ $parameters = $parametersArray ? ", {$parametersArray}" : '';
// Static methods don't have $this
$isStatic = $refMethod->isStatic();
- $context = $isStatic ? 'null' : '$this';
+ $context = $isStatic ? 'null' : '$this';
- $body = $return
+ $body =
+ $return
. 'call_user_func_array('
- . 'self::$' . JoinPoint::JOIN_POINTS_PARAMETER_NAME
- . '[\'' . JoinPoint::TYPE_METHOD . '\']'
- . '[\'' . $methodName . '\'], '
- . "[$context"
- . "$parameters]);";
+ . 'self::$'
+ . JoinPoint::JOIN_POINTS_PARAMETER_NAME
+ . '[\''
+ . JoinPoint::TYPE_METHOD
+ . '\']'
+ . '[\''
+ . $methodName
+ . '\'], '
+ . "[{$context}"
+ . "{$parameters}]);";
/**
* @example
@@ -289,7 +298,7 @@ private function buildMethod(BetterReflectionMethod $refMethod): Method
private function getParametersArray(ReflectionMethod $method): ?string
{
$parameters = $method->getParameters();
- if (empty($parameters)) {
+ if ($parameters === []) {
return null;
}
@@ -313,10 +322,10 @@ private function getParametersArray(ReflectionMethod $method): ?string
private function injectJoinPoints(string &$file): void
{
$reflectionClass = $this->code->getReflectionClass();
- $shortClassName = $reflectionClass->getShortName();
+ $shortClassName = $reflectionClass->getShortName();
// language=PHP
- $code = "DI::get(JoinPointInjector::class)->injectJoinPoints($shortClassName::class);";
+ $code = "DI::get(JoinPointInjector::class)->injectJoinPoints({$shortClassName}::class);";
$file .= "\n" . $code;
}
diff --git a/src/Invocation/BeforeMethodInvocation.php b/src/Invocation/BeforeMethodInvocation.php
index 7000030..9c25cef 100644
--- a/src/Invocation/BeforeMethodInvocation.php
+++ b/src/Invocation/BeforeMethodInvocation.php
@@ -10,6 +10,4 @@
* This class is used to pass information to {@see Before} advices in form of a
* parameter.
*/
-class BeforeMethodInvocation extends MethodInvocation
-{
-}
+class BeforeMethodInvocation extends MethodInvocation {}
diff --git a/src/Invocation/MethodInvocation.php b/src/Invocation/MethodInvocation.php
index b2779d5..64bdb38 100644
--- a/src/Invocation/MethodInvocation.php
+++ b/src/Invocation/MethodInvocation.php
@@ -22,10 +22,10 @@ abstract class MethodInvocation
*/
public function __construct(
private readonly ?object $subject,
- private readonly string $className,
- private readonly string $methodName,
- protected mixed $result,
- private array &$arguments,
+ private readonly string $className,
+ private readonly string $methodName,
+ protected mixed $result,
+ private array &$arguments,
) {}
/**
@@ -39,9 +39,8 @@ public function getArgument(int|string $nameOrIndex): mixed
{
if (is_int($nameOrIndex)) {
return array_values($this->arguments)[$nameOrIndex] ?? null;
- } else {
- return $this->arguments[$nameOrIndex] ?? null;
}
+ return $this->arguments[$nameOrIndex] ?? null;
}
/**
@@ -56,15 +55,15 @@ public function setArgument(int|string $nameOrIndex, mixed $value): void
{
if (is_int($nameOrIndex)) {
$this->arguments[array_keys($this->arguments)[$nameOrIndex]] = $value;
- } else {
- $this->arguments[$nameOrIndex] = $value;
+ return;
}
+ $this->arguments[$nameOrIndex] = $value;
}
/**
* Get all arguments.
*
- * @return array
+ * @return array
*/
public function getArguments(): array
{
@@ -93,13 +92,10 @@ public function setArguments(array $arguments): void
public function getAdviceType(): AdviceType
{
return match (true) {
- $this instanceof AroundMethodInvocation => AdviceType::Around,
- $this instanceof BeforeMethodInvocation => AdviceType::Before,
- $this instanceof AfterMethodInvocation => AdviceType::After,
- // TODO: Implement
- $this instanceof AfterReturningMethodInvocation => AdviceType::AfterReturning,
- // TODO: Implement
- $this instanceof AfterThrowingMethodInvocation => AdviceType::AfterThrowing,
+ $this instanceof AroundMethodInvocation => AdviceType::Around,
+ $this instanceof BeforeMethodInvocation => AdviceType::Before,
+ $this instanceof AfterMethodInvocation => AdviceType::After,
+ default => throw new \UnhandledMatchError('Unsupported advice invocation type.'),
};
}
@@ -115,7 +111,9 @@ public function getSubject(): ?object
return $this->subject;
}
- /** Access the subject's properties, optionally in an original declaring scope. */
+ /**
+ * Access the subject's properties, optionally in an original declaring scope.
+ */
public function properties(?string $declaringClass = null): PropertyAccessor
{
return new PropertyAccessor($this->subject ?? $this->className, $declaringClass);
diff --git a/src/Invocation/PropertyAccessor.php b/src/Invocation/PropertyAccessor.php
index ab39185..1c1dc0d 100644
--- a/src/Invocation/PropertyAccessor.php
+++ b/src/Invocation/PropertyAccessor.php
@@ -1,9 +1,13 @@
subject, $name, $this->declaringClass);
- return $value;
+ return PropertyAccess::reference($this->subject, $name, $this->declaringClass);
}
public function __set(string $name, mixed $value): void
diff --git a/src/PropertyAccess.php b/src/PropertyAccess.php
index 9f0572e..9a4ecae 100644
--- a/src/PropertyAccess.php
+++ b/src/PropertyAccess.php
@@ -1,9 +1,10 @@
isInitialized(is_object($subject) ? $subject : null)) {
- throw new Error('Property ' . $property->getDeclaringClass()->getName()
- . '::$' . $name . ' must not be accessed before initialization');
+ throw new Error(
+ 'Property '
+ . $property->getDeclaringClass()->getName()
+ . '::$'
+ . $name
+ . ' must not be accessed before initialization',
+ );
}
return $property->getValue(is_object($subject) ? $subject : null);
}
@@ -46,14 +52,29 @@ public static function &reference(object|string $subject, string $name, ?string
$property = self::resolve($subject, $name, $declaringClass);
// Do not initialize nullable properties or invoke __get after explicit unset.
if (!$property->isInitialized(is_object($subject) ? $subject : null)) {
- throw new Error('Typed property ' . $property->getDeclaringClass()->getName()
- . '::$' . $name . ' must not be accessed before initialization');
+ throw new Error(
+ 'Typed property '
+ . $property->getDeclaringClass()->getName()
+ . '::$'
+ . $name
+ . ' must not be accessed before initialization',
+ );
}
$scope = $property->getDeclaringClass()->getName();
- $read = $property->isStatic()
- ? Closure::bind(static function &() use ($name) { return self::$$name; }, null, $scope)
- : Closure::bind(function &() use ($name) { return $this->$name; }, $subject, $scope);
- $value =& $read();
+ if ($property->isStatic()) {
+ $read = Closure::bind(static fn&(): mixed => $scope::${$name}, null, $scope);
+ /** @var mixed $value A property can hold any value; its declared type is checked by PHP. */
+ $value = &$read();
+ return $value;
+ }
+ if (!is_object($subject)) {
+ throw new LogicException('An instance property requires an object.');
+ }
+ // resolve() validates the declaration and scope; PHP retains the reference and its type constraint.
+ // @mago-expect analysis:string-member-selector,ambiguous-object-property-access
+ $read = Closure::bind(static fn&(object $target): mixed => $target->{$name}, null, $scope);
+ /** @var mixed $value A property can hold any value; its declared type is checked by PHP. */
+ $value = &$read($subject);
return $value;
}
@@ -78,23 +99,37 @@ public static function remove(object|string $subject, string $name, ?string $dec
return;
}
if ($property->isStatic()) {
- throw new Error("Cannot unset static property \$$name.");
+ throw new Error("Cannot unset static property \${$name}.");
+ }
+ if (!is_object($subject)) {
+ throw new LogicException('An instance property requires an object.');
}
if (!$property->isInitialized($subject)) {
return;
}
- $remove = Closure::bind(function () use ($name): void {
- unset($this->$name);
- }, $subject, $property->getDeclaringClass()->getName());
- $remove();
+ $remove = Closure::bind(
+ static function (object $target) use ($name): void {
+ // resolve() has checked this declared property; runtime names are inherent to the accessor API.
+ // @mago-expect analysis:string-member-selector,ambiguous-object-property-access
+ unset($target->{$name});
+ },
+ null,
+ $property->getDeclaringClass()->getName(),
+ );
+ $remove($subject);
}
- private static function resolve(object|string $subject, string $name, ?string $declaringClass = null): ReflectionProperty
- {
+ private static function resolve(
+ object|string $subject,
+ string $name,
+ ?string $declaringClass = null,
+ ): ReflectionProperty {
$matches = [];
$scope = $declaringClass === null ? null : ltrim($declaringClass, '\\');
- $class = new ReflectionClass($subject);
- do {
+ if (is_string($subject) && !class_exists($subject)) {
+ throw new ReflectionException("Class {$subject} does not exist.");
+ }
+ for ($class = new ReflectionClass($subject); $class !== false; $class = $class->getParentClass()) {
$originalName = $class->getName();
if (str_ends_with($originalName, CachePaths::PROXIED_SUFFIX)) {
$originalName = substr($originalName, 0, -strlen(CachePaths::PROXIED_SUFFIX));
@@ -115,17 +150,19 @@ private static function resolve(object|string $subject, string $name, ?string $d
$key = $independent ? $class->getName() : 'inherited';
$matches[$key] = $property;
}
- } while ($class = $class->getParentClass());
+ }
if (!$matches) {
- throw new ReflectionException("Property \$$name does not exist in the requested scope.");
+ throw new ReflectionException("Property \${$name} does not exist in the requested scope.");
}
if (count($matches) > 1) {
- throw new LogicException("Property \$$name is ambiguous; pass its original declaring class to PropertyAccess::get()/set().");
+ throw new LogicException(
+ "Property \${$name} is ambiguous; pass its original declaring class to PropertyAccess::get()/set().",
+ );
}
- $property = reset($matches);
+ $property = array_values($matches)[0];
if (is_string($subject) && !$property->isStatic()) {
- throw new LogicException("An object is required to access instance property \$$name.");
+ throw new LogicException("An object is required to access instance property \${$name}.");
}
return $property;
}
diff --git a/tests/ClassLoaderMockTrait.php b/tests/ClassLoaderMockTrait.php
index d39bdc5..8f18910 100644
--- a/tests/ClassLoaderMockTrait.php
+++ b/tests/ClassLoaderMockTrait.php
@@ -20,7 +20,11 @@ private function findClassMock(string $class): string
$this->findClassLoader();
}
- return $this->classLoader->findFile($class);
+ assert($this->classLoader instanceof ClassLoader, 'The invocation must match the configured test fixture.');
+ /** @var mixed $file */
+ $file = $this->classLoader->findFile($class);
+ Assert::assertIsString($file);
+ return $file;
}
private function findOriginalClassMock(string $class): string
@@ -29,66 +33,58 @@ private function findOriginalClassMock(string $class): string
$this->findClassLoader();
}
+ assert($this->classLoader instanceof ClassLoader, 'The invocation must match the configured test fixture.');
$original = new ReflectionProperty(ClassLoader::class, 'originalClassLoader');
- $original = $original->getValue($this->classLoader);
- return $original->findFile($class);
+ /** @var mixed $loader */
+ $loader = $original->getValue($this->classLoader);
+ Assert::assertInstanceOf(\Composer\Autoload\ClassLoader::class, $loader);
+ $file = $loader->findFile($class);
+ Assert::assertIsString($file);
+ return $file;
}
private function findClassLoader(): void
{
foreach (spl_autoload_functions() as $function) {
- if (is_array($function) && $function[0] instanceof ClassLoader) {
- $this->classLoader = $function[0];
- break;
+ if (!(is_array($function) && $function[0] instanceof ClassLoader)) {
+ continue;
}
+
+ $this->classLoader = $function[0];
+ break;
}
}
public function assertWillBeWoven(string $className): void
{
$originalFilePath = Path::resolve($this->findOriginalClassMock($className));
+ Assert::assertIsString($originalFilePath);
- $wovenPath =
- FilterInjector::PHP_FILTER_READ .
- StreamFilter::FILTER_ID . '/resource=' .
- $originalFilePath;
+ $wovenPath = FilterInjector::PHP_FILTER_READ . StreamFilter::FILTER_ID . '/resource=' . $originalFilePath;
$filePathMock = $this->findClassMock($className);
- Assert::assertEquals(
- $wovenPath,
- $filePathMock,
- "$className will not be woven",
- );
+ Assert::assertEquals($wovenPath, $filePathMock, "{$className} will not be woven");
}
public function assertAspectLoadedFromCache(string $className): void
{
$filePath = Path::resolve($this->findOriginalClassMock($className));
+ Assert::assertIsString($filePath);
- $cachePath =
- FilterInjector::PHP_FILTER_READ .
- CachedStreamFilter::CACHED_FILTER_ID . '/resource=' .
- $filePath;
+ $cachePath = FilterInjector::PHP_FILTER_READ . CachedStreamFilter::CACHED_FILTER_ID . '/resource=' . $filePath;
$filePathMock = $this->findClassMock($className);
- Assert::assertEquals(
- $cachePath,
- $filePathMock,
- "$className will not be loaded from cache",
- );
+ Assert::assertEquals($cachePath, $filePathMock, "{$className} will not be loaded from cache");
}
public function assertAspectNotApplied(string $className): void
{
$originalFilePath = Path::resolve($this->findOriginalClassMock($className));
- $filePathMock = $this->findClassMock($className);
+ Assert::assertIsString($originalFilePath);
+ $filePathMock = $this->findClassMock($className);
- Assert::assertEquals(
- $originalFilePath,
- $filePathMock,
- "$className will be woven",
- );
+ Assert::assertEquals($originalFilePath, $filePathMock, "{$className} will be woven");
}
}
diff --git a/tests/Functional/AdviceApplication/AdviceMatchingAbstractMethod/AdviceMatchingAbstractMethodTest.php b/tests/Functional/AdviceApplication/AdviceMatchingAbstractMethod/AdviceMatchingAbstractMethodTest.php
index c304684..57c2dba 100644
--- a/tests/Functional/AdviceApplication/AdviceMatchingAbstractMethod/AdviceMatchingAbstractMethodTest.php
+++ b/tests/Functional/AdviceApplication/AdviceMatchingAbstractMethod/AdviceMatchingAbstractMethodTest.php
@@ -29,9 +29,6 @@ public function testAbstractMethod(): void
$result = $uploader->upload('C:\Windows\Temp\file.txt');
/** @noinspection PhpConditionAlreadyCheckedInspection */
- $this->assertEquals(
- 'C:/Windows/Temp/file.txt',
- $result
- );
+ static::assertSame('C:/Windows/Temp/file.txt', $result);
}
}
diff --git a/tests/Functional/AdviceApplication/AdviceMatchingAbstractMethod/Aspect/FileUploaderAspect.php b/tests/Functional/AdviceApplication/AdviceMatchingAbstractMethod/Aspect/FileUploaderAspect.php
index aaf223d..7995082 100644
--- a/tests/Functional/AdviceApplication/AdviceMatchingAbstractMethod/Aspect/FileUploaderAspect.php
+++ b/tests/Functional/AdviceApplication/AdviceMatchingAbstractMethod/Aspect/FileUploaderAspect.php
@@ -1,4 +1,5 @@
proceed();
$modifiedResult = str_replace('\\', '/', $result);
$invocation->setResult($modifiedResult);
diff --git a/tests/Functional/AdviceApplication/AdviceMatchingAbstractMethod/Kernel.php b/tests/Functional/AdviceApplication/AdviceMatchingAbstractMethod/Kernel.php
index c76b9f4..13aa8e4 100644
--- a/tests/Functional/AdviceApplication/AdviceMatchingAbstractMethod/Kernel.php
+++ b/tests/Functional/AdviceApplication/AdviceMatchingAbstractMethod/Kernel.php
@@ -10,6 +10,7 @@ class Kernel extends AopKernel
{
protected ?string $cacheDir = Util::CACHE_DIR;
+ /** @var array */
protected array $aspects = [
FileUploaderAspect::class,
];
diff --git a/tests/Functional/AdviceApplication/ExplicitClassLevelAspect/Aspect/LoggingAspect.php b/tests/Functional/AdviceApplication/ExplicitClassLevelAspect/Aspect/LoggingAspect.php
index 147091f..46dd58f 100644
--- a/tests/Functional/AdviceApplication/ExplicitClassLevelAspect/Aspect/LoggingAspect.php
+++ b/tests/Functional/AdviceApplication/ExplicitClassLevelAspect/Aspect/LoggingAspect.php
@@ -1,4 +1,5 @@
getMethodName();
- $logMessage = sprintf(
- "Method '%s' executed.",
- $methodName,
- );
+ $logMessage = sprintf("Method '%s' executed.", $methodName);
$logger = Logger::getInstance();
$logger->log($logMessage);
}
- #[Before(
- method: 'updateInventory',
- )]
+ #[Before(method: 'updateInventory')]
public function logUpdateInventory(BeforeMethodInvocation $invocation): void
{
$methodName = $invocation->getMethodName();
- $logMessage = sprintf(
- "Method '%s' executed.",
- $methodName,
- );
+ $logMessage = sprintf("Method '%s' executed.", $methodName);
$logger = Logger::getInstance();
$logger->log($logMessage);
diff --git a/tests/Functional/AdviceApplication/ExplicitClassLevelAspect/ExplicitClassLevelAspectTest.php b/tests/Functional/AdviceApplication/ExplicitClassLevelAspect/ExplicitClassLevelAspectTest.php
index 16b72cc..43b25c5 100644
--- a/tests/Functional/AdviceApplication/ExplicitClassLevelAspect/ExplicitClassLevelAspectTest.php
+++ b/tests/Functional/AdviceApplication/ExplicitClassLevelAspect/ExplicitClassLevelAspectTest.php
@@ -50,7 +50,7 @@ private function executeTest(): void
$logger = Logger::getInstance();
- $logs = $logger->getLogs();
+ $logs = $logger->getLogs();
$this->assertCount(6, $logs);
$updateInventoryExecuted = 0;
@@ -61,7 +61,8 @@ private function executeTest(): void
foreach ($logs as $log) {
if ($log === $updateInventoryLog) {
$updateInventoryExecuted++;
- } elseif ($log === $checkInventoryLog) {
+ }
+ if ($log === $checkInventoryLog) {
$checkInventoryExecuted++;
}
}
diff --git a/tests/Functional/AdviceApplication/ExplicitClassLevelAspect/Target/InventoryTracker.php b/tests/Functional/AdviceApplication/ExplicitClassLevelAspect/Target/InventoryTracker.php
index 5667ea1..90e4810 100644
--- a/tests/Functional/AdviceApplication/ExplicitClassLevelAspect/Target/InventoryTracker.php
+++ b/tests/Functional/AdviceApplication/ExplicitClassLevelAspect/Target/InventoryTracker.php
@@ -7,6 +7,7 @@
#[LoggingAspect]
class InventoryTracker
{
+ /** @var array */
private array $inventory = [];
public function updateInventory(int $productId, int $quantity): void
diff --git a/tests/Functional/AdviceApplication/ExplicitMethodLevelAspect/Aspect/PerformanceAspect.php b/tests/Functional/AdviceApplication/ExplicitMethodLevelAspect/Aspect/PerformanceAspect.php
index 93ec978..6db4e00 100644
--- a/tests/Functional/AdviceApplication/ExplicitMethodLevelAspect/Aspect/PerformanceAspect.php
+++ b/tests/Functional/AdviceApplication/ExplicitMethodLevelAspect/Aspect/PerformanceAspect.php
@@ -21,15 +21,10 @@ public function measure(AroundMethodInvocation $invocation): void
$executionTime = $end - $start;
- $class = $invocation->getClassName();
+ $class = $invocation->getClassName();
$method = $invocation->getMethodName();
- $logMessage = sprintf(
- "Method %s::%s executed in %.2f seconds.",
- $class,
- $method,
- $executionTime,
- );
+ $logMessage = sprintf('Method %s::%s executed in %.2f seconds.', $class, $method, $executionTime);
$logger = Logger::getInstance();
$logger->log($logMessage);
diff --git a/tests/Functional/AdviceApplication/ExplicitMethodLevelAspect/ExplicitMethodLevelAspectTest.php b/tests/Functional/AdviceApplication/ExplicitMethodLevelAspect/ExplicitMethodLevelAspectTest.php
index 4ec112b..fd92246 100644
--- a/tests/Functional/AdviceApplication/ExplicitMethodLevelAspect/ExplicitMethodLevelAspectTest.php
+++ b/tests/Functional/AdviceApplication/ExplicitMethodLevelAspect/ExplicitMethodLevelAspectTest.php
@@ -70,8 +70,8 @@ private function executeTest(): void
$firstLog = $logs[0];
$wildcard = 'Method *::* executed in * seconds.';
- $regex = Regex::fromWildcard($wildcard);
- $matches = $regex->matches($firstLog);
+ $regex = Regex::fromWildcard($wildcard);
+ $matches = $regex->matches($firstLog);
$this->assertTrue($matches);
}
}
diff --git a/tests/Functional/AdviceApplication/ExplicitMethodLevelAspect/Kernel.php b/tests/Functional/AdviceApplication/ExplicitMethodLevelAspect/Kernel.php
index 36c32b0..96396a3 100644
--- a/tests/Functional/AdviceApplication/ExplicitMethodLevelAspect/Kernel.php
+++ b/tests/Functional/AdviceApplication/ExplicitMethodLevelAspect/Kernel.php
@@ -10,6 +10,7 @@ class Kernel extends AopKernel
{
protected ?string $cacheDir = Util::CACHE_DIR;
+ /** @var array */
protected array $aspects = [
PerformanceAspect::class,
];
diff --git a/tests/Functional/AdviceApplication/MultipleExplicitMethodLevelAspects/Aspect/SecurityAspect.php b/tests/Functional/AdviceApplication/MultipleExplicitMethodLevelAspects/Aspect/SecurityAspect.php
index 8861727..62519e7 100644
--- a/tests/Functional/AdviceApplication/MultipleExplicitMethodLevelAspects/Aspect/SecurityAspect.php
+++ b/tests/Functional/AdviceApplication/MultipleExplicitMethodLevelAspects/Aspect/SecurityAspect.php
@@ -16,12 +16,13 @@ class SecurityAspect
#[Before]
public function applySecurityMeasures(BeforeMethodInvocation $invocation): void
{
+ /** @var non-empty-array $arguments */
$arguments = $invocation->getArguments();
- $firstArgument = reset($arguments);
- $firstArgumentKey = key($arguments);
+ $firstArgumentKey = array_key_first($arguments);
+ $firstArgument = $arguments[$firstArgumentKey];
- if (gettype($firstArgument) === 'array') {
+ if (is_array($firstArgument)) {
$id = &$firstArgument['id'];
$id .= self::SECRET_HASH;
@@ -30,7 +31,7 @@ public function applySecurityMeasures(BeforeMethodInvocation $invocation): void
$invocation->setArguments($arguments);
}
- if (gettype($firstArgument) === 'string') {
+ if (is_string($firstArgument)) {
$id = &$firstArgument;
$id .= self::SECRET_HASH;
diff --git a/tests/Functional/AdviceApplication/MultipleExplicitMethodLevelAspects/MultipleExplicitMethodLevelAspectsTest.php b/tests/Functional/AdviceApplication/MultipleExplicitMethodLevelAspects/MultipleExplicitMethodLevelAspectsTest.php
index 15c72ad..d66b45a 100644
--- a/tests/Functional/AdviceApplication/MultipleExplicitMethodLevelAspects/MultipleExplicitMethodLevelAspectsTest.php
+++ b/tests/Functional/AdviceApplication/MultipleExplicitMethodLevelAspects/MultipleExplicitMethodLevelAspectsTest.php
@@ -32,17 +32,16 @@ public function testMultipleExplicitMethodLevelAspects(): void
$accountService->createAccount(['id' => $id]);
$accounts = $accountService->getAccounts();
- $this->assertCount(1, $accounts);
+ static::assertCount(1, $accounts);
$firstAccount = $accounts[0];
- $this->assertStringEndsWith(SecurityAspect::SECRET_HASH, $firstAccount);
+ static::assertStringEndsWith(SecurityAspect::SECRET_HASH, $firstAccount);
/** @noinspection PhpUnhandledExceptionInspection */
$accountService->deleteAccount($id);
$accounts = $accountService->getAccounts();
- $this->assertCount(0, $accounts);
-
+ static::assertCount(0, $accounts);
$this->assertWillBeWoven(TransactionService::class);
$transactionService = new TransactionService();
@@ -50,15 +49,15 @@ public function testMultipleExplicitMethodLevelAspects(): void
$transactionService->createTransaction(['id' => $id]);
$transactions = $transactionService->getTransactions();
- $this->assertCount(1, $transactions);
+ static::assertCount(1, $transactions);
$firstTransaction = $transactions[0];
- $this->assertStringEndsWith(SecurityAspect::SECRET_HASH, $firstTransaction);
+ static::assertStringEndsWith(SecurityAspect::SECRET_HASH, $firstTransaction);
/** @noinspection PhpUnhandledExceptionInspection */
$transactionService->rollbackTransaction($id);
$transactions = $transactionService->getTransactions();
- $this->assertCount(0, $transactions);
+ static::assertCount(0, $transactions);
}
}
diff --git a/tests/Functional/AdviceApplication/MultipleExplicitMethodLevelAspects/Target/AccountService.php b/tests/Functional/AdviceApplication/MultipleExplicitMethodLevelAspects/Target/AccountService.php
index 3226ad4..0ffbed5 100644
--- a/tests/Functional/AdviceApplication/MultipleExplicitMethodLevelAspects/Target/AccountService.php
+++ b/tests/Functional/AdviceApplication/MultipleExplicitMethodLevelAspects/Target/AccountService.php
@@ -7,8 +7,10 @@
class AccountService
{
+ /** @var array */
private array $accounts = [];
+ /** @param array{id: string} $userData */
#[SecurityAspect]
public function createAccount(array $userData): void
{
@@ -18,16 +20,17 @@ public function createAccount(array $userData): void
#[SecurityAspect]
public function deleteAccount(string $accountId): void
{
- $accountIndex = array_search($accountId, $this->accounts);
+ $accountIndex = array_search($accountId, $this->accounts, true);
if ($accountIndex === false) {
/** @noinspection PhpUnhandledExceptionInspection */
- throw new Exception("Account with id $accountId not found.");
+ throw new Exception("Account with id {$accountId} not found.");
}
unset($this->accounts[$accountIndex]);
}
+ /** @return array */
public function getAccounts(): array
{
return $this->accounts;
diff --git a/tests/Functional/AdviceApplication/MultipleExplicitMethodLevelAspects/Target/TransactionService.php b/tests/Functional/AdviceApplication/MultipleExplicitMethodLevelAspects/Target/TransactionService.php
index a8c14fc..0c4b544 100644
--- a/tests/Functional/AdviceApplication/MultipleExplicitMethodLevelAspects/Target/TransactionService.php
+++ b/tests/Functional/AdviceApplication/MultipleExplicitMethodLevelAspects/Target/TransactionService.php
@@ -7,8 +7,10 @@
class TransactionService
{
+ /** @var array */
private array $transactions = [];
+ /** @param array{id: string} $transactionData */
#[SecurityAspect]
public function createTransaction(array $transactionData): void
{
@@ -18,16 +20,17 @@ public function createTransaction(array $transactionData): void
#[SecurityAspect]
public function rollbackTransaction(string $transactionId): void
{
- $transactionIndex = array_search($transactionId, $this->transactions);
+ $transactionIndex = array_search($transactionId, $this->transactions, true);
if ($transactionIndex === false) {
/** @noinspection PhpUnhandledExceptionInspection */
- throw new Exception("Transaction with id $transactionId not found.");
+ throw new Exception("Transaction with id {$transactionId} not found.");
}
unset($this->transactions[$transactionIndex]);
}
+ /** @return array */
public function getTransactions(): array
{
return $this->transactions;
diff --git a/tests/Functional/AdviceBehavior/AdviceOrder/AdviceOrderTest.php b/tests/Functional/AdviceBehavior/AdviceOrder/AdviceOrderTest.php
index a1fa95c..9375119 100644
--- a/tests/Functional/AdviceBehavior/AdviceOrder/AdviceOrderTest.php
+++ b/tests/Functional/AdviceBehavior/AdviceOrder/AdviceOrderTest.php
@@ -28,14 +28,11 @@ public function testAdviceOrderTest(): void
$this->assertWillBeWoven(ArticleManager::class);
$articleManager = new ArticleManager();
- $articleManager->createArticle(
- 'Hello World',
- 'AOP is awesome!',
- );
+ $articleManager->createArticle('Hello World', 'AOP is awesome!');
$stackTrace = StackTrace::getInstance();
- $this->assertEquals(
+ static::assertEquals(
[
'checkForSpam',
'validateContent',
diff --git a/tests/Functional/AdviceBehavior/AdviceOrder/Aspect/ArticleModerationAspect.php b/tests/Functional/AdviceBehavior/AdviceOrder/Aspect/ArticleModerationAspect.php
index ddb4e2b..72543a9 100644
--- a/tests/Functional/AdviceBehavior/AdviceOrder/Aspect/ArticleModerationAspect.php
+++ b/tests/Functional/AdviceBehavior/AdviceOrder/Aspect/ArticleModerationAspect.php
@@ -1,4 +1,5 @@
addTrace('validateContent');
}
- #[After(
- class: ArticleManager::class,
- method: 'createArticle',
- order: -10,
- )]
- public function checkForSpam()
+ #[After(class: ArticleManager::class, method: 'createArticle', order: -10)]
+ public function checkForSpam(): void
{
$stackTrace = StackTrace::getInstance();
$stackTrace->addTrace('checkForSpam');
}
- #[After(
- class: ArticleManager::class,
- method: 'createArticle',
- order: 10,
- )]
- public function ensureProperFormatting()
+ #[After(class: ArticleManager::class, method: 'createArticle', order: 10)]
+ public function ensureProperFormatting(): void
{
$stackTrace = StackTrace::getInstance();
$stackTrace->addTrace('ensureProperFormatting');
diff --git a/tests/Functional/AdviceBehavior/AdviceOrder/Kernel.php b/tests/Functional/AdviceBehavior/AdviceOrder/Kernel.php
index ba70d54..4957f41 100644
--- a/tests/Functional/AdviceBehavior/AdviceOrder/Kernel.php
+++ b/tests/Functional/AdviceBehavior/AdviceOrder/Kernel.php
@@ -10,6 +10,7 @@ class Kernel extends AopKernel
{
protected ?string $cacheDir = Util::CACHE_DIR;
+ /** @var array */
protected array $aspects = [
ArticleModerationAspect::class,
];
diff --git a/tests/Functional/AdviceBehavior/AdviceOrder/Target/ArticleManager.php b/tests/Functional/AdviceBehavior/AdviceOrder/Target/ArticleManager.php
index 9f592b8..72b9bf2 100644
--- a/tests/Functional/AdviceBehavior/AdviceOrder/Target/ArticleManager.php
+++ b/tests/Functional/AdviceBehavior/AdviceOrder/Target/ArticleManager.php
@@ -4,7 +4,7 @@
class ArticleManager
{
- public function createArticle(string $title, string $content)
+ public function createArticle(string $title, string $content): void
{
// Code to create and save an article object
}
diff --git a/tests/Functional/AdviceBehavior/BeforeAroundAfterAdviceOnSameAdviceMethod/Aspect/CalculatorLoggerAspect.php b/tests/Functional/AdviceBehavior/BeforeAroundAfterAdviceOnSameAdviceMethod/Aspect/CalculatorLoggerAspect.php
index cf2efe9..c411751 100644
--- a/tests/Functional/AdviceBehavior/BeforeAroundAfterAdviceOnSameAdviceMethod/Aspect/CalculatorLoggerAspect.php
+++ b/tests/Functional/AdviceBehavior/BeforeAroundAfterAdviceOnSameAdviceMethod/Aspect/CalculatorLoggerAspect.php
@@ -1,4 +1,5 @@
getAdviceType();
@@ -38,7 +30,10 @@ public function logCalculation(MethodInvocation $invocation): void
}
if ($adviceType === AdviceType::Around) {
- assert($invocation instanceof AroundMethodInvocation);
+ assert(
+ $invocation instanceof AroundMethodInvocation,
+ 'The invocation must match the configured test fixture.',
+ );
$startTime = microtime(true);
$invocation->proceed();
@@ -50,6 +45,11 @@ public function logCalculation(MethodInvocation $invocation): void
}
if ($adviceType === AdviceType::After) {
+ assert(
+ $invocation instanceof \Okapi\Aop\Invocation\AfterMethodInvocation,
+ 'The invocation must match the configured test fixture.',
+ );
+ /** @var int $result */
$result = $invocation->proceed();
$message = sprintf('Calculation result: %d', $result);
diff --git a/tests/Functional/AdviceBehavior/BeforeAroundAfterAdviceOnSameAdviceMethod/BeforeAroundAfterAdviceOnSameAdviceMethodTest.php b/tests/Functional/AdviceBehavior/BeforeAroundAfterAdviceOnSameAdviceMethod/BeforeAroundAfterAdviceOnSameAdviceMethodTest.php
index c253910..46d8521 100644
--- a/tests/Functional/AdviceBehavior/BeforeAroundAfterAdviceOnSameAdviceMethod/BeforeAroundAfterAdviceOnSameAdviceMethodTest.php
+++ b/tests/Functional/AdviceBehavior/BeforeAroundAfterAdviceOnSameAdviceMethod/BeforeAroundAfterAdviceOnSameAdviceMethodTest.php
@@ -28,23 +28,23 @@ public function testBeforeAroundAfterAdviceOnSameAdviceMethod(): void
$calculator = new Calculator();
$result = $calculator->add(2, 3);
- $this->assertSame(5, $result);
+ static::assertSame(5, $result);
$logger = Logger::getInstance();
$logs = $logger->getLogs();
- $this->assertCount(3, $logs);
+ static::assertCount(3, $logs);
$log1 = $logs[0];
- $this->assertSame('Starting calculation...', $log1);
+ static::assertSame('Starting calculation...', $log1);
- $log2 = $logs[1];
+ $log2 = $logs[1];
$wildcard = 'Calculation took * seconds';
- $regex = Regex::fromWildcard($wildcard);
- $matches = $regex->matches($log2);
- $this->assertTrue($matches);
+ $regex = Regex::fromWildcard($wildcard);
+ $matches = $regex->matches($log2);
+ static::assertTrue($matches);
$log3 = $logs[2];
- $this->assertSame('Calculation result: 5', $log3);
+ static::assertSame('Calculation result: 5', $log3);
}
}
diff --git a/tests/Functional/AdviceBehavior/BeforeAroundAfterAdviceOnSameAdviceMethod/Kernel.php b/tests/Functional/AdviceBehavior/BeforeAroundAfterAdviceOnSameAdviceMethod/Kernel.php
index e00921b..2d5f064 100644
--- a/tests/Functional/AdviceBehavior/BeforeAroundAfterAdviceOnSameAdviceMethod/Kernel.php
+++ b/tests/Functional/AdviceBehavior/BeforeAroundAfterAdviceOnSameAdviceMethod/Kernel.php
@@ -10,6 +10,7 @@ class Kernel extends AopKernel
{
protected ?string $cacheDir = Util::CACHE_DIR;
+ /** @var array */
protected array $aspects = [
CalculatorLoggerAspect::class,
];
diff --git a/tests/Functional/AdviceBehavior/BeforeAroundAfterAdviceOnSameTargetMethod/Aspect/PaymentProcessorAspect.php b/tests/Functional/AdviceBehavior/BeforeAroundAfterAdviceOnSameTargetMethod/Aspect/PaymentProcessorAspect.php
index 3b0022d..e9bd555 100644
--- a/tests/Functional/AdviceBehavior/BeforeAroundAfterAdviceOnSameTargetMethod/Aspect/PaymentProcessorAspect.php
+++ b/tests/Functional/AdviceBehavior/BeforeAroundAfterAdviceOnSameTargetMethod/Aspect/PaymentProcessorAspect.php
@@ -1,4 +1,5 @@
getArgument('amount');
if ($amount < 0) {
@@ -30,49 +29,35 @@ public function checkPaymentAmount(BeforeMethodInvocation $invocation): void
}
}
- #[Around(
- class: PaymentProcessor::class,
- method: 'processPayment',
- )]
+ #[Around(class: PaymentProcessor::class, method: 'processPayment')]
public function logPayment(AroundMethodInvocation $invocation): void
{
$startTime = microtime(true);
$invocation->proceed();
- $endTime = microtime(true);
+ $endTime = microtime(true);
$elapsedTime = $endTime - $startTime;
+ /** @var float $amount */
$amount = $invocation->getArgument('amount');
- $logMessage = sprintf(
- 'Payment processed for amount $%.2f in %.2f seconds',
- $amount,
- $elapsedTime,
- );
+ $logMessage = sprintf('Payment processed for amount $%.2f in %.2f seconds', $amount, $elapsedTime);
$logger = Logger::getInstance();
$logger->log($logMessage);
}
- #[After(
- class: PaymentProcessor::class,
- method: 'processPayment',
- )]
+ #[After(class: PaymentProcessor::class, method: 'processPayment')]
public function sendEmailNotification(AfterMethodInvocation $invocation): void
{
+ /** @var bool $result */
$result = $invocation->proceed();
+ /** @var float $amount */
$amount = $invocation->getArgument('amount');
- $message = sprintf(
- 'Payment processed for amount $%.2f',
- $amount,
- );
- if ($result === true) {
- $message .= ' - Payment successful';
- } else {
- $message .= ' - Payment failed';
- }
+ $message = sprintf('Payment processed for amount $%.2f', $amount);
+ $message .= $result ? ' - Payment successful' : ' - Payment failed';
$mailQueue = MailQueue::getInstance();
$mailQueue->addMail($message);
diff --git a/tests/Functional/AdviceBehavior/BeforeAroundAfterAdviceOnSameTargetMethod/BeforeAroundAfterAdviceOnSameTargetMethodTest.php b/tests/Functional/AdviceBehavior/BeforeAroundAfterAdviceOnSameTargetMethod/BeforeAroundAfterAdviceOnSameTargetMethodTest.php
index 9bb4d61..760c79f 100644
--- a/tests/Functional/AdviceBehavior/BeforeAroundAfterAdviceOnSameTargetMethod/BeforeAroundAfterAdviceOnSameTargetMethodTest.php
+++ b/tests/Functional/AdviceBehavior/BeforeAroundAfterAdviceOnSameTargetMethod/BeforeAroundAfterAdviceOnSameTargetMethodTest.php
@@ -1,4 +1,5 @@
processPayment($amount);
} catch (InvalidArgumentException $e) {
$exceptionThrown = true;
- $this->assertSame(
- 'Invalid payment amount',
- $e->getMessage(),
- );
+ static::assertSame('Invalid payment amount', $e->getMessage());
}
- $this->assertTrue($exceptionThrown);
+ static::assertTrue($exceptionThrown);
// Test with a valid payment amount
- $amount = 420.00;
+ $amount = 420.00;
$success = $processor->processPayment($amount);
- $this->assertTrue($success);
+ static::assertTrue($success);
// Test that the log message was printed
$logger = Logger::getInstance();
- $logs = $logger->getLogs();
- $this->assertCount(1, $logs);
+ $logs = $logger->getLogs();
+ static::assertCount(1, $logs);
$logMessage = $logs[0];
- $wildcard = 'Payment processed for amount $* in * seconds';
- $regex = Regex::fromWildcard($wildcard);
- $matches = $regex->matches($logMessage);
- $this->assertTrue($matches);
+ $wildcard = 'Payment processed for amount $* in * seconds';
+ $regex = Regex::fromWildcard($wildcard);
+ $matches = $regex->matches($logMessage);
+ static::assertTrue($matches);
// Test that the email notification was sent
$mailQueue = MailQueue::getInstance();
- $mails = $mailQueue->getMails();
- $this->assertCount(1, $mails);
- $mail = $mails[0];
+ $mails = $mailQueue->getMails();
+ static::assertCount(1, $mails);
+ $mail = $mails[0];
$wildcard = 'Payment processed for amount $* - Payment successful';
- $regex = Regex::fromWildcard($wildcard);
- $matches = $regex->matches($mail);
- $this->assertTrue($matches);
+ $regex = Regex::fromWildcard($wildcard);
+ $matches = $regex->matches($mail);
+ static::assertTrue($matches);
}
}
diff --git a/tests/Functional/AdviceBehavior/BeforeAroundAfterAdviceOnSameTargetMethod/Kernel.php b/tests/Functional/AdviceBehavior/BeforeAroundAfterAdviceOnSameTargetMethod/Kernel.php
index 823018a..cadf2b3 100644
--- a/tests/Functional/AdviceBehavior/BeforeAroundAfterAdviceOnSameTargetMethod/Kernel.php
+++ b/tests/Functional/AdviceBehavior/BeforeAroundAfterAdviceOnSameTargetMethod/Kernel.php
@@ -10,6 +10,7 @@ class Kernel extends AopKernel
{
protected ?string $cacheDir = Util::CACHE_DIR;
+ /** @var array */
protected array $aspects = [
PaymentProcessorAspect::class,
];
diff --git a/tests/Functional/AdviceBehavior/BeforeAroundAfterAdviceOnSameTargetMethod/Target/PaymentProcessor.php b/tests/Functional/AdviceBehavior/BeforeAroundAfterAdviceOnSameTargetMethod/Target/PaymentProcessor.php
index 4e9a273..6f396f6 100644
--- a/tests/Functional/AdviceBehavior/BeforeAroundAfterAdviceOnSameTargetMethod/Target/PaymentProcessor.php
+++ b/tests/Functional/AdviceBehavior/BeforeAroundAfterAdviceOnSameTargetMethod/Target/PaymentProcessor.php
@@ -1,4 +1,5 @@
getClassName() === SmsSender::class) {
throw new Error('SmsSender should not be intercepted.');
diff --git a/tests/Functional/AdviceBehavior/ClassHierarchyAspect/ClassHierarchyAspectTest.php b/tests/Functional/AdviceBehavior/ClassHierarchyAspect/ClassHierarchyAspectTest.php
index b73acd4..3ef236b 100644
--- a/tests/Functional/AdviceBehavior/ClassHierarchyAspect/ClassHierarchyAspectTest.php
+++ b/tests/Functional/AdviceBehavior/ClassHierarchyAspect/ClassHierarchyAspectTest.php
@@ -27,21 +27,20 @@ public function testClassHierarchyAspect(): void
$emailSender = new EmailSender();
$recipient = 'test@test.com';
- $subject = 'Test';
- $body = 'Test';
- $result = $emailSender->send($recipient, $subject, $body);
-
- $this->assertTrue($result);
+ $subject = 'Test';
+ $body = 'Test';
+ $result = $emailSender->send($recipient, $subject, $body);
+ static::assertTrue($result);
$this->assertAspectNotApplied(SmsSender::class);
$smsSender = new SmsSender();
$recipient = '123456789';
- $message = 'Test';
- $result = $smsSender->send($recipient, $message);
+ $message = 'Test';
+ $result = $smsSender->send($recipient, $message);
// Should not throw an error
- $this->assertTrue($result);
+ static::assertTrue($result);
}
}
diff --git a/tests/Functional/AdviceBehavior/ClassHierarchyAspect/Kernel.php b/tests/Functional/AdviceBehavior/ClassHierarchyAspect/Kernel.php
index a98ee87..49a3438 100644
--- a/tests/Functional/AdviceBehavior/ClassHierarchyAspect/Kernel.php
+++ b/tests/Functional/AdviceBehavior/ClassHierarchyAspect/Kernel.php
@@ -10,6 +10,7 @@ class Kernel extends AopKernel
{
protected ?string $cacheDir = Util::CACHE_DIR;
+ /** @var array */
protected array $aspects = [
NotificationAspect::class,
];
diff --git a/tests/Functional/AdviceBehavior/ExceptionInsideAdvice/Aspect/CommentFilterAspect.php b/tests/Functional/AdviceBehavior/ExceptionInsideAdvice/Aspect/CommentFilterAspect.php
index 867d496..fc7afe5 100644
--- a/tests/Functional/AdviceBehavior/ExceptionInsideAdvice/Aspect/CommentFilterAspect.php
+++ b/tests/Functional/AdviceBehavior/ExceptionInsideAdvice/Aspect/CommentFilterAspect.php
@@ -1,4 +1,5 @@
getArgument('comment');
$inappropriateWords = ['bad', 'terrible', 'awful'];
diff --git a/tests/Functional/AdviceBehavior/ExceptionInsideAdvice/ExceptionInsideAdviceTest.php b/tests/Functional/AdviceBehavior/ExceptionInsideAdvice/ExceptionInsideAdviceTest.php
index b1f7b33..e56e921 100644
--- a/tests/Functional/AdviceBehavior/ExceptionInsideAdvice/ExceptionInsideAdviceTest.php
+++ b/tests/Functional/AdviceBehavior/ExceptionInsideAdvice/ExceptionInsideAdviceTest.php
@@ -27,7 +27,7 @@ public function testExceptionInsideAdvice(): void
$commentController = new CommentController();
$commentController->saveComment('This is a good comment');
- $this->assertTrue(true);
+ static::assertTrue(true);
$this->expectException(Exception::class);
$this->expectExceptionMessage('Comment contains inappropriate language!');
diff --git a/tests/Functional/AdviceBehavior/ExceptionInsideAdvice/Kernel.php b/tests/Functional/AdviceBehavior/ExceptionInsideAdvice/Kernel.php
index 6aeedde..4bfe036 100644
--- a/tests/Functional/AdviceBehavior/ExceptionInsideAdvice/Kernel.php
+++ b/tests/Functional/AdviceBehavior/ExceptionInsideAdvice/Kernel.php
@@ -10,6 +10,7 @@ class Kernel extends AopKernel
{
protected ?string $cacheDir = Util::CACHE_DIR;
+ /** @var array */
protected array $aspects = [
CommentFilterAspect::class,
];
diff --git a/tests/Functional/AdviceBehavior/Include/Aspect/DatabaseModifierAspect.php b/tests/Functional/AdviceBehavior/Include/Aspect/DatabaseModifierAspect.php
index 68535ca..dcb396a 100644
--- a/tests/Functional/AdviceBehavior/Include/Aspect/DatabaseModifierAspect.php
+++ b/tests/Functional/AdviceBehavior/Include/Aspect/DatabaseModifierAspect.php
@@ -1,25 +1,22 @@
-properties()->data = [
- 'd' => 4,
- 'e' => 5,
- 'f' => 6,
- ];
- }
-}
+use Okapi\Aop\Tests\Functional\AdviceBehavior\Include\Target\SecureDatabaseService;
+
+#[Aspect]
+class DatabaseModifierAspect
+{
+ #[After(class: SecureDatabaseService::class, method: 'load')]
+ public function modifyData(AfterMethodInvocation $invocation): void
+ {
+ $invocation->properties()->__set('data', [
+ 'd' => 4,
+ 'e' => 5,
+ 'f' => 6,
+ ]);
+ }
+}
diff --git a/tests/Functional/AdviceBehavior/Include/Database/data.php b/tests/Functional/AdviceBehavior/Include/Database/data.php
index 11908df..e6a11d9 100644
--- a/tests/Functional/AdviceBehavior/Include/Database/data.php
+++ b/tests/Functional/AdviceBehavior/Include/Database/data.php
@@ -1,7 +1,7 @@
- 1,
- 'b' => 2,
- 'c' => 3,
-];
+ 1,
+ 'b' => 2,
+ 'c' => 3,
+];
diff --git a/tests/Functional/AdviceBehavior/Include/IncludeTest.php b/tests/Functional/AdviceBehavior/Include/IncludeTest.php
index 2fc59cf..6269917 100644
--- a/tests/Functional/AdviceBehavior/Include/IncludeTest.php
+++ b/tests/Functional/AdviceBehavior/Include/IncludeTest.php
@@ -1,41 +1,41 @@
-assertWillBeWoven(SecureDatabaseService::class);
-
- $service = new SecureDatabaseService();
- $service->load();
-
- $data = $service->getData();
-
- $this->assertEquals(
- [
- 'd' => 4,
- 'e' => 5,
- 'f' => 6,
- ],
- $data,
- );
- }
-}
+assertWillBeWoven(SecureDatabaseService::class);
+
+ $service = new SecureDatabaseService();
+ $service->load();
+
+ $data = $service->getData();
+
+ static::assertEquals(
+ [
+ 'd' => 4,
+ 'e' => 5,
+ 'f' => 6,
+ ],
+ $data,
+ );
+ }
+}
diff --git a/tests/Functional/AdviceBehavior/Include/Kernel.php b/tests/Functional/AdviceBehavior/Include/Kernel.php
index 572338c..e177578 100644
--- a/tests/Functional/AdviceBehavior/Include/Kernel.php
+++ b/tests/Functional/AdviceBehavior/Include/Kernel.php
@@ -1,16 +1,17 @@
- */
+ protected array $aspects = [
+ DatabaseModifierAspect::class,
+ ];
+}
diff --git a/tests/Functional/AdviceBehavior/Include/Target/SecureDatabaseService.php b/tests/Functional/AdviceBehavior/Include/Target/SecureDatabaseService.php
index bc2cafa..3045520 100644
--- a/tests/Functional/AdviceBehavior/Include/Target/SecureDatabaseService.php
+++ b/tests/Functional/AdviceBehavior/Include/Target/SecureDatabaseService.php
@@ -1,26 +1,30 @@
-data === null) {
- $this->data = require dirname(__DIR__, 3) . '/AdviceBehavior/Include/Database/data.php';
- }
-
- return $this;
- }
-
- public function getData(): array
- {
- if ($this->data === null) {
- $this->load();
- }
-
- return $this->data;
- }
-}
+|null */
+ private ?array $data = null;
+
+ public function load(): self
+ {
+ if ($this->data === null) {
+ /** @var array $data */
+ $data = require dirname(__DIR__, 3) . '/AdviceBehavior/Include/Database/data.php';
+ $this->data = $data;
+ }
+
+ return $this;
+ }
+
+ /** @return array */
+ public function getData(): array
+ {
+ if ($this->data === null) {
+ $this->load();
+ }
+
+ return $this->data;
+ }
+}
diff --git a/tests/Functional/AdviceBehavior/InterfaceAdvice/Aspect/UserInterfaceAspect.php b/tests/Functional/AdviceBehavior/InterfaceAdvice/Aspect/UserInterfaceAspect.php
index 6afc879..7516770 100644
--- a/tests/Functional/AdviceBehavior/InterfaceAdvice/Aspect/UserInterfaceAspect.php
+++ b/tests/Functional/AdviceBehavior/InterfaceAdvice/Aspect/UserInterfaceAspect.php
@@ -1,4 +1,5 @@
assertWillBeWoven(User::class);
- $user = new User();
+ $user = new User();
$userName = $user->getName();
- $this->assertSame('Jane Doe', $userName);
+ static::assertSame('Jane Doe', $userName);
}
}
diff --git a/tests/Functional/AdviceBehavior/InterfaceAdvice/Kernel.php b/tests/Functional/AdviceBehavior/InterfaceAdvice/Kernel.php
index e46c4b8..8e1126d 100644
--- a/tests/Functional/AdviceBehavior/InterfaceAdvice/Kernel.php
+++ b/tests/Functional/AdviceBehavior/InterfaceAdvice/Kernel.php
@@ -10,6 +10,7 @@ class Kernel extends AopKernel
{
protected ?string $cacheDir = Util::CACHE_DIR;
+ /** @var array */
protected array $aspects = [
UserInterfaceAspect::class,
];
diff --git a/tests/Functional/AdviceBehavior/MagicConstants/Aspect/AspectOnClass.php b/tests/Functional/AdviceBehavior/MagicConstants/Aspect/AspectOnClass.php
index 5ba2059..35d1390 100644
--- a/tests/Functional/AdviceBehavior/MagicConstants/Aspect/AspectOnClass.php
+++ b/tests/Functional/AdviceBehavior/MagicConstants/Aspect/AspectOnClass.php
@@ -9,9 +9,6 @@
#[Aspect]
class AspectOnClass
{
- #[After(
- class: TargetClass::class . '*',
- method: '*'
- )]
+ #[After(class: TargetClass::class . '*', method: '*')]
public function doNothing(): void {}
}
diff --git a/tests/Functional/AdviceBehavior/MagicConstants/Aspect/AspectOnParent.php b/tests/Functional/AdviceBehavior/MagicConstants/Aspect/AspectOnParent.php
index 074e837..b328298 100644
--- a/tests/Functional/AdviceBehavior/MagicConstants/Aspect/AspectOnParent.php
+++ b/tests/Functional/AdviceBehavior/MagicConstants/Aspect/AspectOnParent.php
@@ -9,9 +9,6 @@
#[Aspect]
class AspectOnParent
{
- #[After(
- class: TargetParent::class . '*',
- method: '*',
- )]
+ #[After(class: TargetParent::class . '*', method: '*')]
public function doNothing(): void {}
}
diff --git a/tests/Functional/AdviceBehavior/MagicConstants/Aspect/AspectOnTrait.php b/tests/Functional/AdviceBehavior/MagicConstants/Aspect/AspectOnTrait.php
index b5744c2..4729617 100644
--- a/tests/Functional/AdviceBehavior/MagicConstants/Aspect/AspectOnTrait.php
+++ b/tests/Functional/AdviceBehavior/MagicConstants/Aspect/AspectOnTrait.php
@@ -9,9 +9,6 @@
#[Aspect]
class AspectOnTrait
{
- #[After(
- class: TargetTrait::class . '*',
- method: '*',
- )]
+ #[After(class: TargetTrait::class . '*', method: '*')]
public function doNothing(): void {}
}
diff --git a/tests/Functional/AdviceBehavior/MagicConstants/Kernel/KernelOnClass.php b/tests/Functional/AdviceBehavior/MagicConstants/Kernel/KernelOnClass.php
index 8b3cbba..c8c6c42 100644
--- a/tests/Functional/AdviceBehavior/MagicConstants/Kernel/KernelOnClass.php
+++ b/tests/Functional/AdviceBehavior/MagicConstants/Kernel/KernelOnClass.php
@@ -10,6 +10,7 @@ class KernelOnClass extends AopKernel
{
protected ?string $cacheDir = Util::CACHE_DIR;
+ /** @var array */
protected array $aspects = [
AspectOnClass::class,
];
diff --git a/tests/Functional/AdviceBehavior/MagicConstants/Kernel/KernelOnClassAndParent.php b/tests/Functional/AdviceBehavior/MagicConstants/Kernel/KernelOnClassAndParent.php
index bb8f78a..29aa9a8 100644
--- a/tests/Functional/AdviceBehavior/MagicConstants/Kernel/KernelOnClassAndParent.php
+++ b/tests/Functional/AdviceBehavior/MagicConstants/Kernel/KernelOnClassAndParent.php
@@ -11,6 +11,7 @@ class KernelOnClassAndParent extends AopKernel
{
protected ?string $cacheDir = Util::CACHE_DIR;
+ /** @var array */
protected array $aspects = [
AspectOnClass::class,
AspectOnParent::class,
diff --git a/tests/Functional/AdviceBehavior/MagicConstants/Kernel/KernelOnClassAndParentAndTrait.php b/tests/Functional/AdviceBehavior/MagicConstants/Kernel/KernelOnClassAndParentAndTrait.php
index cf41055..5fdef18 100644
--- a/tests/Functional/AdviceBehavior/MagicConstants/Kernel/KernelOnClassAndParentAndTrait.php
+++ b/tests/Functional/AdviceBehavior/MagicConstants/Kernel/KernelOnClassAndParentAndTrait.php
@@ -12,6 +12,7 @@ class KernelOnClassAndParentAndTrait extends AopKernel
{
protected ?string $cacheDir = Util::CACHE_DIR;
+ /** @var array */
protected array $aspects = [
AspectOnClass::class,
AspectOnParent::class,
diff --git a/tests/Functional/AdviceBehavior/MagicConstants/Kernel/KernelOnClassAndTrait.php b/tests/Functional/AdviceBehavior/MagicConstants/Kernel/KernelOnClassAndTrait.php
index 45b602d..d0d11d4 100644
--- a/tests/Functional/AdviceBehavior/MagicConstants/Kernel/KernelOnClassAndTrait.php
+++ b/tests/Functional/AdviceBehavior/MagicConstants/Kernel/KernelOnClassAndTrait.php
@@ -11,6 +11,7 @@ class KernelOnClassAndTrait extends AopKernel
{
protected ?string $cacheDir = Util::CACHE_DIR;
+ /** @var array */
protected array $aspects = [
AspectOnClass::class,
AspectOnTrait::class,
diff --git a/tests/Functional/AdviceBehavior/MagicConstants/Kernel/KernelOnParent.php b/tests/Functional/AdviceBehavior/MagicConstants/Kernel/KernelOnParent.php
index 561576c..3457a87 100644
--- a/tests/Functional/AdviceBehavior/MagicConstants/Kernel/KernelOnParent.php
+++ b/tests/Functional/AdviceBehavior/MagicConstants/Kernel/KernelOnParent.php
@@ -10,6 +10,7 @@ class KernelOnParent extends AopKernel
{
protected ?string $cacheDir = Util::CACHE_DIR;
+ /** @var array */
protected array $aspects = [
AspectOnParent::class,
];
diff --git a/tests/Functional/AdviceBehavior/MagicConstants/Kernel/KernelOnParentAndTrait.php b/tests/Functional/AdviceBehavior/MagicConstants/Kernel/KernelOnParentAndTrait.php
index fc3ea69..4b6fc69 100644
--- a/tests/Functional/AdviceBehavior/MagicConstants/Kernel/KernelOnParentAndTrait.php
+++ b/tests/Functional/AdviceBehavior/MagicConstants/Kernel/KernelOnParentAndTrait.php
@@ -11,6 +11,7 @@ class KernelOnParentAndTrait extends AopKernel
{
protected ?string $cacheDir = Util::CACHE_DIR;
+ /** @var array */
protected array $aspects = [
AspectOnParent::class,
AspectOnTrait::class,
diff --git a/tests/Functional/AdviceBehavior/MagicConstants/Kernel/KernelOnTrait.php b/tests/Functional/AdviceBehavior/MagicConstants/Kernel/KernelOnTrait.php
index 0d9f100..85a3abe 100644
--- a/tests/Functional/AdviceBehavior/MagicConstants/Kernel/KernelOnTrait.php
+++ b/tests/Functional/AdviceBehavior/MagicConstants/Kernel/KernelOnTrait.php
@@ -10,6 +10,7 @@ class KernelOnTrait extends AopKernel
{
protected ?string $cacheDir = Util::CACHE_DIR;
+ /** @var array */
protected array $aspects = [
AspectOnTrait::class,
];
diff --git a/tests/Functional/AdviceBehavior/MagicConstants/MagicConstantsTest.php b/tests/Functional/AdviceBehavior/MagicConstants/MagicConstantsTest.php
index 9493967..4a08a22 100644
--- a/tests/Functional/AdviceBehavior/MagicConstants/MagicConstantsTest.php
+++ b/tests/Functional/AdviceBehavior/MagicConstants/MagicConstantsTest.php
@@ -3,19 +3,19 @@
namespace Okapi\Aop\Tests\Functional\AdviceBehavior\MagicConstants;
use Okapi\Aop\Tests\ClassLoaderMockTrait;
-use Okapi\Aop\Tests\Functional\AdviceBehavior\MagicConstants\Kernel\{KernelOnClass,
- KernelOnClassAndParent,
- KernelOnClassAndParentAndTrait,
- KernelOnClassAndTrait,
- KernelOnParent,
- KernelOnParentAndTrait,
- KernelOnTrait};
-use Okapi\Aop\Tests\Functional\AdviceBehavior\MagicConstants\Target\{TargetClass,
- TargetClass82,
- TargetParent,
- TargetParent82,
- TargetTrait,
- TargetTrait82};
+use Okapi\Aop\Tests\Functional\AdviceBehavior\MagicConstants\Kernel\KernelOnClass;
+use Okapi\Aop\Tests\Functional\AdviceBehavior\MagicConstants\Kernel\KernelOnClassAndParent;
+use Okapi\Aop\Tests\Functional\AdviceBehavior\MagicConstants\Kernel\KernelOnClassAndParentAndTrait;
+use Okapi\Aop\Tests\Functional\AdviceBehavior\MagicConstants\Kernel\KernelOnClassAndTrait;
+use Okapi\Aop\Tests\Functional\AdviceBehavior\MagicConstants\Kernel\KernelOnParent;
+use Okapi\Aop\Tests\Functional\AdviceBehavior\MagicConstants\Kernel\KernelOnParentAndTrait;
+use Okapi\Aop\Tests\Functional\AdviceBehavior\MagicConstants\Kernel\KernelOnTrait;
+use Okapi\Aop\Tests\Functional\AdviceBehavior\MagicConstants\Target\TargetClass;
+use Okapi\Aop\Tests\Functional\AdviceBehavior\MagicConstants\Target\TargetClass82;
+use Okapi\Aop\Tests\Functional\AdviceBehavior\MagicConstants\Target\TargetParent;
+use Okapi\Aop\Tests\Functional\AdviceBehavior\MagicConstants\Target\TargetParent82;
+use Okapi\Aop\Tests\Functional\AdviceBehavior\MagicConstants\Target\TargetTrait;
+use Okapi\Aop\Tests\Functional\AdviceBehavior\MagicConstants\Target\TargetTrait82;
use Okapi\Aop\Tests\Util;
use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
use PHPUnit\Framework\ExpectationFailedException;
@@ -32,19 +32,24 @@ class MagicConstantsTest extends TestCase
{
use ClassLoaderMockTrait;
+ /** @var class-string */
private string $targetClass = TargetClass::class;
+ /** @var class-string */
private string $targetParentClass = TargetParent::class;
- private const PREFIX_TARGET_PATH = '/tests/Functional/AdviceBehavior/MagicConstants/Target';
+ private const PREFIX_TARGET_PATH = '/tests/Functional/AdviceBehavior/MagicConstants/Target';
+
private string $prefixTargetClassPath = self::PREFIX_TARGET_PATH . '/TargetClass.php';
private string $prefixTargetTraitPath = self::PREFIX_TARGET_PATH . '/TargetTrait.php';
private string $prefixTargetParentPath = self::PREFIX_TARGET_PATH . '/TargetParent.php';
- private const NAMESPACE_TARGET = 'Okapi\Aop\Tests\Functional\AdviceBehavior\MagicConstants\Target';
+ private const NAMESPACE_TARGET = 'Okapi\Aop\Tests\Functional\AdviceBehavior\MagicConstants\Target';
+
private string $namespaceTargetClass = TargetClass::class;
private string $namespaceTargetTrait = TargetTrait::class;
private string $namespaceTargetParent = TargetParent::class;
+ /** @param non-empty-string $name */
public function __construct(string $name)
{
parent::__construct($name);
@@ -66,7 +71,7 @@ public function __construct(string $name)
public function testMagicConstantsWithoutAop(): void
{
- $this->test(new $this->targetClass);
+ $this->test($this->newTarget());
}
// Class
@@ -76,7 +81,7 @@ public function testMagicConstantsWithAopOnClass(): void
KernelOnClass::init();
$this->assertWillBeWoven($this->targetClass);
- $this->test(new $this->targetClass);
+ $this->test($this->newTarget());
}
// Class (Cached)
@@ -85,7 +90,7 @@ public function testMagicConstantsWithAopOnClassCached(): void
KernelOnClass::init();
$this->assertAspectLoadedFromCache($this->targetClass);
- $this->test(new $this->targetClass);
+ $this->test($this->newTarget());
}
// Parent
@@ -96,7 +101,7 @@ public function testMagicConstantsWithAopOnParent(): void
$this->assertWillBeWoven($this->targetParentClass);
$this->assertWillBeWoven($this->targetClass);
- $this->test(new $this->targetClass, $this->namespaceTargetParent);
+ $this->test($this->newTarget(), $this->namespaceTargetParent);
}
// Parent (Cached)
@@ -106,7 +111,7 @@ public function testMagicConstantsWithAopOnParentCached(): void
$this->assertAspectLoadedFromCache($this->targetParentClass);
$this->assertAspectLoadedFromCache($this->targetClass);
- $this->test(new $this->targetClass, $this->namespaceTargetParent);
+ $this->test($this->newTarget(), $this->namespaceTargetParent);
}
// Trait
@@ -116,7 +121,7 @@ public function testMagicConstantsWithAopOnTrait(): void
KernelOnTrait::init();
$this->assertWillBeWoven($this->targetClass);
- $this->test(new $this->targetClass);
+ $this->test($this->newTarget());
}
// Trait (Cached)
@@ -125,7 +130,7 @@ public function testMagicConstantsWithAopOnTraitCached(): void
KernelOnTrait::init();
$this->assertAspectLoadedFromCache($this->targetClass);
- $this->test(new $this->targetClass);
+ $this->test($this->newTarget());
}
// Class + Parent
@@ -136,7 +141,7 @@ public function testMagicConstantsWithAopOnClassAndParent(): void
$this->assertWillBeWoven($this->targetParentClass);
$this->assertWillBeWoven($this->targetClass);
- $this->test(new $this->targetClass, $this->namespaceTargetParent);
+ $this->test($this->newTarget(), $this->namespaceTargetParent);
}
// Class + Parent (Cached)
@@ -146,7 +151,7 @@ public function testMagicConstantsWithAopOnClassAndParentCached(): void
$this->assertAspectLoadedFromCache($this->targetParentClass);
$this->assertAspectLoadedFromCache($this->targetClass);
- $this->test(new $this->targetClass, $this->namespaceTargetParent);
+ $this->test($this->newTarget(), $this->namespaceTargetParent);
}
// Class + Trait
@@ -156,7 +161,7 @@ public function testMagicConstantsWithAopOnClassAndTrait(): void
KernelOnClassAndTrait::init();
$this->assertWillBeWoven($this->targetClass);
- $this->test(new $this->targetClass);
+ $this->test($this->newTarget());
}
// Class + Trait (Cached)
@@ -165,7 +170,7 @@ public function testMagicConstantsWithAopOnClassAndTraitCached(): void
KernelOnClassAndTrait::init();
$this->assertAspectLoadedFromCache($this->targetClass);
- $this->test(new $this->targetClass);
+ $this->test($this->newTarget());
}
// Parent + Trait
@@ -176,7 +181,7 @@ public function testMagicConstantsWithAopOnParentAndTrait(): void
$this->assertWillBeWoven($this->targetParentClass);
$this->assertWillBeWoven($this->targetClass);
- $this->test(new $this->targetClass, $this->namespaceTargetParent);
+ $this->test($this->newTarget(), $this->namespaceTargetParent);
}
// Parent + Trait (Cached)
@@ -186,7 +191,7 @@ public function testMagicConstantsWithAopOnParentAndTraitCached(): void
$this->assertAspectLoadedFromCache($this->targetParentClass);
$this->assertAspectLoadedFromCache($this->targetClass);
- $this->test(new $this->targetClass, $this->namespaceTargetParent);
+ $this->test($this->newTarget(), $this->namespaceTargetParent);
}
// Class + Parent + Trait
@@ -197,7 +202,7 @@ public function testMagicConstantsWithAopOnClassAndParentAndTrait(): void
$this->assertWillBeWoven($this->targetParentClass);
$this->assertWillBeWoven($this->targetClass);
- $this->test(new $this->targetClass, $this->namespaceTargetParent);
+ $this->test($this->newTarget(), $this->namespaceTargetParent);
}
// Class + Parent + Trait (Cached)
@@ -207,20 +212,18 @@ public function testMagicConstantsWithAopOnClassAndParentAndTraitCached(): void
$this->assertAspectLoadedFromCache($this->targetParentClass);
$this->assertAspectLoadedFromCache($this->targetClass);
- $this->test(new $this->targetClass, $this->namespaceTargetParent);
+ $this->test($this->newTarget(), $this->namespaceTargetParent);
}
- private function test(
- TargetClass|TargetClass82 $target,
- ?string $staticClass = null
- ): void {
+ private function test(TargetClass|TargetClass82 $target, ?string $staticClass = null): void
+ {
if (!$staticClass) {
$staticClass = $this->namespaceTargetClass;
}
$constantExceptions = $this->testConstants($target);
$propertyExceptions = $this->testProperty($target);
- $methodExceptions = $this->testMethod($target, $staticClass);
+ $methodExceptions = $this->testMethod($target, $staticClass);
$exceptions = [
...$constantExceptions,
@@ -229,56 +232,60 @@ private function test(
];
if ($exceptions) {
- $this->markTestIncomplete(
- 'Some tests skipped: ' .
- 'https://github.com/okapi-web/php-aop/issues/69#issuecomment-1806817698'
- );
+ $this->markTestIncomplete('Some tests skipped: '
+ . 'https://github.com/okapi-web/php-aop/issues/69#issuecomment-1806817698');
}
}
+ private function newTarget(): TargetClass|TargetClass82
+ {
+ return $this->targetClass === TargetClass82::class ? new TargetClass82() : new TargetClass();
+ }
+
+ /** @return list */
private function testConstants(TargetClass|TargetClass82 $target): array
{
$exceptions = [];
$expected = [
- 'dir' => $this->np($this->rootPath() . self::PREFIX_TARGET_PATH),
- 'file' => $this->np($this->rootPath() . $this->prefixTargetClassPath),
- 'function' => '',
- 'class' => $this->namespaceTargetClass,
- 'trait' => '',
- 'method' => '',
- 'namespace' => self::NAMESPACE_TARGET,
- 'targetClassClass' => $this->namespaceTargetClass,
- 'targetTraitClass' => $this->namespaceTargetTrait,
+ 'dir' => $this->np($this->rootPath() . self::PREFIX_TARGET_PATH),
+ 'file' => $this->np($this->rootPath() . $this->prefixTargetClassPath),
+ 'function' => '',
+ 'class' => $this->namespaceTargetClass,
+ 'trait' => '',
+ 'method' => '',
+ 'namespace' => self::NAMESPACE_TARGET,
+ 'targetClassClass' => $this->namespaceTargetClass,
+ 'targetTraitClass' => $this->namespaceTargetTrait,
'targetParentClass' => $this->namespaceTargetParent,
- 'selfClass' => $this->namespaceTargetClass,
+ 'selfClass' => $this->namespaceTargetClass,
];
// region Class
- $this->assertSame($expected, $target::CONST);
+ static::assertSame($expected, $target::CONST);
// endregion
// region Parent
- $expected['file'] = $this->np($this->rootPath() . $this->prefixTargetParentPath);
- $expected['class'] = $this->namespaceTargetParent;
+ $expected['file'] = $this->np($this->rootPath() . $this->prefixTargetParentPath);
+ $expected['class'] = $this->namespaceTargetParent;
$expected['selfClass'] = $this->namespaceTargetParent;
- $this->assertSame($expected, $target::PARENT_CONST);
+ static::assertSame($expected, $target::PARENT_CONST);
// endregion
// region Trait
// Only PHP >= 8.2 has trait constants
- if (version_compare(PHP_VERSION, '8.2.0', '>=')) {
- $expected['file'] = $this->np($this->rootPath() . $this->prefixTargetTraitPath);
+ if ($target instanceof TargetClass82) {
+ $expected['file'] = $this->np($this->rootPath() . $this->prefixTargetTraitPath);
$expected['trait'] = $this->namespaceTargetTrait;
try {
- $this->assertSame($expected, $target::TRAIT_CONST);
+ static::assertSame($expected, $target::TRAIT_CONST);
} catch (ExpectationFailedException $e) {
$exceptions[] = $e;
}
@@ -289,50 +296,51 @@ private function testConstants(TargetClass|TargetClass82 $target): array
return $exceptions;
}
+ /** @return list */
private function testProperty(TargetClass|TargetClass82 $target): array
{
$exceptions = [];
$expected = [
- 'dir' => $this->np($this->rootPath() . self::PREFIX_TARGET_PATH),
- 'file' => $this->np($this->rootPath() . $this->prefixTargetClassPath),
- 'function' => '',
- 'class' => $this->namespaceTargetClass,
- 'trait' => '',
- 'method' => '',
- 'namespace' => self::NAMESPACE_TARGET,
- 'targetClassClass' => $this->namespaceTargetClass,
- 'targetTraitClass' => $this->namespaceTargetTrait,
+ 'dir' => $this->np($this->rootPath() . self::PREFIX_TARGET_PATH),
+ 'file' => $this->np($this->rootPath() . $this->prefixTargetClassPath),
+ 'function' => '',
+ 'class' => $this->namespaceTargetClass,
+ 'trait' => '',
+ 'method' => '',
+ 'namespace' => self::NAMESPACE_TARGET,
+ 'targetClassClass' => $this->namespaceTargetClass,
+ 'targetTraitClass' => $this->namespaceTargetTrait,
'targetParentClass' => $this->namespaceTargetParent,
- 'selfClass' => $this->namespaceTargetClass,
+ 'selfClass' => $this->namespaceTargetClass,
];
// region Class
- $this->assertSame($expected, $target->property);
- $this->assertSame($expected, $target::$staticProperty);
+ static::assertSame($expected, $target->property);
+ static::assertSame($expected, $target::$staticProperty);
// endregion
// region Parent
- $expected['file'] = $this->np($this->rootPath() . $this->prefixTargetParentPath);
- $expected['class'] = $this->namespaceTargetParent;
+ $expected['file'] = $this->np($this->rootPath() . $this->prefixTargetParentPath);
+ $expected['class'] = $this->namespaceTargetParent;
$expected['selfClass'] = $this->namespaceTargetParent;
- $this->assertSame($expected, $target->parentProperty);
- $this->assertSame($expected, $target::$parentStaticProperty);
+ static::assertSame($expected, $target->parentProperty);
+ static::assertSame($expected, $target::$parentStaticProperty);
// endregion
// region Trait
- $expected['file'] = $this->np($this->rootPath() . $this->prefixTargetTraitPath);
+ $expected['file'] = $this->np($this->rootPath() . $this->prefixTargetTraitPath);
$expected['trait'] = $this->namespaceTargetTrait;
try {
- $this->assertSame($expected, $target->traitProperty);
- $this->assertSame($expected, $target::$traitStaticProperty);
+ static::assertSame($expected, $target->traitProperty);
+ static::assertSame($expected, $target::$traitStaticProperty);
} catch (ExpectationFailedException $e) {
$exceptions[] = $e;
}
@@ -342,10 +350,9 @@ private function testProperty(TargetClass|TargetClass82 $target): array
return $exceptions;
}
- private function testMethod(
- TargetClass|TargetClass82 $target,
- ?string $staticClass
- ): array {
+ /** @return list */
+ private function testMethod(TargetClass|TargetClass82 $target, ?string $staticClass): array
+ {
if (!$staticClass) {
$staticClass = $this->namespaceTargetClass;
}
@@ -353,63 +360,63 @@ private function testMethod(
$exceptions = [];
$expected = [
- 'dir' => $this->np($this->rootPath() . self::PREFIX_TARGET_PATH),
- 'file' => $this->np($this->rootPath() . $this->prefixTargetClassPath),
- 'function' => 'method',
- 'class' => $this->namespaceTargetClass,
- 'trait' => '',
- 'method' => $this->namespaceTargetClass . '::method',
- 'namespace' => self::NAMESPACE_TARGET,
- 'targetClassClass' => $this->namespaceTargetClass,
- 'targetTraitClass' => $this->namespaceTargetTrait,
+ 'dir' => $this->np($this->rootPath() . self::PREFIX_TARGET_PATH),
+ 'file' => $this->np($this->rootPath() . $this->prefixTargetClassPath),
+ 'function' => 'method',
+ 'class' => $this->namespaceTargetClass,
+ 'trait' => '',
+ 'method' => $this->namespaceTargetClass . '::method',
+ 'namespace' => self::NAMESPACE_TARGET,
+ 'targetClassClass' => $this->namespaceTargetClass,
+ 'targetTraitClass' => $this->namespaceTargetTrait,
'targetParentClass' => $this->namespaceTargetParent,
- 'selfClass' => $this->namespaceTargetClass,
- 'staticClass' => $this->namespaceTargetClass,
+ 'selfClass' => $this->namespaceTargetClass,
+ 'staticClass' => $this->namespaceTargetClass,
];
// region Class
- $this->assertSame($expected, $target->method());
+ static::assertSame($expected, $target->method());
$expected['function'] = 'staticMethod';
- $expected['method'] = $this->namespaceTargetClass . '::staticMethod';
+ $expected['method'] = $this->namespaceTargetClass . '::staticMethod';
- $this->assertSame($expected, $target::staticMethod());
+ static::assertSame($expected, $target::staticMethod());
// endregion
// region Parent
- $expected['file'] = $this->np($this->rootPath() . $this->prefixTargetParentPath);
- $expected['function'] = 'parentMethod';
- $expected['class'] = $this->namespaceTargetParent;
- $expected['method'] = $this->namespaceTargetParent . '::parentMethod';
+ $expected['file'] = $this->np($this->rootPath() . $this->prefixTargetParentPath);
+ $expected['function'] = 'parentMethod';
+ $expected['class'] = $this->namespaceTargetParent;
+ $expected['method'] = $this->namespaceTargetParent . '::parentMethod';
$expected['selfClass'] = $this->namespaceTargetParent;
- $this->assertSame($expected, $target->parentMethod());
+ static::assertSame($expected, $target->parentMethod());
- $expected['function'] = 'parentStaticMethod';
- $expected['method'] = $this->namespaceTargetParent . '::parentStaticMethod';
+ $expected['function'] = 'parentStaticMethod';
+ $expected['method'] = $this->namespaceTargetParent . '::parentStaticMethod';
$expected['staticClass'] = $staticClass;
- $this->assertSame($expected, $target::parentStaticMethod());
+ static::assertSame($expected, $target::parentStaticMethod());
// endregion
// region Trait
try {
- $expected['file'] = $this->np($this->rootPath() . $this->prefixTargetTraitPath);
+ $expected['file'] = $this->np($this->rootPath() . $this->prefixTargetTraitPath);
$expected['function'] = 'traitMethod';
- $expected['trait'] = $this->namespaceTargetTrait;
- $expected['method'] = $this->namespaceTargetTrait . '::traitMethod';
+ $expected['trait'] = $this->namespaceTargetTrait;
+ $expected['method'] = $this->namespaceTargetTrait . '::traitMethod';
- $this->assertSame($expected, $target->traitMethod());
+ static::assertSame($expected, $target->traitMethod());
$expected['function'] = 'traitStaticMethod';
- $expected['method'] = $this->namespaceTargetTrait . '::traitStaticMethod';
+ $expected['method'] = $this->namespaceTargetTrait . '::traitStaticMethod';
- $this->assertSame($expected, $target::traitStaticMethod());
+ static::assertSame($expected, $target::traitStaticMethod());
} catch (ExpectationFailedException $e) {
$exceptions[] = $e;
}
diff --git a/tests/Functional/AdviceBehavior/MagicConstants/Target/TargetClass.php b/tests/Functional/AdviceBehavior/MagicConstants/Target/TargetClass.php
index 7606a8b..45f2987 100644
--- a/tests/Functional/AdviceBehavior/MagicConstants/Target/TargetClass.php
+++ b/tests/Functional/AdviceBehavior/MagicConstants/Target/TargetClass.php
@@ -7,80 +7,84 @@ class TargetClass extends TargetParent
use TargetTrait;
public const CONST = [
- 'dir' => __DIR__,
- 'file' => __FILE__,
- 'function' => __FUNCTION__,
- 'class' => __CLASS__,
- 'trait' => __TRAIT__,
- 'method' => __METHOD__,
- 'namespace' => __NAMESPACE__,
- 'targetClassClass' => TargetClass::class,
- 'targetTraitClass' => TargetTrait::class,
+ 'dir' => __DIR__,
+ 'file' => __FILE__,
+ 'function' => __FUNCTION__,
+ 'class' => __CLASS__,
+ 'trait' => __TRAIT__,
+ 'method' => __METHOD__,
+ 'namespace' => __NAMESPACE__,
+ 'targetClassClass' => TargetClass::class,
+ 'targetTraitClass' => TargetTrait::class,
'targetParentClass' => TargetParent::class,
- 'selfClass' => self::class,
+ 'selfClass' => self::class,
];
+ /** @var array */
public array $property = [
- 'dir' => __DIR__,
- 'file' => __FILE__,
- 'function' => __FUNCTION__,
- 'class' => __CLASS__,
- 'trait' => __TRAIT__,
- 'method' => __METHOD__,
- 'namespace' => __NAMESPACE__,
- 'targetClassClass' => TargetClass::class,
- 'targetTraitClass' => TargetTrait::class,
+ 'dir' => __DIR__,
+ 'file' => __FILE__,
+ 'function' => __FUNCTION__,
+ 'class' => __CLASS__,
+ 'trait' => __TRAIT__,
+ 'method' => __METHOD__,
+ 'namespace' => __NAMESPACE__,
+ 'targetClassClass' => TargetClass::class,
+ 'targetTraitClass' => TargetTrait::class,
'targetParentClass' => TargetParent::class,
- 'selfClass' => self::class,
+ 'selfClass' => self::class,
];
+ /** @var array */
public static array $staticProperty = [
- 'dir' => __DIR__,
- 'file' => __FILE__,
- 'function' => __FUNCTION__,
- 'class' => __CLASS__,
- 'trait' => __TRAIT__,
- 'method' => __METHOD__,
- 'namespace' => __NAMESPACE__,
- 'targetClassClass' => TargetClass::class,
- 'targetTraitClass' => TargetTrait::class,
+ 'dir' => __DIR__,
+ 'file' => __FILE__,
+ 'function' => __FUNCTION__,
+ 'class' => __CLASS__,
+ 'trait' => __TRAIT__,
+ 'method' => __METHOD__,
+ 'namespace' => __NAMESPACE__,
+ 'targetClassClass' => TargetClass::class,
+ 'targetTraitClass' => TargetTrait::class,
'targetParentClass' => TargetParent::class,
- 'selfClass' => self::class,
+ 'selfClass' => self::class,
];
+ /** @return array */
public function method(): array
{
return [
- 'dir' => __DIR__,
- 'file' => __FILE__,
- 'function' => __FUNCTION__,
- 'class' => __CLASS__,
- 'trait' => __TRAIT__,
- 'method' => __METHOD__,
- 'namespace' => __NAMESPACE__,
- 'targetClassClass' => TargetClass::class,
- 'targetTraitClass' => TargetTrait::class,
+ 'dir' => __DIR__,
+ 'file' => __FILE__,
+ 'function' => __FUNCTION__,
+ 'class' => __CLASS__,
+ 'trait' => __TRAIT__,
+ 'method' => __METHOD__,
+ 'namespace' => __NAMESPACE__,
+ 'targetClassClass' => TargetClass::class,
+ 'targetTraitClass' => TargetTrait::class,
'targetParentClass' => TargetParent::class,
- 'selfClass' => self::class,
- 'staticClass' => static::class,
+ 'selfClass' => self::class,
+ 'staticClass' => static::class,
];
}
+ /** @return array */
public static function staticMethod(): array
{
return [
- 'dir' => __DIR__,
- 'file' => __FILE__,
- 'function' => __FUNCTION__,
- 'class' => __CLASS__,
- 'trait' => __TRAIT__,
- 'method' => __METHOD__,
- 'namespace' => __NAMESPACE__,
- 'targetClassClass' => TargetClass::class,
- 'targetTraitClass' => TargetTrait::class,
+ 'dir' => __DIR__,
+ 'file' => __FILE__,
+ 'function' => __FUNCTION__,
+ 'class' => __CLASS__,
+ 'trait' => __TRAIT__,
+ 'method' => __METHOD__,
+ 'namespace' => __NAMESPACE__,
+ 'targetClassClass' => TargetClass::class,
+ 'targetTraitClass' => TargetTrait::class,
'targetParentClass' => TargetParent::class,
- 'selfClass' => self::class,
- 'staticClass' => static::class,
+ 'selfClass' => self::class,
+ 'staticClass' => static::class,
];
}
}
diff --git a/tests/Functional/AdviceBehavior/MagicConstants/Target/TargetClass82.php b/tests/Functional/AdviceBehavior/MagicConstants/Target/TargetClass82.php
index b5225e0..f88582e 100644
--- a/tests/Functional/AdviceBehavior/MagicConstants/Target/TargetClass82.php
+++ b/tests/Functional/AdviceBehavior/MagicConstants/Target/TargetClass82.php
@@ -7,80 +7,84 @@ class TargetClass82 extends TargetParent82
use TargetTrait82;
public const CONST = [
- 'dir' => __DIR__,
- 'file' => __FILE__,
- 'function' => __FUNCTION__,
- 'class' => __CLASS__,
- 'trait' => __TRAIT__,
- 'method' => __METHOD__,
- 'namespace' => __NAMESPACE__,
- 'targetClassClass' => TargetClass82::class,
- 'targetTraitClass' => TargetTrait82::class,
+ 'dir' => __DIR__,
+ 'file' => __FILE__,
+ 'function' => __FUNCTION__,
+ 'class' => __CLASS__,
+ 'trait' => __TRAIT__,
+ 'method' => __METHOD__,
+ 'namespace' => __NAMESPACE__,
+ 'targetClassClass' => TargetClass82::class,
+ 'targetTraitClass' => TargetTrait82::class,
'targetParentClass' => TargetParent82::class,
- 'selfClass' => self::class,
+ 'selfClass' => self::class,
];
+ /** @var array */
public array $property = [
- 'dir' => __DIR__,
- 'file' => __FILE__,
- 'function' => __FUNCTION__,
- 'class' => __CLASS__,
- 'trait' => __TRAIT__,
- 'method' => __METHOD__,
- 'namespace' => __NAMESPACE__,
- 'targetClassClass' => TargetClass82::class,
- 'targetTraitClass' => TargetTrait82::class,
+ 'dir' => __DIR__,
+ 'file' => __FILE__,
+ 'function' => __FUNCTION__,
+ 'class' => __CLASS__,
+ 'trait' => __TRAIT__,
+ 'method' => __METHOD__,
+ 'namespace' => __NAMESPACE__,
+ 'targetClassClass' => TargetClass82::class,
+ 'targetTraitClass' => TargetTrait82::class,
'targetParentClass' => TargetParent82::class,
- 'selfClass' => self::class,
+ 'selfClass' => self::class,
];
+ /** @var array */
public static array $staticProperty = [
- 'dir' => __DIR__,
- 'file' => __FILE__,
- 'function' => __FUNCTION__,
- 'class' => __CLASS__,
- 'trait' => __TRAIT__,
- 'method' => __METHOD__,
- 'namespace' => __NAMESPACE__,
- 'targetClassClass' => TargetClass82::class,
- 'targetTraitClass' => TargetTrait82::class,
+ 'dir' => __DIR__,
+ 'file' => __FILE__,
+ 'function' => __FUNCTION__,
+ 'class' => __CLASS__,
+ 'trait' => __TRAIT__,
+ 'method' => __METHOD__,
+ 'namespace' => __NAMESPACE__,
+ 'targetClassClass' => TargetClass82::class,
+ 'targetTraitClass' => TargetTrait82::class,
'targetParentClass' => TargetParent82::class,
- 'selfClass' => self::class,
+ 'selfClass' => self::class,
];
+ /** @return array */
public function method(): array
{
return [
- 'dir' => __DIR__,
- 'file' => __FILE__,
- 'function' => __FUNCTION__,
- 'class' => __CLASS__,
- 'trait' => __TRAIT__,
- 'method' => __METHOD__,
- 'namespace' => __NAMESPACE__,
- 'targetClassClass' => TargetClass82::class,
- 'targetTraitClass' => TargetTrait82::class,
+ 'dir' => __DIR__,
+ 'file' => __FILE__,
+ 'function' => __FUNCTION__,
+ 'class' => __CLASS__,
+ 'trait' => __TRAIT__,
+ 'method' => __METHOD__,
+ 'namespace' => __NAMESPACE__,
+ 'targetClassClass' => TargetClass82::class,
+ 'targetTraitClass' => TargetTrait82::class,
'targetParentClass' => TargetParent82::class,
- 'selfClass' => self::class,
- 'staticClass' => static::class,
+ 'selfClass' => self::class,
+ 'staticClass' => static::class,
];
}
+ /** @return array */
public static function staticMethod(): array
{
return [
- 'dir' => __DIR__,
- 'file' => __FILE__,
- 'function' => __FUNCTION__,
- 'class' => __CLASS__,
- 'trait' => __TRAIT__,
- 'method' => __METHOD__,
- 'namespace' => __NAMESPACE__,
- 'targetClassClass' => TargetClass82::class,
- 'targetTraitClass' => TargetTrait82::class,
+ 'dir' => __DIR__,
+ 'file' => __FILE__,
+ 'function' => __FUNCTION__,
+ 'class' => __CLASS__,
+ 'trait' => __TRAIT__,
+ 'method' => __METHOD__,
+ 'namespace' => __NAMESPACE__,
+ 'targetClassClass' => TargetClass82::class,
+ 'targetTraitClass' => TargetTrait82::class,
'targetParentClass' => TargetParent82::class,
- 'selfClass' => self::class,
- 'staticClass' => static::class,
+ 'selfClass' => self::class,
+ 'staticClass' => static::class,
];
}
}
diff --git a/tests/Functional/AdviceBehavior/MagicConstants/Target/TargetParent.php b/tests/Functional/AdviceBehavior/MagicConstants/Target/TargetParent.php
index 47e4dee..5eebcda 100644
--- a/tests/Functional/AdviceBehavior/MagicConstants/Target/TargetParent.php
+++ b/tests/Functional/AdviceBehavior/MagicConstants/Target/TargetParent.php
@@ -5,80 +5,84 @@
class TargetParent
{
public const PARENT_CONST = [
- 'dir' => __DIR__,
- 'file' => __FILE__,
- 'function' => __FUNCTION__,
- 'class' => __CLASS__,
- 'trait' => __TRAIT__,
- 'method' => __METHOD__,
- 'namespace' => __NAMESPACE__,
- 'targetClassClass' => TargetClass::class,
- 'targetTraitClass' => TargetTrait::class,
+ 'dir' => __DIR__,
+ 'file' => __FILE__,
+ 'function' => __FUNCTION__,
+ 'class' => __CLASS__,
+ 'trait' => __TRAIT__,
+ 'method' => __METHOD__,
+ 'namespace' => __NAMESPACE__,
+ 'targetClassClass' => TargetClass::class,
+ 'targetTraitClass' => TargetTrait::class,
'targetParentClass' => TargetParent::class,
- 'selfClass' => self::class,
+ 'selfClass' => self::class,
];
+ /** @var array */
public array $parentProperty = [
- 'dir' => __DIR__,
- 'file' => __FILE__,
- 'function' => __FUNCTION__,
- 'class' => __CLASS__,
- 'trait' => __TRAIT__,
- 'method' => __METHOD__,
- 'namespace' => __NAMESPACE__,
- 'targetClassClass' => TargetClass::class,
- 'targetTraitClass' => TargetTrait::class,
+ 'dir' => __DIR__,
+ 'file' => __FILE__,
+ 'function' => __FUNCTION__,
+ 'class' => __CLASS__,
+ 'trait' => __TRAIT__,
+ 'method' => __METHOD__,
+ 'namespace' => __NAMESPACE__,
+ 'targetClassClass' => TargetClass::class,
+ 'targetTraitClass' => TargetTrait::class,
'targetParentClass' => TargetParent::class,
- 'selfClass' => self::class,
+ 'selfClass' => self::class,
];
+ /** @var array */
public static array $parentStaticProperty = [
- 'dir' => __DIR__,
- 'file' => __FILE__,
- 'function' => __FUNCTION__,
- 'class' => __CLASS__,
- 'trait' => __TRAIT__,
- 'method' => __METHOD__,
- 'namespace' => __NAMESPACE__,
- 'targetClassClass' => TargetClass::class,
- 'targetTraitClass' => TargetTrait::class,
+ 'dir' => __DIR__,
+ 'file' => __FILE__,
+ 'function' => __FUNCTION__,
+ 'class' => __CLASS__,
+ 'trait' => __TRAIT__,
+ 'method' => __METHOD__,
+ 'namespace' => __NAMESPACE__,
+ 'targetClassClass' => TargetClass::class,
+ 'targetTraitClass' => TargetTrait::class,
'targetParentClass' => TargetParent::class,
- 'selfClass' => self::class,
+ 'selfClass' => self::class,
];
+ /** @return array */
public function parentMethod(): array
{
return [
- 'dir' => __DIR__,
- 'file' => __FILE__,
- 'function' => __FUNCTION__,
- 'class' => __CLASS__,
- 'trait' => __TRAIT__,
- 'method' => __METHOD__,
- 'namespace' => __NAMESPACE__,
- 'targetClassClass' => TargetClass::class,
- 'targetTraitClass' => TargetTrait::class,
+ 'dir' => __DIR__,
+ 'file' => __FILE__,
+ 'function' => __FUNCTION__,
+ 'class' => __CLASS__,
+ 'trait' => __TRAIT__,
+ 'method' => __METHOD__,
+ 'namespace' => __NAMESPACE__,
+ 'targetClassClass' => TargetClass::class,
+ 'targetTraitClass' => TargetTrait::class,
'targetParentClass' => TargetParent::class,
- 'selfClass' => self::class,
- 'staticClass' => static::class,
+ 'selfClass' => self::class,
+ 'staticClass' => static::class,
];
}
+ /** @return array */
public static function parentStaticMethod(): array
{
return [
- 'dir' => __DIR__,
- 'file' => __FILE__,
- 'function' => __FUNCTION__,
- 'class' => __CLASS__,
- 'trait' => __TRAIT__,
- 'method' => __METHOD__,
- 'namespace' => __NAMESPACE__,
- 'targetClassClass' => TargetClass::class,
- 'targetTraitClass' => TargetTrait::class,
+ 'dir' => __DIR__,
+ 'file' => __FILE__,
+ 'function' => __FUNCTION__,
+ 'class' => __CLASS__,
+ 'trait' => __TRAIT__,
+ 'method' => __METHOD__,
+ 'namespace' => __NAMESPACE__,
+ 'targetClassClass' => TargetClass::class,
+ 'targetTraitClass' => TargetTrait::class,
'targetParentClass' => TargetParent::class,
- 'selfClass' => self::class,
- 'staticClass' => static::class,
+ 'selfClass' => self::class,
+ 'staticClass' => static::class,
];
}
}
diff --git a/tests/Functional/AdviceBehavior/MagicConstants/Target/TargetParent82.php b/tests/Functional/AdviceBehavior/MagicConstants/Target/TargetParent82.php
index 4b9067c..b5ffcaf 100644
--- a/tests/Functional/AdviceBehavior/MagicConstants/Target/TargetParent82.php
+++ b/tests/Functional/AdviceBehavior/MagicConstants/Target/TargetParent82.php
@@ -5,80 +5,84 @@
class TargetParent82
{
public const PARENT_CONST = [
- 'dir' => __DIR__,
- 'file' => __FILE__,
- 'function' => __FUNCTION__,
- 'class' => __CLASS__,
- 'trait' => __TRAIT__,
- 'method' => __METHOD__,
- 'namespace' => __NAMESPACE__,
- 'targetClassClass' => TargetClass82::class,
- 'targetTraitClass' => TargetTrait82::class,
+ 'dir' => __DIR__,
+ 'file' => __FILE__,
+ 'function' => __FUNCTION__,
+ 'class' => __CLASS__,
+ 'trait' => __TRAIT__,
+ 'method' => __METHOD__,
+ 'namespace' => __NAMESPACE__,
+ 'targetClassClass' => TargetClass82::class,
+ 'targetTraitClass' => TargetTrait82::class,
'targetParentClass' => TargetParent82::class,
- 'selfClass' => self::class,
+ 'selfClass' => self::class,
];
+ /** @var array */
public array $parentProperty = [
- 'dir' => __DIR__,
- 'file' => __FILE__,
- 'function' => __FUNCTION__,
- 'class' => __CLASS__,
- 'trait' => __TRAIT__,
- 'method' => __METHOD__,
- 'namespace' => __NAMESPACE__,
- 'targetClassClass' => TargetClass82::class,
- 'targetTraitClass' => TargetTrait82::class,
+ 'dir' => __DIR__,
+ 'file' => __FILE__,
+ 'function' => __FUNCTION__,
+ 'class' => __CLASS__,
+ 'trait' => __TRAIT__,
+ 'method' => __METHOD__,
+ 'namespace' => __NAMESPACE__,
+ 'targetClassClass' => TargetClass82::class,
+ 'targetTraitClass' => TargetTrait82::class,
'targetParentClass' => TargetParent82::class,
- 'selfClass' => self::class,
+ 'selfClass' => self::class,
];
+ /** @var array */
public static array $parentStaticProperty = [
- 'dir' => __DIR__,
- 'file' => __FILE__,
- 'function' => __FUNCTION__,
- 'class' => __CLASS__,
- 'trait' => __TRAIT__,
- 'method' => __METHOD__,
- 'namespace' => __NAMESPACE__,
- 'targetClassClass' => TargetClass82::class,
- 'targetTraitClass' => TargetTrait82::class,
+ 'dir' => __DIR__,
+ 'file' => __FILE__,
+ 'function' => __FUNCTION__,
+ 'class' => __CLASS__,
+ 'trait' => __TRAIT__,
+ 'method' => __METHOD__,
+ 'namespace' => __NAMESPACE__,
+ 'targetClassClass' => TargetClass82::class,
+ 'targetTraitClass' => TargetTrait82::class,
'targetParentClass' => TargetParent82::class,
- 'selfClass' => self::class,
+ 'selfClass' => self::class,
];
+ /** @return array */
public function parentMethod(): array
{
return [
- 'dir' => __DIR__,
- 'file' => __FILE__,
- 'function' => __FUNCTION__,
- 'class' => __CLASS__,
- 'trait' => __TRAIT__,
- 'method' => __METHOD__,
- 'namespace' => __NAMESPACE__,
- 'targetClassClass' => TargetClass82::class,
- 'targetTraitClass' => TargetTrait82::class,
+ 'dir' => __DIR__,
+ 'file' => __FILE__,
+ 'function' => __FUNCTION__,
+ 'class' => __CLASS__,
+ 'trait' => __TRAIT__,
+ 'method' => __METHOD__,
+ 'namespace' => __NAMESPACE__,
+ 'targetClassClass' => TargetClass82::class,
+ 'targetTraitClass' => TargetTrait82::class,
'targetParentClass' => TargetParent82::class,
- 'selfClass' => self::class,
- 'staticClass' => static::class,
+ 'selfClass' => self::class,
+ 'staticClass' => static::class,
];
}
+ /** @return array */
public static function parentStaticMethod(): array
{
return [
- 'dir' => __DIR__,
- 'file' => __FILE__,
- 'function' => __FUNCTION__,
- 'class' => __CLASS__,
- 'trait' => __TRAIT__,
- 'method' => __METHOD__,
- 'namespace' => __NAMESPACE__,
- 'targetClassClass' => TargetClass82::class,
- 'targetTraitClass' => TargetTrait82::class,
+ 'dir' => __DIR__,
+ 'file' => __FILE__,
+ 'function' => __FUNCTION__,
+ 'class' => __CLASS__,
+ 'trait' => __TRAIT__,
+ 'method' => __METHOD__,
+ 'namespace' => __NAMESPACE__,
+ 'targetClassClass' => TargetClass82::class,
+ 'targetTraitClass' => TargetTrait82::class,
'targetParentClass' => TargetParent82::class,
- 'selfClass' => self::class,
- 'staticClass' => static::class,
+ 'selfClass' => self::class,
+ 'staticClass' => static::class,
];
}
}
diff --git a/tests/Functional/AdviceBehavior/MagicConstants/Target/TargetTrait.php b/tests/Functional/AdviceBehavior/MagicConstants/Target/TargetTrait.php
index 0dcb9a2..5b7627a 100644
--- a/tests/Functional/AdviceBehavior/MagicConstants/Target/TargetTrait.php
+++ b/tests/Functional/AdviceBehavior/MagicConstants/Target/TargetTrait.php
@@ -4,67 +4,71 @@
trait TargetTrait
{
+ /** @var array */
public array $traitProperty = [
- 'dir' => __DIR__,
- 'file' => __FILE__,
- 'function' => __FUNCTION__,
- 'class' => __CLASS__,
- 'trait' => __TRAIT__,
- 'method' => __METHOD__,
- 'namespace' => __NAMESPACE__,
- 'targetClassClass' => TargetClass::class,
- 'targetTraitClass' => TargetTrait::class,
+ 'dir' => __DIR__,
+ 'file' => __FILE__,
+ 'function' => __FUNCTION__,
+ 'class' => __CLASS__,
+ 'trait' => __TRAIT__,
+ 'method' => __METHOD__,
+ 'namespace' => __NAMESPACE__,
+ 'targetClassClass' => TargetClass::class,
+ 'targetTraitClass' => TargetTrait::class,
'targetParentClass' => TargetParent::class,
- 'selfClass' => self::class,
+ 'selfClass' => self::class,
];
+ /** @var array */
public static array $traitStaticProperty = [
- 'dir' => __DIR__,
- 'file' => __FILE__,
- 'function' => __FUNCTION__,
- 'class' => __CLASS__,
- 'trait' => __TRAIT__,
- 'method' => __METHOD__,
- 'namespace' => __NAMESPACE__,
- 'targetClassClass' => TargetClass::class,
- 'targetTraitClass' => TargetTrait::class,
+ 'dir' => __DIR__,
+ 'file' => __FILE__,
+ 'function' => __FUNCTION__,
+ 'class' => __CLASS__,
+ 'trait' => __TRAIT__,
+ 'method' => __METHOD__,
+ 'namespace' => __NAMESPACE__,
+ 'targetClassClass' => TargetClass::class,
+ 'targetTraitClass' => TargetTrait::class,
'targetParentClass' => TargetParent::class,
- 'selfClass' => self::class,
+ 'selfClass' => self::class,
];
+ /** @return array */
public function traitMethod(): array
{
return [
- 'dir' => __DIR__,
- 'file' => __FILE__,
- 'function' => __FUNCTION__,
- 'class' => __CLASS__,
- 'trait' => __TRAIT__,
- 'method' => __METHOD__,
- 'namespace' => __NAMESPACE__,
- 'targetClassClass' => TargetClass::class,
- 'targetTraitClass' => TargetTrait::class,
+ 'dir' => __DIR__,
+ 'file' => __FILE__,
+ 'function' => __FUNCTION__,
+ 'class' => __CLASS__,
+ 'trait' => __TRAIT__,
+ 'method' => __METHOD__,
+ 'namespace' => __NAMESPACE__,
+ 'targetClassClass' => TargetClass::class,
+ 'targetTraitClass' => TargetTrait::class,
'targetParentClass' => TargetParent::class,
- 'selfClass' => self::class,
- 'staticClass' => static::class,
+ 'selfClass' => self::class,
+ 'staticClass' => static::class,
];
}
+ /** @return array */
public static function traitStaticMethod(): array
{
return [
- 'dir' => __DIR__,
- 'file' => __FILE__,
- 'function' => __FUNCTION__,
- 'class' => __CLASS__,
- 'trait' => __TRAIT__,
- 'method' => __METHOD__,
- 'namespace' => __NAMESPACE__,
- 'targetClassClass' => TargetClass::class,
- 'targetTraitClass' => TargetTrait::class,
+ 'dir' => __DIR__,
+ 'file' => __FILE__,
+ 'function' => __FUNCTION__,
+ 'class' => __CLASS__,
+ 'trait' => __TRAIT__,
+ 'method' => __METHOD__,
+ 'namespace' => __NAMESPACE__,
+ 'targetClassClass' => TargetClass::class,
+ 'targetTraitClass' => TargetTrait::class,
'targetParentClass' => TargetParent::class,
- 'selfClass' => self::class,
- 'staticClass' => static::class,
+ 'selfClass' => self::class,
+ 'staticClass' => static::class,
];
}
}
diff --git a/tests/Functional/AdviceBehavior/MagicConstants/Target/TargetTrait82.php b/tests/Functional/AdviceBehavior/MagicConstants/Target/TargetTrait82.php
index 6057690..595eda6 100644
--- a/tests/Functional/AdviceBehavior/MagicConstants/Target/TargetTrait82.php
+++ b/tests/Functional/AdviceBehavior/MagicConstants/Target/TargetTrait82.php
@@ -1,84 +1,89 @@
__DIR__,
- 'file' => __FILE__,
- 'function' => __FUNCTION__,
- 'class' => __CLASS__,
- 'trait' => __TRAIT__,
- 'method' => __METHOD__,
- 'namespace' => __NAMESPACE__,
- 'targetClassClass' => TargetClass82::class,
- 'targetTraitClass' => TargetTrait82::class,
+ 'dir' => __DIR__,
+ 'file' => __FILE__,
+ 'function' => __FUNCTION__,
+ 'class' => __CLASS__,
+ 'trait' => __TRAIT__,
+ 'method' => __METHOD__,
+ 'namespace' => __NAMESPACE__,
+ 'targetClassClass' => TargetClass82::class,
+ 'targetTraitClass' => TargetTrait82::class,
'targetParentClass' => TargetParent82::class,
- 'selfClass' => self::class,
+ 'selfClass' => self::class,
];
+ /** @var array */
public array $traitProperty = [
- 'dir' => __DIR__,
- 'file' => __FILE__,
- 'function' => __FUNCTION__,
- 'class' => __CLASS__,
- 'trait' => __TRAIT__,
- 'method' => __METHOD__,
- 'namespace' => __NAMESPACE__,
- 'targetClassClass' => TargetClass82::class,
- 'targetTraitClass' => TargetTrait82::class,
+ 'dir' => __DIR__,
+ 'file' => __FILE__,
+ 'function' => __FUNCTION__,
+ 'class' => __CLASS__,
+ 'trait' => __TRAIT__,
+ 'method' => __METHOD__,
+ 'namespace' => __NAMESPACE__,
+ 'targetClassClass' => TargetClass82::class,
+ 'targetTraitClass' => TargetTrait82::class,
'targetParentClass' => TargetParent82::class,
- 'selfClass' => self::class,
+ 'selfClass' => self::class,
];
+ /** @var array */
public static array $traitStaticProperty = [
- 'dir' => __DIR__,
- 'file' => __FILE__,
- 'function' => __FUNCTION__,
- 'class' => __CLASS__,
- 'trait' => __TRAIT__,
- 'method' => __METHOD__,
- 'namespace' => __NAMESPACE__,
- 'targetClassClass' => TargetClass82::class,
- 'targetTraitClass' => TargetTrait82::class,
+ 'dir' => __DIR__,
+ 'file' => __FILE__,
+ 'function' => __FUNCTION__,
+ 'class' => __CLASS__,
+ 'trait' => __TRAIT__,
+ 'method' => __METHOD__,
+ 'namespace' => __NAMESPACE__,
+ 'targetClassClass' => TargetClass82::class,
+ 'targetTraitClass' => TargetTrait82::class,
'targetParentClass' => TargetParent82::class,
- 'selfClass' => self::class,
+ 'selfClass' => self::class,
];
+ /** @return array */
public function traitMethod(): array
{
return [
- 'dir' => __DIR__,
- 'file' => __FILE__,
- 'function' => __FUNCTION__,
- 'class' => __CLASS__,
- 'trait' => __TRAIT__,
- 'method' => __METHOD__,
- 'namespace' => __NAMESPACE__,
- 'targetClassClass' => TargetClass82::class,
- 'targetTraitClass' => TargetTrait82::class,
+ 'dir' => __DIR__,
+ 'file' => __FILE__,
+ 'function' => __FUNCTION__,
+ 'class' => __CLASS__,
+ 'trait' => __TRAIT__,
+ 'method' => __METHOD__,
+ 'namespace' => __NAMESPACE__,
+ 'targetClassClass' => TargetClass82::class,
+ 'targetTraitClass' => TargetTrait82::class,
'targetParentClass' => TargetParent82::class,
- 'selfClass' => self::class,
- 'staticClass' => static::class,
+ 'selfClass' => self::class,
+ 'staticClass' => static::class,
];
}
+ /** @return array */
public static function traitStaticMethod(): array
{
return [
- 'dir' => __DIR__,
- 'file' => __FILE__,
- 'function' => __FUNCTION__,
- 'class' => __CLASS__,
- 'trait' => __TRAIT__,
- 'method' => __METHOD__,
- 'namespace' => __NAMESPACE__,
- 'targetClassClass' => TargetClass82::class,
- 'targetTraitClass' => TargetTrait82::class,
+ 'dir' => __DIR__,
+ 'file' => __FILE__,
+ 'function' => __FUNCTION__,
+ 'class' => __CLASS__,
+ 'trait' => __TRAIT__,
+ 'method' => __METHOD__,
+ 'namespace' => __NAMESPACE__,
+ 'targetClassClass' => TargetClass82::class,
+ 'targetTraitClass' => TargetTrait82::class,
'targetParentClass' => TargetParent82::class,
- 'selfClass' => self::class,
- 'staticClass' => static::class,
+ 'selfClass' => self::class,
+ 'staticClass' => static::class,
];
}
}
diff --git a/tests/Functional/AdviceBehavior/ModifyArgument/Aspect/NumberHelperAspect.php b/tests/Functional/AdviceBehavior/ModifyArgument/Aspect/NumberHelperAspect.php
index a2cc41c..80887ab 100644
--- a/tests/Functional/AdviceBehavior/ModifyArgument/Aspect/NumberHelperAspect.php
+++ b/tests/Functional/AdviceBehavior/ModifyArgument/Aspect/NumberHelperAspect.php
@@ -1,4 +1,5 @@
$numbers */
$numbers = $invocation->getArgument(0);
- $numbers = array_filter($numbers, fn($number) => $number >= 0);
+ $numbers = array_filter($numbers, static fn($number) => $number >= 0);
$invocation->setArgument(0, $numbers);
}
}
diff --git a/tests/Functional/AdviceBehavior/ModifyArgument/Kernel.php b/tests/Functional/AdviceBehavior/ModifyArgument/Kernel.php
index 0b51ca1..7be9719 100644
--- a/tests/Functional/AdviceBehavior/ModifyArgument/Kernel.php
+++ b/tests/Functional/AdviceBehavior/ModifyArgument/Kernel.php
@@ -10,6 +10,7 @@ class Kernel extends AopKernel
{
protected ?string $cacheDir = Util::CACHE_DIR;
+ /** @var array */
protected array $aspects = [
NumberHelperAspect::class,
];
diff --git a/tests/Functional/AdviceBehavior/ModifyArgument/ModifyArgumentTest.php b/tests/Functional/AdviceBehavior/ModifyArgument/ModifyArgumentTest.php
index 41bdd3d..dc65d76 100644
--- a/tests/Functional/AdviceBehavior/ModifyArgument/ModifyArgumentTest.php
+++ b/tests/Functional/AdviceBehavior/ModifyArgument/ModifyArgumentTest.php
@@ -28,11 +28,11 @@ public function testModifyArgument(): void
$numbers = [1, 2, 3, 4, 5];
$expected = 15;
$actual = $numberHelper->sumArray($numbers);
- $this->assertEquals($expected, $actual);
+ static::assertEquals($expected, $actual);
$numbers = [1, 2, -3, 4, 5];
$expected = 12;
$actual = $numberHelper->sumArray($numbers);
- $this->assertEquals($expected, $actual);
+ static::assertEquals($expected, $actual);
}
}
diff --git a/tests/Functional/AdviceBehavior/ModifyArgument/Target/NumberHelper.php b/tests/Functional/AdviceBehavior/ModifyArgument/Target/NumberHelper.php
index d702a2b..423b691 100644
--- a/tests/Functional/AdviceBehavior/ModifyArgument/Target/NumberHelper.php
+++ b/tests/Functional/AdviceBehavior/ModifyArgument/Target/NumberHelper.php
@@ -4,6 +4,7 @@
class NumberHelper
{
+ /** @param array $numbers */
public function sumArray(array $numbers): int
{
return array_sum($numbers);
diff --git a/tests/Functional/AdviceBehavior/ModifyArgumentPassedByReference/Aspect/AddMetadataToArrayAspect.php b/tests/Functional/AdviceBehavior/ModifyArgumentPassedByReference/Aspect/AddMetadataToArrayAspect.php
index 84e8bdc..06baecc 100644
--- a/tests/Functional/AdviceBehavior/ModifyArgumentPassedByReference/Aspect/AddMetadataToArrayAspect.php
+++ b/tests/Functional/AdviceBehavior/ModifyArgumentPassedByReference/Aspect/AddMetadataToArrayAspect.php
@@ -1,24 +1,22 @@
-getArgument('data');
- $array['metadata'] = 'metadata';
- $invocation->setArgument('data', $array);
- }
-}
+getArgument('data');
+ $array['metadata'] = 'metadata';
+ $invocation->setArgument('data', $array);
+ }
+}
diff --git a/tests/Functional/AdviceBehavior/ModifyArgumentPassedByReference/Kernel.php b/tests/Functional/AdviceBehavior/ModifyArgumentPassedByReference/Kernel.php
index aae0053..c02410f 100644
--- a/tests/Functional/AdviceBehavior/ModifyArgumentPassedByReference/Kernel.php
+++ b/tests/Functional/AdviceBehavior/ModifyArgumentPassedByReference/Kernel.php
@@ -1,16 +1,17 @@
- */
+ protected array $aspects = [
+ AddMetadataToArrayAspect::class,
+ ];
+}
diff --git a/tests/Functional/AdviceBehavior/ModifyArgumentPassedByReference/ModifyArgumentPassedByReferenceTest.php b/tests/Functional/AdviceBehavior/ModifyArgumentPassedByReference/ModifyArgumentPassedByReferenceTest.php
index 274ef12..227d751 100644
--- a/tests/Functional/AdviceBehavior/ModifyArgumentPassedByReference/ModifyArgumentPassedByReferenceTest.php
+++ b/tests/Functional/AdviceBehavior/ModifyArgumentPassedByReference/ModifyArgumentPassedByReferenceTest.php
@@ -1,32 +1,30 @@
-assertWillBeWoven(ArrayCreator::class);
- $idCreator = new ArrayCreator();
-
- $data = 'my-awesome-data';
- $idCreator->createArray($data);
- /** @var array $data */
-
- $this->assertIsArray($data);
- $this->assertArrayHasKey('metadata', $data);
- $this->assertEquals('metadata', $data['metadata']);
- }
-}
+assertWillBeWoven(ArrayCreator::class);
+ $idCreator = new ArrayCreator();
+
+ $data = 'my-awesome-data';
+ $idCreator->createArray($data);
+
+ static::assertArrayHasKey('metadata', $data);
+ static::assertSame('metadata', $data['metadata']);
+ }
+}
diff --git a/tests/Functional/AdviceBehavior/ModifyArgumentPassedByReference/Target/ArrayCreator.php b/tests/Functional/AdviceBehavior/ModifyArgumentPassedByReference/Target/ArrayCreator.php
index 9edccf2..5799788 100644
--- a/tests/Functional/AdviceBehavior/ModifyArgumentPassedByReference/Target/ArrayCreator.php
+++ b/tests/Functional/AdviceBehavior/ModifyArgumentPassedByReference/Target/ArrayCreator.php
@@ -1,11 +1,12 @@
- $data];
- }
-}
+ $data */
+ public function createArray(mixed &$data): void
+ {
+ $data = ['data' => $data];
+ }
+}
diff --git a/tests/Functional/AdviceBehavior/MultipleAdvicesWithSameAdviceTypeOnSameTargetMethod/Aspect/ProfilePictureValidatorAspect.php b/tests/Functional/AdviceBehavior/MultipleAdvicesWithSameAdviceTypeOnSameTargetMethod/Aspect/ProfilePictureValidatorAspect.php
index e5d95b4..0ab2a43 100644
--- a/tests/Functional/AdviceBehavior/MultipleAdvicesWithSameAdviceTypeOnSameTargetMethod/Aspect/ProfilePictureValidatorAspect.php
+++ b/tests/Functional/AdviceBehavior/MultipleAdvicesWithSameAdviceTypeOnSameTargetMethod/Aspect/ProfilePictureValidatorAspect.php
@@ -1,4 +1,5 @@
getArgument('image');
$imageInfo = getimagesize($image);
$allowedFormats = [IMAGETYPE_PNG];
- if (!$imageInfo || !in_array($imageInfo[2], $allowedFormats)) {
+ if (!$imageInfo || !in_array($imageInfo[2], $allowedFormats, true)) {
throw new Exception('Invalid image format');
}
}
@@ -33,19 +32,17 @@ public function checkImageFormat(BeforeMethodInvocation $invocation): void
/**
* @throws Exception
*/
- #[Before(
- class: ProfileController::class,
- method: 'uploadProfilePicture',
- )]
+ #[Before(class: ProfileController::class, method: 'uploadProfilePicture')]
public function checkImageSize(BeforeMethodInvocation $invocation): void
{
+ /** @var string $image */
$image = $invocation->getArgument('image');
$imageSize = filesize($image);
// 1 MB
- $maxSize = 1048576;
+ $maxSize = 1_048_576;
- if ($imageSize > $maxSize) {
+ if ($imageSize !== false && $imageSize > $maxSize) {
throw new Exception('Image is too big');
}
}
diff --git a/tests/Functional/AdviceBehavior/MultipleAdvicesWithSameAdviceTypeOnSameTargetMethod/Kernel.php b/tests/Functional/AdviceBehavior/MultipleAdvicesWithSameAdviceTypeOnSameTargetMethod/Kernel.php
index 9f6687f..9986a1d 100644
--- a/tests/Functional/AdviceBehavior/MultipleAdvicesWithSameAdviceTypeOnSameTargetMethod/Kernel.php
+++ b/tests/Functional/AdviceBehavior/MultipleAdvicesWithSameAdviceTypeOnSameTargetMethod/Kernel.php
@@ -10,6 +10,7 @@ class Kernel extends AopKernel
{
protected ?string $cacheDir = Util::CACHE_DIR;
+ /** @var array */
protected array $aspects = [
ProfilePictureValidatorAspect::class,
];
diff --git a/tests/Functional/AdviceBehavior/MultipleAdvicesWithSameAdviceTypeOnSameTargetMethod/MultipleAdvicesWithSameAdviceTypeOnSameTargetMethodTest.php b/tests/Functional/AdviceBehavior/MultipleAdvicesWithSameAdviceTypeOnSameTargetMethod/MultipleAdvicesWithSameAdviceTypeOnSameTargetMethodTest.php
index 3b39dbf..f604009 100644
--- a/tests/Functional/AdviceBehavior/MultipleAdvicesWithSameAdviceTypeOnSameTargetMethod/MultipleAdvicesWithSameAdviceTypeOnSameTargetMethodTest.php
+++ b/tests/Functional/AdviceBehavior/MultipleAdvicesWithSameAdviceTypeOnSameTargetMethod/MultipleAdvicesWithSameAdviceTypeOnSameTargetMethodTest.php
@@ -1,4 +1,5 @@
uploadProfilePicture(
- 'avatar',
- self::AVATAR_PATH,
- );
+ $path = $profileController->uploadProfilePicture('avatar', self::AVATAR_PATH);
// No exception thrown
- $this->assertTrue(true);
+ static::assertTrue(true);
- $this->assertSame(
- 'https://example.com/avatar',
- $path,
- );
+ static::assertSame('https://example.com/avatar', $path);
// Invalid avatar size
$exceptionThrown = false;
try {
- $profileController->uploadProfilePicture(
- 'avatar',
- self::AVATAR_HQ_PATH,
- );
+ $profileController->uploadProfilePicture('avatar', self::AVATAR_HQ_PATH);
} catch (Exception $e) {
$exceptionThrown = true;
- $this->assertSame(
- 'Image is too big',
- $e->getMessage(),
- );
+ static::assertSame('Image is too big', $e->getMessage());
}
- $this->assertTrue($exceptionThrown);
+ static::assertTrue($exceptionThrown);
// Invalid avatar format
$exceptionThrown = false;
try {
- $profileController->uploadProfilePicture(
- 'avatar',
- self::AVATAR_WRONG_FORMAT_PATH,
- );
+ $profileController->uploadProfilePicture('avatar', self::AVATAR_WRONG_FORMAT_PATH);
} catch (Exception $e) {
$exceptionThrown = true;
- $this->assertSame(
- 'Invalid image format',
- $e->getMessage(),
- );
+ static::assertSame('Invalid image format', $e->getMessage());
}
- $this->assertTrue($exceptionThrown);
+ static::assertTrue($exceptionThrown);
}
}
diff --git a/tests/Functional/AdviceBehavior/MultipleAdvicesWithSameAdviceTypeOnSameTargetMethod/Target/ProfileController.php b/tests/Functional/AdviceBehavior/MultipleAdvicesWithSameAdviceTypeOnSameTargetMethod/Target/ProfileController.php
index e3570b2..b06e60d 100644
--- a/tests/Functional/AdviceBehavior/MultipleAdvicesWithSameAdviceTypeOnSameTargetMethod/Target/ProfileController.php
+++ b/tests/Functional/AdviceBehavior/MultipleAdvicesWithSameAdviceTypeOnSameTargetMethod/Target/ProfileController.php
@@ -1,4 +1,5 @@
*/
+ protected array $aspects = [
+ ModifyGroupPolicyAspect::class,
+ ];
+}
diff --git a/tests/Functional/AdviceBehavior/NewClassCreationWithProxiedClasses/NewClassCreationWithProxiedClassesTest.php b/tests/Functional/AdviceBehavior/NewClassCreationWithProxiedClasses/NewClassCreationWithProxiedClassesTest.php
index 091861d..3d68ae6 100644
--- a/tests/Functional/AdviceBehavior/NewClassCreationWithProxiedClasses/NewClassCreationWithProxiedClassesTest.php
+++ b/tests/Functional/AdviceBehavior/NewClassCreationWithProxiedClasses/NewClassCreationWithProxiedClassesTest.php
@@ -1,71 +1,69 @@
-addDefinitions([
- GroupPolicy::class => DI\create(GroupPolicy::class),
- GroupMemberService::class => DI\autowire(),
- ]);
-
- $container = $containerBuilder->build();
-
- $service = $container->get(GroupMemberService::class);
-
- $this->assertInstanceOf(GroupMemberService::class, $service);
- $this->assertEquals(
- 'Original Policy Details',
- $service->getPolicyDetails(),
- );
- }
-
- public function testManualDefinition(): void
- {
- Util::clearCache();
- Kernel::init();
-
- $containerBuilder = new ContainerBuilder();
- $containerBuilder->addDefinitions([
- GroupPolicy::class => DI\create(GroupPolicy::class),
- GroupMemberService::class => static function (ContainerInterface $container) {
- return new GroupMemberService(
- $container->get(GroupPolicy::class)
- );
- }
- ]);
-
- $container = $containerBuilder->build();
-
- $service = $container->get(GroupMemberService::class);
-
- $this->assertInstanceOf(GroupMemberService::class, $service);
- $this->assertEquals(
- 'Original Policy Details',
- $service->getPolicyDetails(),
- );
- }
-}
+addDefinitions([
+ GroupPolicy::class => DI\create(GroupPolicy::class),
+ GroupMemberService::class => DI\autowire(),
+ ]);
+
+ $container = $containerBuilder->build();
+
+ /** @var mixed $service */
+ $service = $container->get(GroupMemberService::class);
+
+ static::assertInstanceOf(GroupMemberService::class, $service);
+ static::assertSame('Original Policy Details', $service->getPolicyDetails());
+ }
+
+ public function testManualDefinition(): void
+ {
+ Util::clearCache();
+ Kernel::init();
+
+ $containerBuilder = new ContainerBuilder();
+ $containerBuilder->addDefinitions([
+ GroupPolicy::class => DI\create(GroupPolicy::class),
+ GroupMemberService::class => static function (ContainerInterface $container): GroupMemberService {
+ /** @var mixed $policy */
+ $policy = $container->get(GroupPolicy::class);
+ static::assertInstanceOf(GroupPolicy::class, $policy);
+ return new GroupMemberService($policy);
+ },
+ ]);
+
+ $container = $containerBuilder->build();
+
+ /** @var mixed $service */
+ $service = $container->get(GroupMemberService::class);
+
+ static::assertInstanceOf(GroupMemberService::class, $service);
+ static::assertSame('Original Policy Details', $service->getPolicyDetails());
+ }
+}
diff --git a/tests/Functional/AdviceBehavior/NewClassCreationWithProxiedClasses/Target/GroupMemberService.php b/tests/Functional/AdviceBehavior/NewClassCreationWithProxiedClasses/Target/GroupMemberService.php
index dbdae6d..be6d4f3 100644
--- a/tests/Functional/AdviceBehavior/NewClassCreationWithProxiedClasses/Target/GroupMemberService.php
+++ b/tests/Functional/AdviceBehavior/NewClassCreationWithProxiedClasses/Target/GroupMemberService.php
@@ -1,18 +1,18 @@
-groupPolicy = $groupPolicy;
- }
-
- public function getPolicyDetails(): string
- {
- return $this->groupPolicy->getPolicyDetails();
- }
-}
+groupPolicy = $groupPolicy;
+ }
+
+ public function getPolicyDetails(): string
+ {
+ return $this->groupPolicy->getPolicyDetails();
+ }
+}
diff --git a/tests/Functional/AdviceBehavior/NewClassCreationWithProxiedClasses/Target/GroupPolicy.php b/tests/Functional/AdviceBehavior/NewClassCreationWithProxiedClasses/Target/GroupPolicy.php
index ad71de0..a5049a6 100644
--- a/tests/Functional/AdviceBehavior/NewClassCreationWithProxiedClasses/Target/GroupPolicy.php
+++ b/tests/Functional/AdviceBehavior/NewClassCreationWithProxiedClasses/Target/GroupPolicy.php
@@ -1,11 +1,11 @@
-addTrace('DefaultAspect '.$invocation->getMethodName());
+ $stackTrace->addTrace('DefaultAspect ' . $invocation->getMethodName());
}
}
diff --git a/tests/Functional/AdviceBehavior/OnlyPublicMethods/Aspect/OnlyPublicMethodsAspect.php b/tests/Functional/AdviceBehavior/OnlyPublicMethods/Aspect/OnlyPublicMethodsAspect.php
index 889be0d..5630757 100644
--- a/tests/Functional/AdviceBehavior/OnlyPublicMethods/Aspect/OnlyPublicMethodsAspect.php
+++ b/tests/Functional/AdviceBehavior/OnlyPublicMethods/Aspect/OnlyPublicMethodsAspect.php
@@ -1,4 +1,5 @@
addTrace('OnlyPublicMethodsAspect '.$invocation->getMethodName());
+ $stackTrace->addTrace('OnlyPublicMethodsAspect ' . $invocation->getMethodName());
}
}
diff --git a/tests/Functional/AdviceBehavior/OnlyPublicMethods/Kernel.php b/tests/Functional/AdviceBehavior/OnlyPublicMethods/Kernel.php
index 8fe2c60..9cd2ae7 100644
--- a/tests/Functional/AdviceBehavior/OnlyPublicMethods/Kernel.php
+++ b/tests/Functional/AdviceBehavior/OnlyPublicMethods/Kernel.php
@@ -11,6 +11,7 @@ class Kernel extends AopKernel
{
protected ?string $cacheDir = Util::CACHE_DIR;
+ /** @var array */
protected array $aspects = [
DefaultAspect::class,
OnlyPublicMethodsAspect::class,
diff --git a/tests/Functional/AdviceBehavior/OnlyPublicMethods/OnlyPublicMethodsTest.php b/tests/Functional/AdviceBehavior/OnlyPublicMethods/OnlyPublicMethodsTest.php
index 7ca8a8b..6df4e39 100644
--- a/tests/Functional/AdviceBehavior/OnlyPublicMethods/OnlyPublicMethodsTest.php
+++ b/tests/Functional/AdviceBehavior/OnlyPublicMethods/OnlyPublicMethodsTest.php
@@ -35,7 +35,7 @@ public function testOnlyPublicMethodsAreWoven(): void
$targetClass->askTraitHelloHere();
$stackTrace = StackTrace::getInstance();
- $this->assertEquals(
+ static::assertEquals(
[
// Call to $targetClass->helloWorld() = 2 Advice invocations
'DefaultAspect helloWorld',
diff --git a/tests/Functional/AdviceBehavior/OnlyPublicMethods/Target/TargetClass.php b/tests/Functional/AdviceBehavior/OnlyPublicMethods/Target/TargetClass.php
index ecec896..1352fca 100644
--- a/tests/Functional/AdviceBehavior/OnlyPublicMethods/Target/TargetClass.php
+++ b/tests/Functional/AdviceBehavior/OnlyPublicMethods/Target/TargetClass.php
@@ -6,9 +6,9 @@ class TargetClass extends TargetParentClass
{
use TargetTrait;
- public function helloWorld() {}
+ public function helloWorld(): void {}
- protected function helloHere() {}
+ protected function helloHere(): void {}
public function askParentHelloHere(): void
{
diff --git a/tests/Functional/AdviceBehavior/OnlyPublicMethods/Target/TargetParentClass.php b/tests/Functional/AdviceBehavior/OnlyPublicMethods/Target/TargetParentClass.php
index 15eb0e4..eaab43b 100644
--- a/tests/Functional/AdviceBehavior/OnlyPublicMethods/Target/TargetParentClass.php
+++ b/tests/Functional/AdviceBehavior/OnlyPublicMethods/Target/TargetParentClass.php
@@ -4,8 +4,7 @@
class TargetParentClass
{
- public function parentHelloWorld() {}
+ public function parentHelloWorld(): void {}
- protected function parentHelloHere() {}
+ protected function parentHelloHere(): void {}
}
-
diff --git a/tests/Functional/AdviceBehavior/OnlyPublicMethods/Target/TargetTrait.php b/tests/Functional/AdviceBehavior/OnlyPublicMethods/Target/TargetTrait.php
index 7617f1e..98ff972 100644
--- a/tests/Functional/AdviceBehavior/OnlyPublicMethods/Target/TargetTrait.php
+++ b/tests/Functional/AdviceBehavior/OnlyPublicMethods/Target/TargetTrait.php
@@ -4,8 +4,7 @@
trait TargetTrait
{
- public function traitHelloWorld() {}
+ public function traitHelloWorld(): void {}
- protected function traitHelloHere() {}
+ protected function traitHelloHere(): void {}
}
-
diff --git a/tests/Functional/AdviceBehavior/PrivateProperties/EverythingAspect.php b/tests/Functional/AdviceBehavior/PrivateProperties/EverythingAspect.php
index 104d1c5..ed9fd15 100644
--- a/tests/Functional/AdviceBehavior/PrivateProperties/EverythingAspect.php
+++ b/tests/Functional/AdviceBehavior/PrivateProperties/EverythingAspect.php
@@ -1,4 +1,5 @@
*/
protected array $aspects = [EverythingAspect::class];
}
diff --git a/tests/Functional/AdviceBehavior/PrivateProperties/PrivatePropertiesTest.php b/tests/Functional/AdviceBehavior/PrivateProperties/PrivatePropertiesTest.php
index 206cb59..428885b 100644
--- a/tests/Functional/AdviceBehavior/PrivateProperties/PrivatePropertiesTest.php
+++ b/tests/Functional/AdviceBehavior/PrivateProperties/PrivatePropertiesTest.php
@@ -1,17 +1,18 @@
parentTokens());
+ static::assertSame(['parent'], (new ParentInput())->parentTokens());
$child = new ChildInput();
- self::assertSame(['parent'], $child->parentTokens());
- self::assertSame('child', $child->childTokens());
- self::assertGreaterThanOrEqual(3, EverythingAspect::$calls);
+ static::assertSame(['parent'], $child->parentTokens());
+ static::assertSame('child', $child->childTokens());
+ static::assertGreaterThanOrEqual(3, EverythingAspect::$calls);
}
public function testSameTypesRetainIndependentValues(): void
{
$child = new SameTypeInput();
- self::assertSame(['parent'], $child->parentTokens());
- self::assertSame(['child'], $child->childTokens());
+ static::assertSame(['parent'], $child->parentTokens());
+ static::assertSame(['child'], $child->childTokens());
}
public function testPromotedPropertyIsNotDuplicatedByForwardingConstructor(): void
{
$child = new PromotedInput('initial');
PropertyAccess::set($child, 'tokens', 'changed', PromotedInput::class);
- self::assertSame('changed', $child->childTokens());
- self::assertSame(['parent'], $child->parentTokens());
+ static::assertSame('changed', $child->childTokens());
+ static::assertSame(['parent'], $child->parentTokens());
}
public function testUnambiguousPropertyAccessDoesNotRequireScope(): void
{
$parent = new ParentInput();
+ /** @var list $values */
$values = PropertyAccess::get($parent, 'unique');
$values[] = 'appended';
PropertyAccess::set($parent, 'unique', $values);
- self::assertSame(['unique', 'appended'], $parent->unique());
+ static::assertSame(['unique', 'appended'], $parent->unique());
PropertyAccess::set($parent, 'unique', ['assigned']);
- self::assertSame(['assigned'], $parent->unique());
+ static::assertSame(['assigned'], $parent->unique());
}
public function testExplicitScopeSelectsTheOriginalDeclaration(): void
@@ -65,9 +73,9 @@ public function testExplicitScopeSelectsTheOriginalDeclaration(): void
$child = new ChildInput();
PropertyAccess::set($child, 'tokens', ['updated parent'], ParentInput::class);
PropertyAccess::set($child, 'tokens', 'updated child', ChildInput::class);
- self::assertSame(['updated parent'], $child->parentTokens());
- self::assertSame('updated child', $child->childTokens());
- self::assertSame(['updated parent'], PropertyAccess::get($child, 'tokens', ParentInput::class));
+ static::assertSame(['updated parent'], $child->parentTokens());
+ static::assertSame('updated child', $child->childTokens());
+ static::assertSame(['updated parent'], PropertyAccess::get($child, 'tokens', ParentInput::class));
}
public function testAmbiguousAccessRequiresExplicitScope(): void
@@ -81,32 +89,32 @@ public function testAmbiguousAccessRequiresExplicitScope(): void
public function testTraitPropertyRemainsSeparate(): void
{
$child = new TraitInput();
- self::assertSame(['parent'], $child->parentTokens());
- self::assertSame('trait', $child->childTokens());
+ static::assertSame(['parent'], $child->parentTokens());
+ static::assertSame('trait', $child->childTokens());
PropertyAccess::set($child, 'tokens', 'updated trait', TraitInput::class);
- self::assertSame('updated trait', $child->childTokens());
+ static::assertSame('updated trait', $child->childTokens());
}
public function testCustomMagicAccessorsKeepVirtualPropertyBehavior(): void
{
$input = new MagicInput();
- self::assertSame('virtual', $input->example);
+ static::assertSame('virtual', $input->example);
$input->example = 'assigned';
- self::assertSame('assigned', $input->example);
- self::assertTrue(isset($input->example));
- self::assertSame(['example' => 'assigned'], PropertyAccess::get($input, 'values', MagicInput::class));
+ static::assertSame('assigned', $input->example);
+ static::assertTrue(isset($input->example));
+ static::assertSame(['example' => 'assigned'], PropertyAccess::get($input, 'values', MagicInput::class));
unset($input->example);
- self::assertFalse(isset($input->example));
+ static::assertFalse(isset($input->example));
}
public function testStaticPrivatePropertiesHaveIndependentStorage(): void
{
- self::assertSame(['parent'], StaticChild::parentTokens());
- self::assertSame('child', StaticChild::childTokens());
+ static::assertSame(['parent'], StaticChild::parentTokens());
+ static::assertSame('child', StaticChild::childTokens());
PropertyAccess::set(StaticChild::class, 'tokens', ['updated'], StaticParent::class);
PropertyAccess::set(StaticChild::class, 'tokens', 'updated child', StaticChild::class);
- self::assertSame(['updated'], StaticChild::parentTokens());
- self::assertSame('updated child', PropertyAccess::get(StaticChild::class, 'tokens', StaticChild::class));
+ static::assertSame(['updated'], StaticChild::parentTokens());
+ static::assertSame('updated child', PropertyAccess::get(StaticChild::class, 'tokens', StaticChild::class));
}
public function testUnknownScopeDoesNotFallBackToAnotherDeclaration(): void
@@ -131,32 +139,35 @@ public function testPrivateParentAndPublicChildStayIndependent(): void
{
$child = new PublicInput();
$child->tokens = 'direct write';
- self::assertSame(['parent'], $child->parentTokens());
- self::assertSame('direct write', $child->childTokens());
- self::assertSame('direct write', PropertyAccess::get($child, 'tokens', PublicInput::class));
+ static::assertSame(['parent'], $child->parentTokens());
+ static::assertSame('direct write', $child->childTokens());
+ static::assertSame('direct write', PropertyAccess::get($child, 'tokens', PublicInput::class));
}
public function testNonPrivateOverridesShareStorage(): void
{
$child = new PublicGrandchild();
PropertyAccess::set($child, 'tokens', 'shared', PublicInput::class);
- self::assertSame('shared', $child->tokens);
- self::assertSame('shared', PropertyAccess::get($child, 'tokens', PublicGrandchild::class));
- self::assertSame(['parent'], $child->parentTokens());
+ static::assertSame('shared', $child->tokens);
+ static::assertSame('shared', PropertyAccess::get($child, 'tokens', PublicGrandchild::class));
+ static::assertSame(['parent'], $child->parentTokens());
}
public function testUninitializedNullableReadThrowsWithoutInitializingProperty(): void
{
$child = new PublicInput();
$property = new \ReflectionProperty(PublicInput::class . '__AopProxied', 'uninitialized');
- self::assertFalse($property->isInitialized($child));
+ static::assertFalse($property->isInitialized($child));
+ static::assertFalse($child->hasUninitializedValue());
try {
PropertyAccess::get($child, 'uninitialized', PublicInput::class);
- self::fail('Expected an uninitialized property error.');
- } catch (\Error $error) {
- self::assertStringContainsString('must not be accessed before initialization', $error->getMessage());
+ static::fail('Expected an uninitialized property error.');
+ } catch (\Throwable $error) {
+ static::assertInstanceOf(\Error::class, $error);
+ static::assertStringContainsString('must not be accessed before initialization', $error->getMessage());
}
- self::assertFalse($property->isInitialized($child));
+ static::assertFalse($property->isInitialized($child));
+ static::assertFalse($child->hasUninitializedValue());
}
public function testInvocationAccessorMutatesActualSubjectAndSupportsReferences(): void
@@ -164,18 +175,19 @@ public function testInvocationAccessorMutatesActualSubjectAndSupportsReferences(
$subject = new ParentInput();
$subject->unique();
$invocation = EverythingAspect::$invocation;
- self::assertSame($subject, $invocation->getSubject());
- $properties = $invocation->properties();
+ static::assertSame($subject, $invocation->getSubject());
+ /** @var object{unique: list, missing?: mixed} $properties */
+ $properties = $this->propertyView($invocation->properties());
$properties->unique[] = 'appended';
- $reference =& $properties->unique;
+ $reference = &$properties->unique;
$reference[] = 'reference';
- self::assertSame(['unique', 'appended', 'reference'], $subject->unique());
- self::assertTrue(isset($properties->unique));
+ static::assertSame(['unique', 'appended', 'reference'], $subject->unique());
+ static::assertTrue(isset($properties->unique));
$properties->unique = ['assigned'];
- self::assertSame(['assigned'], $subject->unique());
+ static::assertSame(['assigned'], $subject->unique());
unset($properties->unique);
- self::assertFalse(isset($properties->unique));
- self::assertFalse(isset($properties->missing));
+ static::assertFalse(isset($properties->unique));
+ static::assertFalse(isset($properties->missing));
}
public function testInvocationAccessorSelectsParentAndChildScope(): void
@@ -183,23 +195,24 @@ public function testInvocationAccessorSelectsParentAndChildScope(): void
$subject = new ChildInput();
$subject->childTokens();
$invocation = EverythingAspect::$invocation;
- $invocation->properties(ParentInput::class)->tokens = ['changed parent'];
- $invocation->properties(ChildInput::class)->tokens = 'changed child';
- self::assertSame(['changed parent'], $subject->parentTokens());
- self::assertSame('changed child', $subject->childTokens());
+ $invocation->properties(ParentInput::class)->__set('tokens', ['changed parent']);
+ $invocation->properties(ChildInput::class)->__set('tokens', 'changed child');
+ static::assertSame(['changed parent'], $subject->parentTokens());
+ static::assertSame('changed child', $subject->childTokens());
$this->expectException(\LogicException::class);
- $invocation->properties()->tokens;
+ $invocation->properties()->__get('tokens');
}
public function testStaticInvocationAccessor(): void
{
StaticChild::childTokens();
$invocation = EverythingAspect::$invocation;
- self::assertNull($invocation->getSubject());
- $properties = $invocation->properties(StaticChild::class);
+ static::assertNull($invocation->getSubject());
+ /** @var object{tokens: string} $properties */
+ $properties = $this->propertyView($invocation->properties(StaticChild::class));
$properties->tokens = 'assigned';
- self::assertSame('assigned', $properties->tokens);
- self::assertSame('assigned', StaticChild::childTokens());
+ static::assertSame('assigned', $properties->tokens);
+ static::assertSame('assigned', StaticChild::childTokens());
$this->expectException(\Error::class);
unset($properties->tokens);
}
@@ -208,10 +221,11 @@ public function testAccessorDoesNotInitializeNullablePropertyOnRead(): void
{
$subject = new PublicInput();
$subject->childTokens();
- $properties = EverythingAspect::$invocation->properties(PublicInput::class);
- self::assertFalse(isset($properties->uninitialized));
+ /** @var object{uninitialized: ?string} $properties */
+ $properties = $this->propertyView(EverythingAspect::$invocation->properties(PublicInput::class));
+ static::assertFalse(isset($properties->uninitialized));
$this->expectException(\Error::class);
- $properties->uninitialized;
+ static::fail('Expected an uninitialized property error: ' . var_export($properties->uninitialized, true));
}
public function testUnsetPropertyReadDoesNotInvokeSubjectMagicGetter(): void
@@ -219,15 +233,21 @@ public function testUnsetPropertyReadDoesNotInvokeSubjectMagicGetter(): void
$subject = new class {
private string $value = 'initial';
public int $calls = 0;
- public function __get(string $name): mixed { $this->calls++; return 'magic'; }
+
+ public function __get(string $name): mixed
+ {
+ $this->calls++;
+ return 'magic';
+ }
};
- $properties = new \Okapi\Aop\Invocation\PropertyAccessor($subject);
+ /** @var object{value: string} $properties */
+ $properties = $this->propertyView(new \Okapi\Aop\Invocation\PropertyAccessor($subject));
unset($properties->value);
try {
- $properties->value;
- self::fail('Expected uninitialized property error.');
- } catch (\Error) {
- self::assertSame(0, $subject->calls);
+ static::fail('Expected uninitialized property error: ' . $properties->value);
+ } catch (\Throwable $error) {
+ static::assertInstanceOf(\Error::class, $error);
+ static::assertSame(0, $subject->calls);
}
}
@@ -235,10 +255,11 @@ public function testRedeclaredPublicStaticPropertiesRequireScope(): void
{
$parent = Target\SharedStaticParent::class;
$child = Target\SharedStaticChild::class;
- $properties = new \Okapi\Aop\Invocation\PropertyAccessor($child, $parent);
+ /** @var object{value: int} $properties */
+ $properties = $this->propertyView(new \Okapi\Aop\Invocation\PropertyAccessor($child, $parent));
$properties->value = 3;
- self::assertSame(3, $parent::$value);
- self::assertSame(2, $child::$value);
+ static::assertSame(3, $parent::$value);
+ static::assertSame(2, $child::$value);
$this->expectException(\LogicException::class);
PropertyAccess::get($child, 'value');
}
@@ -248,12 +269,17 @@ public function testWriteAfterUnsetPreservesNativeMagicSetterBehavior(): void
$subject = new class {
private string $value = 'initial';
public int $calls = 0;
- public function __set(string $name, mixed $value): void { $this->calls++; }
+
+ public function __set(string $name, mixed $value): void
+ {
+ $this->calls++;
+ }
};
- $properties = new \Okapi\Aop\Invocation\PropertyAccessor($subject);
+ /** @var object{value: string} $properties */
+ $properties = $this->propertyView(new \Okapi\Aop\Invocation\PropertyAccessor($subject));
unset($properties->value);
$properties->value = 'new';
- self::assertSame(1, $subject->calls);
- self::assertFalse(isset($properties->value));
+ static::assertSame(1, $subject->calls);
+ static::assertFalse(isset($properties->value));
}
}
diff --git a/tests/Functional/AdviceBehavior/PrivateProperties/Target/ChildInput.php b/tests/Functional/AdviceBehavior/PrivateProperties/Target/ChildInput.php
index 606a56e..b581914 100644
--- a/tests/Functional/AdviceBehavior/PrivateProperties/Target/ChildInput.php
+++ b/tests/Functional/AdviceBehavior/PrivateProperties/Target/ChildInput.php
@@ -1,8 +1,13 @@
tokens; }
+
+ public function childTokens(): mixed
+ {
+ return $this->tokens;
+ }
}
diff --git a/tests/Functional/AdviceBehavior/PrivateProperties/Target/MagicInput.php b/tests/Functional/AdviceBehavior/PrivateProperties/Target/MagicInput.php
index 7929e1c..d5374f8 100644
--- a/tests/Functional/AdviceBehavior/PrivateProperties/Target/MagicInput.php
+++ b/tests/Functional/AdviceBehavior/PrivateProperties/Target/MagicInput.php
@@ -1,11 +1,30 @@
*/
private array $values = [];
- public function __get(string $name): mixed { return $this->values[$name] ?? 'virtual'; }
- public function __set(string $name, mixed $value): void { $this->values[$name] = $value; }
- public function __isset(string $name): bool { return isset($this->values[$name]); }
- public function __unset(string $name): void { unset($this->values[$name]); }
+
+ public function __get(string $name): mixed
+ {
+ return $this->values[$name] ?? 'virtual';
+ }
+
+ public function __set(string $name, mixed $value): void
+ {
+ $this->values[$name] = $value;
+ }
+
+ public function __isset(string $name): bool
+ {
+ return isset($this->values[$name]);
+ }
+
+ public function __unset(string $name): void
+ {
+ unset($this->values[$name]);
+ }
}
diff --git a/tests/Functional/AdviceBehavior/PrivateProperties/Target/ParentInput.php b/tests/Functional/AdviceBehavior/PrivateProperties/Target/ParentInput.php
index 4081e05..32bb10b 100644
--- a/tests/Functional/AdviceBehavior/PrivateProperties/Target/ParentInput.php
+++ b/tests/Functional/AdviceBehavior/PrivateProperties/Target/ParentInput.php
@@ -1,11 +1,23 @@
*/
private array $tokens = ['parent'];
+ /** @var list */
private array $unique = ['unique'];
- public function parentTokens(): array { return $this->tokens; }
- public function unique(): array { return $this->unique; }
+ /** @return list */
+ public function parentTokens(): array
+ {
+ return $this->tokens;
+ }
+
+ /** @return list */
+ public function unique(): array
+ {
+ return $this->unique;
+ }
}
diff --git a/tests/Functional/AdviceBehavior/PrivateProperties/Target/PromotedInput.php b/tests/Functional/AdviceBehavior/PrivateProperties/Target/PromotedInput.php
index a1c7e7e..a10e812 100644
--- a/tests/Functional/AdviceBehavior/PrivateProperties/Target/PromotedInput.php
+++ b/tests/Functional/AdviceBehavior/PrivateProperties/Target/PromotedInput.php
@@ -1,8 +1,15 @@
tokens; }
+ public function __construct(
+ private string $tokens = 'promoted',
+ ) {}
+
+ public function childTokens(): string
+ {
+ return $this->tokens;
+ }
}
diff --git a/tests/Functional/AdviceBehavior/PrivateProperties/Target/PublicGrandchild.php b/tests/Functional/AdviceBehavior/PrivateProperties/Target/PublicGrandchild.php
index 1bce681..dca2ca8 100644
--- a/tests/Functional/AdviceBehavior/PrivateProperties/Target/PublicGrandchild.php
+++ b/tests/Functional/AdviceBehavior/PrivateProperties/Target/PublicGrandchild.php
@@ -1,4 +1,5 @@
tokens; }
+
+ public function hasUninitializedValue(): bool
+ {
+ return isset($this->uninitialized);
+ }
+
+ public function childTokens(): string
+ {
+ return $this->tokens;
+ }
}
diff --git a/tests/Functional/AdviceBehavior/PrivateProperties/Target/SameTypeInput.php b/tests/Functional/AdviceBehavior/PrivateProperties/Target/SameTypeInput.php
index 4191e49..26210f8 100644
--- a/tests/Functional/AdviceBehavior/PrivateProperties/Target/SameTypeInput.php
+++ b/tests/Functional/AdviceBehavior/PrivateProperties/Target/SameTypeInput.php
@@ -1,8 +1,15 @@
*/
private array $tokens = ['child'];
- public function childTokens(): array { return $this->tokens; }
+
+ /** @return list */
+ public function childTokens(): array
+ {
+ return $this->tokens;
+ }
}
diff --git a/tests/Functional/AdviceBehavior/PrivateProperties/Target/SharedStaticChild.php b/tests/Functional/AdviceBehavior/PrivateProperties/Target/SharedStaticChild.php
index 454564e..a9e89e5 100644
--- a/tests/Functional/AdviceBehavior/PrivateProperties/Target/SharedStaticChild.php
+++ b/tests/Functional/AdviceBehavior/PrivateProperties/Target/SharedStaticChild.php
@@ -1,4 +1,5 @@
*/
private static array $tokens = ['parent'];
- public static function parentTokens(): array { return self::$tokens; }
+
+ /** @return list */
+ public static function parentTokens(): array
+ {
+ return self::$tokens;
+ }
}
diff --git a/tests/Functional/AdviceBehavior/PrivateProperties/Target/TokenTrait.php b/tests/Functional/AdviceBehavior/PrivateProperties/Target/TokenTrait.php
index c474ee2..b467db3 100644
--- a/tests/Functional/AdviceBehavior/PrivateProperties/Target/TokenTrait.php
+++ b/tests/Functional/AdviceBehavior/PrivateProperties/Target/TokenTrait.php
@@ -1,8 +1,13 @@
tokens; }
+
+ public function childTokens(): string
+ {
+ return $this->tokens;
+ }
}
diff --git a/tests/Functional/AdviceBehavior/PrivateProperties/Target/TraitInput.php b/tests/Functional/AdviceBehavior/PrivateProperties/Target/TraitInput.php
index 2b3d550..9ff7e8c 100644
--- a/tests/Functional/AdviceBehavior/PrivateProperties/Target/TraitInput.php
+++ b/tests/Functional/AdviceBehavior/PrivateProperties/Target/TraitInput.php
@@ -1,4 +1,5 @@
proceed();
- $result = $result / (1 - BankingSystem::DEPOSIT_FEE_PERCENTAGE / 100);
+ $result /= 1 - (BankingSystem::DEPOSIT_FEE_PERCENTAGE / 100);
$invocation->setResult($result);
}
- #[After(
- BankingSystem::class,
- 'addFeeToWithdraw',
- )]
+ #[After(BankingSystem::class, 'addFeeToWithdraw')]
public function removeFeeFromWithdraw(AfterMethodInvocation $invocation): void
{
+ /** @var float $result */
$result = $invocation->proceed();
- $result = $result / (1 + BankingSystem::WITHDRAW_FEE_PERCENTAGE / 100);
+ $result /= 1 + (BankingSystem::WITHDRAW_FEE_PERCENTAGE / 100);
$invocation->setResult($result);
}
diff --git a/tests/Functional/AdviceBehavior/ProtectedAndPrivateMethods/Kernel.php b/tests/Functional/AdviceBehavior/ProtectedAndPrivateMethods/Kernel.php
index 4e3e6ed..53597bc 100644
--- a/tests/Functional/AdviceBehavior/ProtectedAndPrivateMethods/Kernel.php
+++ b/tests/Functional/AdviceBehavior/ProtectedAndPrivateMethods/Kernel.php
@@ -10,6 +10,7 @@ class Kernel extends AopKernel
{
protected ?string $cacheDir = Util::CACHE_DIR;
+ /** @var array */
protected array $aspects = [
BankingAspect::class,
];
diff --git a/tests/Functional/AdviceBehavior/ProtectedAndPrivateMethods/ProtectedAndPrivateMethodsTest.php b/tests/Functional/AdviceBehavior/ProtectedAndPrivateMethods/ProtectedAndPrivateMethodsTest.php
index 574cfe9..1d2d6db 100644
--- a/tests/Functional/AdviceBehavior/ProtectedAndPrivateMethods/ProtectedAndPrivateMethodsTest.php
+++ b/tests/Functional/AdviceBehavior/ProtectedAndPrivateMethods/ProtectedAndPrivateMethodsTest.php
@@ -29,17 +29,11 @@ public function testProtectedAndPrivateMethods(): void
$bankingSystem->deposit(100.0);
$balance = $bankingSystem->getBalance();
- $this->assertEquals(
- 100.0,
- $balance,
- );
+ static::assertSame(100.0, $balance);
$bankingSystem->withdraw(50.0);
$balance = $bankingSystem->getBalance();
- $this->assertEquals(
- 50.0,
- $balance,
- );
+ static::assertSame(50.0, $balance);
}
}
diff --git a/tests/Functional/AdviceBehavior/ProtectedAndPrivateMethods/Target/BankingSystem.php b/tests/Functional/AdviceBehavior/ProtectedAndPrivateMethods/Target/BankingSystem.php
index 059cb5d..a6b5138 100644
--- a/tests/Functional/AdviceBehavior/ProtectedAndPrivateMethods/Target/BankingSystem.php
+++ b/tests/Functional/AdviceBehavior/ProtectedAndPrivateMethods/Target/BankingSystem.php
@@ -16,7 +16,7 @@ public function deposit(float $amount): void
protected function removeFeeFromDeposit(float $amount): float
{
- return $amount - ($amount * self::DEPOSIT_FEE_PERCENTAGE / 100);
+ return $amount - (($amount * self::DEPOSIT_FEE_PERCENTAGE) / 100);
}
public function withdraw(float $amount): void
@@ -26,7 +26,7 @@ public function withdraw(float $amount): void
private function addFeeToWithdraw(float $amount): float
{
- return $amount + ($amount * self::WITHDRAW_FEE_PERCENTAGE / 100);
+ return $amount + (($amount * self::WITHDRAW_FEE_PERCENTAGE) / 100);
}
public function getBalance(): float
diff --git a/tests/Functional/AdviceBehavior/Readonly/Aspect/ReadonlyAspect.php b/tests/Functional/AdviceBehavior/Readonly/Aspect/ReadonlyAspect.php
index 8f3bfc2..72acd8e 100644
--- a/tests/Functional/AdviceBehavior/Readonly/Aspect/ReadonlyAspect.php
+++ b/tests/Functional/AdviceBehavior/Readonly/Aspect/ReadonlyAspect.php
@@ -1,16 +1,14 @@
- */
+ protected array $aspects = [
+ ReadonlyAspect::class,
+ ];
+}
diff --git a/tests/Functional/AdviceBehavior/Readonly/ReadonlyTest.php b/tests/Functional/AdviceBehavior/Readonly/ReadonlyTest.php
index 17485dc..84f5f2a 100644
--- a/tests/Functional/AdviceBehavior/Readonly/ReadonlyTest.php
+++ b/tests/Functional/AdviceBehavior/Readonly/ReadonlyTest.php
@@ -1,48 +1,49 @@
-markTestSkipped('Readonly classes are supported only in PHP 8.2 and later.');
- }
-
- Util::clearCache();
- Kernel::init();
-
- $this->assertWillBeWoven(ReadonlyClass::class);
-
- new ReadonlyClass();
-
- $this->assertTrue(true);
- }
-
- public function testReadonlyPromotedProperties(): void
- {
- Util::clearCache();
- Kernel::init();
-
- $this->assertWillBeWoven(ReadonlyPromotedProperties::class);
-
- new ReadonlyPromotedProperties('Walter Woshid', 42);
-
- $this->assertTrue(true);
- }
-}
+assertWillBeWoven(ReadonlyClass::class);
+
+ new ReadonlyClass();
+
+ static::assertTrue(true);
+ }
+
+ public function testReadonlyPromotedProperties(): void
+ {
+ Util::clearCache();
+ Kernel::init();
+
+ $this->assertWillBeWoven(ReadonlyPromotedProperties::class);
+
+ new ReadonlyPromotedProperties('Walter Woshid', 42);
+
+ static::assertTrue(true);
+ }
+}
diff --git a/tests/Functional/AdviceBehavior/Readonly/Target/ReadonlyClass.php b/tests/Functional/AdviceBehavior/Readonly/Target/ReadonlyClass.php
index 10a242e..c57ca52 100644
--- a/tests/Functional/AdviceBehavior/Readonly/Target/ReadonlyClass.php
+++ b/tests/Functional/AdviceBehavior/Readonly/Target/ReadonlyClass.php
@@ -1,8 +1,9 @@
->> */
public static array $cachedRoutes = [];
- #[Around(
- class: RouteCaching::class,
- method: 'getRoutes',
- )]
+ #[Around(class: RouteCaching::class, method: 'getRoutes')]
public function cacheRoutes(AroundMethodInvocation $invocation): void
{
$arguments = $invocation->getArguments();
@@ -28,16 +27,19 @@ public function cacheRoutes(AroundMethodInvocation $invocation): void
return;
}
+ /** @var array> $routes */
$routes = $invocation->proceed();
$this->storeInCache($cacheKey, $routes);
}
+ /** @return array>|null */
private function getFromCache(string $cacheKey): ?array
{
return self::$cachedRoutes[$cacheKey] ?? null;
}
+ /** @param array> $routes */
private function storeInCache(string $cacheKey, array $routes): void
{
self::$cachedRoutes[$cacheKey] = $routes;
diff --git a/tests/Functional/AdviceBehavior/TraitAdvice/Kernel.php b/tests/Functional/AdviceBehavior/TraitAdvice/Kernel.php
index b73ff98..8b7984b 100644
--- a/tests/Functional/AdviceBehavior/TraitAdvice/Kernel.php
+++ b/tests/Functional/AdviceBehavior/TraitAdvice/Kernel.php
@@ -10,6 +10,7 @@ class Kernel extends AopKernel
{
protected ?string $cacheDir = Util::CACHE_DIR;
+ /** @var array */
protected array $aspects = [
RouteCachingAspect::class,
];
diff --git a/tests/Functional/AdviceBehavior/TraitAdvice/Target/RouteCaching.php b/tests/Functional/AdviceBehavior/TraitAdvice/Target/RouteCaching.php
index ce871b8..890c345 100644
--- a/tests/Functional/AdviceBehavior/TraitAdvice/Target/RouteCaching.php
+++ b/tests/Functional/AdviceBehavior/TraitAdvice/Target/RouteCaching.php
@@ -4,6 +4,7 @@
trait RouteCaching
{
+ /** @return array> */
public function getRoutes(): array
{
return [
diff --git a/tests/Functional/AdviceBehavior/TraitAdvice/TraitAdviceTest.php b/tests/Functional/AdviceBehavior/TraitAdvice/TraitAdviceTest.php
index 48308ad..6325875 100644
--- a/tests/Functional/AdviceBehavior/TraitAdvice/TraitAdviceTest.php
+++ b/tests/Functional/AdviceBehavior/TraitAdvice/TraitAdviceTest.php
@@ -26,9 +26,9 @@ public function testTraitAdvice(): void
$router = new Router();
$routes = $router->getRoutes();
- $this->assertCount(1, $routes);
+ static::assertCount(1, $routes);
$cachedRoutes = RouteCachingAspect::$cachedRoutes;
- $this->assertCount(1, $cachedRoutes);
+ static::assertCount(1, $cachedRoutes);
}
}
diff --git a/tests/Functional/AdviceBehavior/VariadicParameters/Aspect/StringPrefixerAspect.php b/tests/Functional/AdviceBehavior/VariadicParameters/Aspect/StringPrefixerAspect.php
index d2aceda..94c0cab 100644
--- a/tests/Functional/AdviceBehavior/VariadicParameters/Aspect/StringPrefixerAspect.php
+++ b/tests/Functional/AdviceBehavior/VariadicParameters/Aspect/StringPrefixerAspect.php
@@ -1,4 +1,5 @@
getArgument('prefix');
+ /** @var list $ids */
$ids = $invocation->getArgument('ids');
foreach ($ids as &$id) {
diff --git a/tests/Functional/AdviceBehavior/VariadicParameters/Target/IdHelper.php b/tests/Functional/AdviceBehavior/VariadicParameters/Target/IdHelper.php
index 1dff828..81c94ae 100644
--- a/tests/Functional/AdviceBehavior/VariadicParameters/Target/IdHelper.php
+++ b/tests/Functional/AdviceBehavior/VariadicParameters/Target/IdHelper.php
@@ -2,11 +2,11 @@
namespace Okapi\Aop\Tests\Functional\AdviceBehavior\VariadicParameters\Target;
-
use Okapi\Aop\Tests\Functional\AdviceBehavior\VariadicParameters\Aspect\StringPrefixerAspect;
class IdHelper
{
+ /** @return array */
#[StringPrefixerAspect]
public function createIds(string $prefix, string ...$ids): array
{
diff --git a/tests/Functional/AdviceBehavior/VariadicParameters/VariadicParametersTest.php b/tests/Functional/AdviceBehavior/VariadicParameters/VariadicParametersTest.php
index 175a53a..6ecf25a 100644
--- a/tests/Functional/AdviceBehavior/VariadicParameters/VariadicParametersTest.php
+++ b/tests/Functional/AdviceBehavior/VariadicParameters/VariadicParametersTest.php
@@ -32,7 +32,7 @@ public function testVariadicParameters(): void
$expectedResult = ['prefix-id1', 'prefix-id2', 'prefix-id3'];
- $this->assertSame($expectedResult, $result);
+ static::assertSame($expectedResult, $result);
}
public function testVariadicParametersWithoutAop(): void
@@ -47,6 +47,6 @@ public function testVariadicParametersWithoutAop(): void
$expectedResult = ['id1', 'id2', 'id3'];
- $this->assertSame($expectedResult, $result);
+ static::assertSame($expectedResult, $result);
}
}
diff --git a/tests/Functional/AspectMatching/AdviceMatchingMultipleClassesAndMethods/AdviceMatchingMultipleClassesAndMethodsTest.php b/tests/Functional/AspectMatching/AdviceMatchingMultipleClassesAndMethods/AdviceMatchingMultipleClassesAndMethodsTest.php
index 51791ea..40e5a0d 100644
--- a/tests/Functional/AspectMatching/AdviceMatchingMultipleClassesAndMethods/AdviceMatchingMultipleClassesAndMethodsTest.php
+++ b/tests/Functional/AspectMatching/AdviceMatchingMultipleClassesAndMethods/AdviceMatchingMultipleClassesAndMethodsTest.php
@@ -26,12 +26,12 @@ public function testAdviceMatchingMultipleClassesAndMethods(): void
$this->assertWillBeWoven(Product::class);
$product = new Product();
$productPrice = $product->getPrice();
- $this->assertEquals(90.00, $productPrice);
+ static::assertSame(90.00, $productPrice);
$this->assertWillBeWoven(Order::class);
$order = new Order();
$orderTotal = $order->getTotal();
- $this->assertEquals(400.00, $orderTotal);
+ static::assertSame(400.00, $orderTotal);
}
public function testCachedAdviceMatchingMultipleClassesAndMethods(): void
@@ -41,11 +41,11 @@ public function testCachedAdviceMatchingMultipleClassesAndMethods(): void
$this->assertAspectLoadedFromCache(Product::class);
$product = new Product();
$productPrice = $product->getPrice();
- $this->assertEquals(90.00, $productPrice);
+ static::assertSame(90.00, $productPrice);
$this->assertAspectLoadedFromCache(Order::class);
$order = new Order();
$orderTotal = $order->getTotal();
- $this->assertEquals(400.00, $orderTotal);
+ static::assertSame(400.00, $orderTotal);
}
}
diff --git a/tests/Functional/AspectMatching/AdviceMatchingMultipleClassesAndMethods/Aspect/DiscountAspect.php b/tests/Functional/AspectMatching/AdviceMatchingMultipleClassesAndMethods/Aspect/DiscountAspect.php
index d378b47..582056c 100644
--- a/tests/Functional/AspectMatching/AdviceMatchingMultipleClassesAndMethods/Aspect/DiscountAspect.php
+++ b/tests/Functional/AspectMatching/AdviceMatchingMultipleClassesAndMethods/Aspect/DiscountAspect.php
@@ -1,4 +1,5 @@
getSubject();
$productDiscount = 0.1;
- $orderDiscount = 0.2;
+ $orderDiscount = 0.2;
if ($subject instanceof Product) {
+ /** @var float $oldPrice */
$oldPrice = $invocation->proceed();
$newPrice = $oldPrice - ($oldPrice * $productDiscount);
@@ -30,6 +29,7 @@ public function applyDiscount(AfterMethodInvocation $invocation): void
}
if ($subject instanceof Order) {
+ /** @var float $oldTotal */
$oldTotal = $invocation->proceed();
$newTotal = $oldTotal - ($oldTotal * $orderDiscount);
diff --git a/tests/Functional/AspectMatching/AdviceMatchingMultipleClassesAndMethods/Kernel.php b/tests/Functional/AspectMatching/AdviceMatchingMultipleClassesAndMethods/Kernel.php
index 5c447e6..375a5eb 100644
--- a/tests/Functional/AspectMatching/AdviceMatchingMultipleClassesAndMethods/Kernel.php
+++ b/tests/Functional/AspectMatching/AdviceMatchingMultipleClassesAndMethods/Kernel.php
@@ -10,6 +10,7 @@ class Kernel extends AopKernel
{
protected ?string $cacheDir = Util::CACHE_DIR;
+ /** @var array */
protected array $aspects = [
DiscountAspect::class,
];
diff --git a/tests/Functional/AspectMatching/ClassHierarchyOnlyInvokedOnce/Aspect.php b/tests/Functional/AspectMatching/ClassHierarchyOnlyInvokedOnce/Aspect.php
index 7fabc56..da61060 100644
--- a/tests/Functional/AspectMatching/ClassHierarchyOnlyInvokedOnce/Aspect.php
+++ b/tests/Functional/AspectMatching/ClassHierarchyOnlyInvokedOnce/Aspect.php
@@ -1,4 +1,5 @@
addTrace("Method call $count");
+ $stackTrace->addTrace("Method call {$count}");
}
}
diff --git a/tests/Functional/AspectMatching/ClassHierarchyOnlyInvokedOnce/ClassHierarchyOnlyInvokedOnceTest.php b/tests/Functional/AspectMatching/ClassHierarchyOnlyInvokedOnce/ClassHierarchyOnlyInvokedOnceTest.php
index 744d6af..62561e2 100644
--- a/tests/Functional/AspectMatching/ClassHierarchyOnlyInvokedOnce/ClassHierarchyOnlyInvokedOnceTest.php
+++ b/tests/Functional/AspectMatching/ClassHierarchyOnlyInvokedOnce/ClassHierarchyOnlyInvokedOnceTest.php
@@ -30,7 +30,7 @@ public function testAdviceIsInvokedOnlyOnce(): void
$stackTrace = StackTrace::getInstance();
- $this->assertEquals(
+ static::assertEquals(
[
'Method call 1',
'Method call 2',
diff --git a/tests/Functional/AspectMatching/ClassHierarchyOnlyInvokedOnce/Kernel.php b/tests/Functional/AspectMatching/ClassHierarchyOnlyInvokedOnce/Kernel.php
index 56eafaf..bac64c7 100644
--- a/tests/Functional/AspectMatching/ClassHierarchyOnlyInvokedOnce/Kernel.php
+++ b/tests/Functional/AspectMatching/ClassHierarchyOnlyInvokedOnce/Kernel.php
@@ -9,6 +9,7 @@ class Kernel extends AopKernel
{
protected ?string $cacheDir = Util::CACHE_DIR;
+ /** @var array */
protected array $aspects = [
Aspect::class,
];
diff --git a/tests/Functional/AspectMatching/ClassHierarchyOnlyInvokedOnce/Target/TargetClassA.php b/tests/Functional/AspectMatching/ClassHierarchyOnlyInvokedOnce/Target/TargetClassA.php
index 8547ce2..098adde 100644
--- a/tests/Functional/AspectMatching/ClassHierarchyOnlyInvokedOnce/Target/TargetClassA.php
+++ b/tests/Functional/AspectMatching/ClassHierarchyOnlyInvokedOnce/Target/TargetClassA.php
@@ -2,6 +2,4 @@
namespace Okapi\Aop\Tests\Functional\AspectMatching\ClassHierarchyOnlyInvokedOnce\Target;
-class TargetClassA extends TargetClassB
-{
-}
+class TargetClassA extends TargetClassB {}
diff --git a/tests/Functional/AspectMatching/ClassHierarchyOnlyInvokedOnce/Target/TargetClassB.php b/tests/Functional/AspectMatching/ClassHierarchyOnlyInvokedOnce/Target/TargetClassB.php
index 3ea5836..92e977d 100644
--- a/tests/Functional/AspectMatching/ClassHierarchyOnlyInvokedOnce/Target/TargetClassB.php
+++ b/tests/Functional/AspectMatching/ClassHierarchyOnlyInvokedOnce/Target/TargetClassB.php
@@ -2,6 +2,4 @@
namespace Okapi\Aop\Tests\Functional\AspectMatching\ClassHierarchyOnlyInvokedOnce\Target;
-class TargetClassB extends TargetClassC
-{
-}
+class TargetClassB extends TargetClassC {}
diff --git a/tests/Functional/AspectMatching/ClassHierarchyOnlyInvokedOnce/Target/TargetClassC.php b/tests/Functional/AspectMatching/ClassHierarchyOnlyInvokedOnce/Target/TargetClassC.php
index 1b22fd9..11af849 100644
--- a/tests/Functional/AspectMatching/ClassHierarchyOnlyInvokedOnce/Target/TargetClassC.php
+++ b/tests/Functional/AspectMatching/ClassHierarchyOnlyInvokedOnce/Target/TargetClassC.php
@@ -4,5 +4,5 @@
class TargetClassC
{
- public function helloWorld() {}
+ public function helloWorld(): void {}
}
diff --git a/tests/Functional/AspectMatching/InterceptTraitMethods/AdviceInterceptTraitMethodsTest.php b/tests/Functional/AspectMatching/InterceptTraitMethods/AdviceInterceptTraitMethodsTest.php
index 57299d3..56b064e 100644
--- a/tests/Functional/AspectMatching/InterceptTraitMethods/AdviceInterceptTraitMethodsTest.php
+++ b/tests/Functional/AspectMatching/InterceptTraitMethods/AdviceInterceptTraitMethodsTest.php
@@ -34,7 +34,7 @@ public function testTraitMethodsNotWoven(): void
$targetClass->helloHere();
$stackTrace = StackTrace::getInstance();
- $this->assertEquals(
+ static::assertEquals(
[
// First call to TargetClass::helloWorld()
'DefaultAspect',
diff --git a/tests/Functional/AspectMatching/InterceptTraitMethods/Aspect/DefaultAspect.php b/tests/Functional/AspectMatching/InterceptTraitMethods/Aspect/DefaultAspect.php
index e30e90a..b942817 100644
--- a/tests/Functional/AspectMatching/InterceptTraitMethods/Aspect/DefaultAspect.php
+++ b/tests/Functional/AspectMatching/InterceptTraitMethods/Aspect/DefaultAspect.php
@@ -1,4 +1,5 @@
*/
protected array $aspects = [
DefaultAspect::class,
InterceptTraitMethodsAspect::class,
diff --git a/tests/Functional/AspectMatching/InterceptTraitMethods/Target/TargetClass.php b/tests/Functional/AspectMatching/InterceptTraitMethods/Target/TargetClass.php
index e77258c..c16a022 100644
--- a/tests/Functional/AspectMatching/InterceptTraitMethods/Target/TargetClass.php
+++ b/tests/Functional/AspectMatching/InterceptTraitMethods/Target/TargetClass.php
@@ -6,5 +6,5 @@ class TargetClass
{
use TargetTrait;
- public function helloWorld() {}
+ public function helloWorld(): void {}
}
diff --git a/tests/Functional/AspectMatching/InterceptTraitMethods/Target/TargetTrait.php b/tests/Functional/AspectMatching/InterceptTraitMethods/Target/TargetTrait.php
index 8e4efe6..d9e6ba5 100644
--- a/tests/Functional/AspectMatching/InterceptTraitMethods/Target/TargetTrait.php
+++ b/tests/Functional/AspectMatching/InterceptTraitMethods/Target/TargetTrait.php
@@ -4,6 +4,5 @@
trait TargetTrait
{
- public function helloHere() {}
+ public function helloHere(): void {}
}
-
diff --git a/tests/Functional/AspectMatching/SelfType/Aspect/SalaryIncreaserAspect.php b/tests/Functional/AspectMatching/SelfType/Aspect/SalaryIncreaserAspect.php
index a826533..76aac77 100644
--- a/tests/Functional/AspectMatching/SelfType/Aspect/SalaryIncreaserAspect.php
+++ b/tests/Functional/AspectMatching/SelfType/Aspect/SalaryIncreaserAspect.php
@@ -1,4 +1,5 @@
getArgument('salaryIncrease');
- $invocation->setArgument(
- 'salaryIncrease',
- $salary * 2,
- );
+ $invocation->setArgument('salaryIncrease', $salary * 2);
}
}
diff --git a/tests/Functional/AspectMatching/SelfType/Kernel.php b/tests/Functional/AspectMatching/SelfType/Kernel.php
index 6d9013f..07bbbc6 100644
--- a/tests/Functional/AspectMatching/SelfType/Kernel.php
+++ b/tests/Functional/AspectMatching/SelfType/Kernel.php
@@ -10,6 +10,7 @@ class Kernel extends AopKernel
{
protected ?string $cacheDir = Util::CACHE_DIR;
+ /** @var array */
protected array $aspects = [
SalaryIncreaserAspect::class,
];
diff --git a/tests/Functional/AspectMatching/SelfType/SelfTypeTest.php b/tests/Functional/AspectMatching/SelfType/SelfTypeTest.php
index 022121c..5258f69 100644
--- a/tests/Functional/AspectMatching/SelfType/SelfTypeTest.php
+++ b/tests/Functional/AspectMatching/SelfType/SelfTypeTest.php
@@ -32,32 +32,19 @@ public function testSelfType(): void
$promotedEmployee = $employee->promote($employee, $salaryIncrease);
- $this->assertInstanceOf(Employee::class, $promotedEmployee);
- $this->assertInstanceOf(AbstractEmployee::class, $promotedEmployee);
- $this->assertSame(
- $employee->getName(),
- $promotedEmployee->getName(),
- );
- $this->assertSame(
- $employee->getSalary() + ($salaryIncrease * 2),
- $promotedEmployee->getSalary(),
- );
-
+ static::assertInstanceOf(Employee::class, $promotedEmployee);
+ static::assertInstanceOf(AbstractEmployee::class, $promotedEmployee);
+ static::assertSame($employee->getName(), $promotedEmployee->getName());
+ static::assertSame($employee->getSalary() + ($salaryIncrease * 2), $promotedEmployee->getSalary());
$salaryDecrease = 1000.0;
$demotedEmployee = $promotedEmployee->demote($promotedEmployee, $salaryDecrease);
- $this->assertInstanceOf(PartTimeEmployee::class, $demotedEmployee);
- $this->assertInstanceOf(Employee::class, $demotedEmployee);
- $this->assertInstanceOf(AbstractEmployee::class, $demotedEmployee);
- $this->assertSame(
- $promotedEmployee->getName(),
- $demotedEmployee->getName(),
- );
- $this->assertSame(
- $promotedEmployee->getSalary() - $salaryDecrease,
- $demotedEmployee->getSalary(),
- );
+ static::assertInstanceOf(PartTimeEmployee::class, $demotedEmployee);
+ static::assertInstanceOf(Employee::class, $demotedEmployee);
+ static::assertInstanceOf(AbstractEmployee::class, $demotedEmployee);
+ static::assertSame($promotedEmployee->getName(), $demotedEmployee->getName());
+ static::assertSame($promotedEmployee->getSalary() - $salaryDecrease, $demotedEmployee->getSalary());
}
}
diff --git a/tests/Functional/AspectMatching/SelfType/Target/Employee.php b/tests/Functional/AspectMatching/SelfType/Target/Employee.php
index c208ed0..8d4feb0 100644
--- a/tests/Functional/AspectMatching/SelfType/Target/Employee.php
+++ b/tests/Functional/AspectMatching/SelfType/Target/Employee.php
@@ -11,6 +11,10 @@ public function __construct(
public function promote(AbstractEmployee|int $employee, float $salaryIncrease): self|int
{
+ if (is_int($employee)) {
+ return $employee;
+ }
+
$promotedSalary = $employee->getSalary() + $salaryIncrease;
return new self($employee->getName(), $promotedSalary);
diff --git a/tests/Functional/AspectMatching/SelfType/Target/PartTimeEmployee.php b/tests/Functional/AspectMatching/SelfType/Target/PartTimeEmployee.php
index dfb3eb1..2f75847 100644
--- a/tests/Functional/AspectMatching/SelfType/Target/PartTimeEmployee.php
+++ b/tests/Functional/AspectMatching/SelfType/Target/PartTimeEmployee.php
@@ -2,6 +2,4 @@
namespace Okapi\Aop\Tests\Functional\AspectMatching\SelfType\Target;
-class PartTimeEmployee extends Employee
-{
-}
+class PartTimeEmployee extends Employee {}
diff --git a/tests/Functional/ErrorHandling/InvalidAspect/Aspect/InvalidAspect.php b/tests/Functional/ErrorHandling/InvalidAspect/Aspect/InvalidAspect.php
index 705bc82..20b50b0 100644
--- a/tests/Functional/ErrorHandling/InvalidAspect/Aspect/InvalidAspect.php
+++ b/tests/Functional/ErrorHandling/InvalidAspect/Aspect/InvalidAspect.php
@@ -6,10 +6,7 @@
class InvalidAspect
{
- #[Before(
- class: 'Nice',
- method: 'test',
- )]
+ #[Before(class: 'Nice', method: 'test')]
public function test(): string
{
return 'I am invalid!';
diff --git a/tests/Functional/ErrorHandling/InvalidAspect/Kernel/InvalidAspectClassKernel.php b/tests/Functional/ErrorHandling/InvalidAspect/Kernel/InvalidAspectClassKernel.php
index 7d3c111..4ea632b 100644
--- a/tests/Functional/ErrorHandling/InvalidAspect/Kernel/InvalidAspectClassKernel.php
+++ b/tests/Functional/ErrorHandling/InvalidAspect/Kernel/InvalidAspectClassKernel.php
@@ -7,6 +7,7 @@
class InvalidAspectClassKernel extends AopKernel
{
+ /** @var array */
protected array $aspects = [
InvalidAspect::class,
];
diff --git a/tests/Functional/ErrorHandling/InvalidAspect/Kernel/InvalidAspectClassNameKernel.php b/tests/Functional/ErrorHandling/InvalidAspect/Kernel/InvalidAspectClassNameKernel.php
index b189cf8..6f98035 100644
--- a/tests/Functional/ErrorHandling/InvalidAspect/Kernel/InvalidAspectClassNameKernel.php
+++ b/tests/Functional/ErrorHandling/InvalidAspect/Kernel/InvalidAspectClassNameKernel.php
@@ -6,6 +6,7 @@
class InvalidAspectClassNameKernel extends AopKernel
{
+ /** @var array */
protected array $aspects = [
'InvalidAspect',
];
diff --git a/tests/Functional/ErrorHandling/InvalidAspect/Kernel/InvalidAspectsTypeKernel.php b/tests/Functional/ErrorHandling/InvalidAspect/Kernel/InvalidAspectsTypeKernel.php
index 392968d..ecd1012 100644
--- a/tests/Functional/ErrorHandling/InvalidAspect/Kernel/InvalidAspectsTypeKernel.php
+++ b/tests/Functional/ErrorHandling/InvalidAspect/Kernel/InvalidAspectsTypeKernel.php
@@ -6,6 +6,7 @@
class InvalidAspectsTypeKernel extends AopKernel
{
+ /** @var array */
protected array $aspects = [
42,
];
diff --git a/tests/Functional/ErrorHandling/MissingClassOrMethod/Aspect/AddItemLoggerAspect.php b/tests/Functional/ErrorHandling/MissingClassOrMethod/Aspect/AddItemLoggerAspect.php
index d53d5e4..7b459e3 100644
--- a/tests/Functional/ErrorHandling/MissingClassOrMethod/Aspect/AddItemLoggerAspect.php
+++ b/tests/Functional/ErrorHandling/MissingClassOrMethod/Aspect/AddItemLoggerAspect.php
@@ -10,19 +10,15 @@
#[Aspect]
class AddItemLoggerAspect
{
- #[After(
- method: 'addItem',
- )]
+ #[After(method: 'addItem')]
public function logAddItem(AfterMethodInvocation $invocation): void
{
+ /** @var string $itemName */
$itemName = $invocation->getArgument('itemName');
+ /** @var int $quantity */
$quantity = $invocation->getArgument('quantity');
- $logMessage = sprintf(
- "Item %s added to inventory with quantity %d.",
- $itemName,
- $quantity,
- );
+ $logMessage = sprintf('Item %s added to inventory with quantity %d.', $itemName, $quantity);
$logger = Logger::getInstance();
$logger->log($logMessage);
diff --git a/tests/Functional/ErrorHandling/MissingClassOrMethod/Aspect/GetQuantityLoggerAspect.php b/tests/Functional/ErrorHandling/MissingClassOrMethod/Aspect/GetQuantityLoggerAspect.php
index 8c87ba8..c657d1c 100644
--- a/tests/Functional/ErrorHandling/MissingClassOrMethod/Aspect/GetQuantityLoggerAspect.php
+++ b/tests/Functional/ErrorHandling/MissingClassOrMethod/Aspect/GetQuantityLoggerAspect.php
@@ -1,4 +1,5 @@
getArgument('itemName');
+ /** @var int $quantity */
$quantity = $invocation->proceed();
- $logMessage = sprintf(
- "Item %s has quantity %d.",
- $itemName,
- $quantity,
- );
+ $logMessage = sprintf('Item %s has quantity %d.', $itemName, $quantity);
$logger = Logger::getInstance();
$logger->log($logMessage);
diff --git a/tests/Functional/ErrorHandling/MissingClassOrMethod/Aspect/RemoveItemLoggerAspect.php b/tests/Functional/ErrorHandling/MissingClassOrMethod/Aspect/RemoveItemLoggerAspect.php
index d81664c..4082dc3 100644
--- a/tests/Functional/ErrorHandling/MissingClassOrMethod/Aspect/RemoveItemLoggerAspect.php
+++ b/tests/Functional/ErrorHandling/MissingClassOrMethod/Aspect/RemoveItemLoggerAspect.php
@@ -1,4 +1,5 @@
getArgument('itemName');
- $logMessage = sprintf(
- "Item %s removed from inventory.",
- $itemName,
- );
+ $logMessage = sprintf('Item %s removed from inventory.', $itemName);
$logger = Logger::getInstance();
$logger->log($logMessage);
diff --git a/tests/Functional/ErrorHandling/MissingClassOrMethod/Kernel/AddItemKernel.php b/tests/Functional/ErrorHandling/MissingClassOrMethod/Kernel/AddItemKernel.php
index c53ad28..4a0449e 100644
--- a/tests/Functional/ErrorHandling/MissingClassOrMethod/Kernel/AddItemKernel.php
+++ b/tests/Functional/ErrorHandling/MissingClassOrMethod/Kernel/AddItemKernel.php
@@ -10,6 +10,7 @@ class AddItemKernel extends AopKernel
{
protected ?string $cacheDir = Util::CACHE_DIR;
+ /** @var array */
protected array $aspects = [
AddItemLoggerAspect::class,
];
diff --git a/tests/Functional/ErrorHandling/MissingClassOrMethod/Kernel/GetQuantityKernel.php b/tests/Functional/ErrorHandling/MissingClassOrMethod/Kernel/GetQuantityKernel.php
index da271f2..64504d3 100644
--- a/tests/Functional/ErrorHandling/MissingClassOrMethod/Kernel/GetQuantityKernel.php
+++ b/tests/Functional/ErrorHandling/MissingClassOrMethod/Kernel/GetQuantityKernel.php
@@ -10,6 +10,7 @@ class GetQuantityKernel extends AopKernel
{
protected ?string $cacheDir = Util::CACHE_DIR;
+ /** @var array */
protected array $aspects = [
GetQuantityLoggerAspect::class,
];
diff --git a/tests/Functional/ErrorHandling/MissingClassOrMethod/Kernel/RemoveItemKernel.php b/tests/Functional/ErrorHandling/MissingClassOrMethod/Kernel/RemoveItemKernel.php
index 5b51ae4..90eaf4a 100644
--- a/tests/Functional/ErrorHandling/MissingClassOrMethod/Kernel/RemoveItemKernel.php
+++ b/tests/Functional/ErrorHandling/MissingClassOrMethod/Kernel/RemoveItemKernel.php
@@ -10,6 +10,7 @@ class RemoveItemKernel extends AopKernel
{
protected ?string $cacheDir = Util::CACHE_DIR;
+ /** @var array */
protected array $aspects = [
RemoveItemLoggerAspect::class,
];
diff --git a/tests/Functional/ErrorHandling/MissingClassOrMethod/MissingClassOrMethodTest.php b/tests/Functional/ErrorHandling/MissingClassOrMethod/MissingClassOrMethodTest.php
index cff9a9c..ab734c0 100644
--- a/tests/Functional/ErrorHandling/MissingClassOrMethod/MissingClassOrMethodTest.php
+++ b/tests/Functional/ErrorHandling/MissingClassOrMethod/MissingClassOrMethodTest.php
@@ -1,4 +1,5 @@
assertInstanceOf(
- MissingClassNameException::class,
- $error,
- );
+ static::assertInstanceOf(MissingClassNameException::class, $error);
}
/**
@@ -57,10 +55,7 @@ public function testMissingMethodName(): void
$error = $e;
}
- $this->assertInstanceOf(
- MissingMethodNameException::class,
- $error,
- );
+ static::assertInstanceOf(MissingMethodNameException::class, $error);
}
/**
@@ -82,8 +77,6 @@ public function testMissingClassAndMethodName(): void
$missingClassNameException = $error instanceof MissingClassNameException;
$missingMethodNameException = $error instanceof MissingMethodNameException;
- $this->assertTrue(
- $missingClassNameException || $missingMethodNameException,
- );
+ static::assertTrue($missingClassNameException || $missingMethodNameException);
}
}
diff --git a/tests/Functional/ErrorHandling/MissingClassOrMethod/Target/InventoryManager.php b/tests/Functional/ErrorHandling/MissingClassOrMethod/Target/InventoryManager.php
index 04ad80a..25f5d14 100644
--- a/tests/Functional/ErrorHandling/MissingClassOrMethod/Target/InventoryManager.php
+++ b/tests/Functional/ErrorHandling/MissingClassOrMethod/Target/InventoryManager.php
@@ -1,9 +1,11 @@
*/
private array $items = [];
public function addItem(string $itemName, int $quantity): void
diff --git a/tests/Functional/Kernel/CustomDependencyInjectionHandler/Aspect.php b/tests/Functional/Kernel/CustomDependencyInjectionHandler/Aspect.php
index ee0aeb5..d05f43e 100644
--- a/tests/Functional/Kernel/CustomDependencyInjectionHandler/Aspect.php
+++ b/tests/Functional/Kernel/CustomDependencyInjectionHandler/Aspect.php
@@ -8,10 +8,7 @@
#[AspectAttribute]
class Aspect
{
- #[After(
- class: Target::class,
- method: 'answer',
- )]
+ #[After(class: Target::class, method: 'answer')]
public function higherAnswer(): int
{
return 420;
diff --git a/tests/Functional/Kernel/CustomDependencyInjectionHandler/CustomDependencyInjectionHandlerTest.php b/tests/Functional/Kernel/CustomDependencyInjectionHandler/CustomDependencyInjectionHandlerTest.php
index 41a3175..fb58fbc 100644
--- a/tests/Functional/Kernel/CustomDependencyInjectionHandler/CustomDependencyInjectionHandlerTest.php
+++ b/tests/Functional/Kernel/CustomDependencyInjectionHandler/CustomDependencyInjectionHandlerTest.php
@@ -18,17 +18,12 @@ public function testCustomDependencyInjectionHandler(): void
Kernel::init();
$output = ob_get_clean();
+ static::assertIsString($output);
- $this->assertStringContainsString(
- 'Generating aspect/transformer instance: ' . Aspect::class,
- $output,
- );
+ static::assertStringContainsString('Generating aspect/transformer instance: ' . Aspect::class, $output);
$class = new Target();
- $this->assertSame(
- 420,
- $class->answer(),
- );
+ static::assertSame(420, $class->answer());
}
}
diff --git a/tests/Functional/Kernel/CustomDependencyInjectionHandler/Kernel.php b/tests/Functional/Kernel/CustomDependencyInjectionHandler/Kernel.php
index fa76324..a044e10 100644
--- a/tests/Functional/Kernel/CustomDependencyInjectionHandler/Kernel.php
+++ b/tests/Functional/Kernel/CustomDependencyInjectionHandler/Kernel.php
@@ -12,13 +12,14 @@ class Kernel extends AopKernel
protected function dependencyInjectionHandler(): ?Closure
{
- return function (string $className) {
+ return /** @param class-string $className */ static function (string $className) {
echo 'Generating aspect/transformer instance: ' . $className . PHP_EOL;
- return new $className();
+ return (new \ReflectionClass($className))->newInstance();
};
}
+ /** @var array */
protected array $aspects = [
Aspect::class,
];
diff --git a/tests/Integration/TransformerAndAspect/Aspect/FixWrongReturnValueAspect.php b/tests/Integration/TransformerAndAspect/Aspect/FixWrongReturnValueAspect.php
index 9e1b861..0c80dc3 100644
--- a/tests/Integration/TransformerAndAspect/Aspect/FixWrongReturnValueAspect.php
+++ b/tests/Integration/TransformerAndAspect/Aspect/FixWrongReturnValueAspect.php
@@ -1,21 +1,20 @@
proceed();
$invocation->setResult(!$result);
}
diff --git a/tests/Integration/TransformerAndAspect/Kernel.php b/tests/Integration/TransformerAndAspect/Kernel.php
index 3569abe..fe36e83 100644
--- a/tests/Integration/TransformerAndAspect/Kernel.php
+++ b/tests/Integration/TransformerAndAspect/Kernel.php
@@ -4,17 +4,19 @@
use Okapi\Aop\AopKernel;
use Okapi\Aop\Tests\Integration\TransformerAndAspect\Aspect\FixWrongReturnValueAspect;
-use Okapi\Aop\Tests\Integration\TransformerAndAspect\Transformer\FixDeprecatedFunctionTransformer;
+use Okapi\Aop\Tests\Integration\TransformerAndAspect\Transformer\FixIncorrectFunctionTransformer;
use Okapi\Aop\Tests\Util;
class Kernel extends AopKernel
{
protected ?string $cacheDir = Util::CACHE_DIR;
+ /** @var array> */
protected array $transformers = [
- FixDeprecatedFunctionTransformer::class,
+ FixIncorrectFunctionTransformer::class,
];
+ /** @var array */
protected array $aspects = [
FixWrongReturnValueAspect::class,
];
diff --git a/tests/Integration/TransformerAndAspect/Target/DeprecatedAndWrongClass.php b/tests/Integration/TransformerAndAspect/Target/IncorrectFunctionAndReturnClass.php
similarity index 55%
rename from tests/Integration/TransformerAndAspect/Target/DeprecatedAndWrongClass.php
rename to tests/Integration/TransformerAndAspect/Target/IncorrectFunctionAndReturnClass.php
index c705215..fb12791 100644
--- a/tests/Integration/TransformerAndAspect/Target/DeprecatedAndWrongClass.php
+++ b/tests/Integration/TransformerAndAspect/Target/IncorrectFunctionAndReturnClass.php
@@ -2,11 +2,10 @@
namespace Okapi\Aop\Tests\Integration\TransformerAndAspect\Target;
-class DeprecatedAndWrongClass
+class IncorrectFunctionAndReturnClass
{
public function checkIfFloat(mixed $value): bool
{
- /** @noinspection PhpDeprecationInspection */
- return !is_real($value);
+ return !is_int($value);
}
}
diff --git a/tests/Integration/TransformerAndAspect/Transformer/FixDeprecatedFunctionTransformer.php b/tests/Integration/TransformerAndAspect/Transformer/FixIncorrectFunctionTransformer.php
similarity index 53%
rename from tests/Integration/TransformerAndAspect/Transformer/FixDeprecatedFunctionTransformer.php
rename to tests/Integration/TransformerAndAspect/Transformer/FixIncorrectFunctionTransformer.php
index 32205c9..10d0578 100644
--- a/tests/Integration/TransformerAndAspect/Transformer/FixDeprecatedFunctionTransformer.php
+++ b/tests/Integration/TransformerAndAspect/Transformer/FixIncorrectFunctionTransformer.php
@@ -3,28 +3,28 @@
namespace Okapi\Aop\Tests\Integration\TransformerAndAspect\Transformer;
use Microsoft\PhpParser\Node\QualifiedName;
-use Okapi\Aop\Tests\Integration\TransformerAndAspect\Target\DeprecatedAndWrongClass;
+use Okapi\Aop\Tests\Integration\TransformerAndAspect\Target\IncorrectFunctionAndReturnClass;
use Okapi\CodeTransformer\Transformer;
use Okapi\CodeTransformer\Transformer\Code;
-class FixDeprecatedFunctionTransformer extends Transformer
+class FixIncorrectFunctionTransformer extends Transformer
{
public function getTargetClass(): string|array
{
- return DeprecatedAndWrongClass::class;
+ return IncorrectFunctionAndReturnClass::class;
}
public function transform(Code $code): void
{
$sourceFileNode = $code->getSourceFileNode();
+ /** @var \Microsoft\PhpParser\Node $node */
foreach ($sourceFileNode->getDescendantNodes() as $node) {
- if ($node instanceof QualifiedName && $node->getText() === 'is_real') {
- $code->edit(
- $node->nameParts[0],
- 'is_float',
- );
+ if (!($node instanceof QualifiedName && $node->getText() === 'is_int')) {
+ continue;
}
+
+ $code->edit($node, 'is_float');
}
}
}
diff --git a/tests/Integration/TransformerAndAspect/TransformerAndAspectTest.php b/tests/Integration/TransformerAndAspect/TransformerAndAspectTest.php
index a824941..fdbe129 100644
--- a/tests/Integration/TransformerAndAspect/TransformerAndAspectTest.php
+++ b/tests/Integration/TransformerAndAspect/TransformerAndAspectTest.php
@@ -4,8 +4,8 @@
use Okapi\Aop\Tests\ClassLoaderMockTrait;
use Okapi\Aop\Tests\Integration\TransformerAndAspect\Aspect\FixWrongReturnValueAspect;
-use Okapi\Aop\Tests\Integration\TransformerAndAspect\Target\DeprecatedAndWrongClass;
-use Okapi\Aop\Tests\Integration\TransformerAndAspect\Transformer\FixDeprecatedFunctionTransformer;
+use Okapi\Aop\Tests\Integration\TransformerAndAspect\Target\IncorrectFunctionAndReturnClass;
+use Okapi\Aop\Tests\Integration\TransformerAndAspect\Transformer\FixIncorrectFunctionTransformer;
use Okapi\Aop\Tests\Util;
use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
use PHPUnit\Framework\TestCase;
@@ -16,7 +16,7 @@ class TransformerAndAspectTest extends TestCase
use ClassLoaderMockTrait;
/**
- * @see FixDeprecatedFunctionTransformer
+ * @see FixIncorrectFunctionTransformer
* @see FixWrongReturnValueAspect::fixWrongReturnValue()
*/
public function testTransformerAndAspect(): void
@@ -24,18 +24,18 @@ public function testTransformerAndAspect(): void
Util::clearCache();
Kernel::init();
- $this->assertWillBeWoven(DeprecatedAndWrongClass::class);
- $class = new DeprecatedAndWrongClass();
- $this->assertTrue($class->checkIfFloat(1.0));
+ $this->assertWillBeWoven(IncorrectFunctionAndReturnClass::class);
+ $class = new IncorrectFunctionAndReturnClass();
+ static::assertTrue($class->checkIfFloat(1.0));
}
public function testCachedTransformerAndAspect(): void
{
Kernel::init();
- $this->assertAspectLoadedFromCache(DeprecatedAndWrongClass::class);
- $class = new DeprecatedAndWrongClass();
- $this->assertTrue($class->checkIfFloat(42.0));
- $this->assertFalse($class->checkIfFloat("Hello World!"));
+ $this->assertAspectLoadedFromCache(IncorrectFunctionAndReturnClass::class);
+ $class = new IncorrectFunctionAndReturnClass();
+ static::assertTrue($class->checkIfFloat(42.0));
+ static::assertFalse($class->checkIfFloat('Hello World!'));
}
}
diff --git a/tests/Integration/TransformerAndAspectDependencyInjectionHandler/Aspect.php b/tests/Integration/TransformerAndAspectDependencyInjectionHandler/Aspect.php
index 133f115..5d1161d 100644
--- a/tests/Integration/TransformerAndAspectDependencyInjectionHandler/Aspect.php
+++ b/tests/Integration/TransformerAndAspectDependencyInjectionHandler/Aspect.php
@@ -1,4 +1,5 @@
proceed();
return $result + 378;
diff --git a/tests/Integration/TransformerAndAspectDependencyInjectionHandler/Kernel.php b/tests/Integration/TransformerAndAspectDependencyInjectionHandler/Kernel.php
index b88e764..65c0ec0 100644
--- a/tests/Integration/TransformerAndAspectDependencyInjectionHandler/Kernel.php
+++ b/tests/Integration/TransformerAndAspectDependencyInjectionHandler/Kernel.php
@@ -13,24 +13,25 @@ class Kernel extends AopKernel
protected function dependencyInjectionHandler(): ?Closure
{
- return function (string $className, ComponentType $type) {
+ return /** @param class-string $className */ static function (string $className, ComponentType $type) {
/** @noinspection PhpIfWithCommonPartsInspection */
if ($type === ComponentType::ASPECT) {
echo 'Generating aspect instance: ' . $className . PHP_EOL;
- return new $className();
- } else {
- echo 'Generating transformer instance: ' . $className . PHP_EOL;
-
- return new $className();
+ return (new \ReflectionClass($className))->newInstance();
}
+ echo 'Generating transformer instance: ' . $className . PHP_EOL;
+
+ return (new \ReflectionClass($className))->newInstance();
};
}
+ /** @var array */
protected array $aspects = [
Aspect::class,
];
+ /** @var array> */
protected array $transformers = [
Transformer::class,
];
diff --git a/tests/Integration/TransformerAndAspectDependencyInjectionHandler/Transformer.php b/tests/Integration/TransformerAndAspectDependencyInjectionHandler/Transformer.php
index 8f72684..2f15b19 100644
--- a/tests/Integration/TransformerAndAspectDependencyInjectionHandler/Transformer.php
+++ b/tests/Integration/TransformerAndAspectDependencyInjectionHandler/Transformer.php
@@ -20,18 +20,24 @@ public function transform(Code $code): void
{
$sourceFileNode = $code->getSourceFileNode();
+ /** @var \Microsoft\PhpParser\Node $node */
foreach ($sourceFileNode->getDescendantNodes() as $node) {
- if ($node instanceof QualifiedNameList
- && $node->getFirstAncestor(MethodDeclaration::class)?->getName() === 'answer'
+ $method = $node->getFirstAncestor(MethodDeclaration::class);
+ if (
+ $node instanceof QualifiedNameList
+ && $method instanceof MethodDeclaration
+ && $method->getName() === 'answer'
) {
$code->edit($node, 'int|float');
}
- if ($node instanceof NumericLiteral
- && $node->getFirstAncestor(MethodDeclaration::class)?->getName() === 'answer'
+ if (
+ $node instanceof NumericLiteral
+ && $method instanceof MethodDeclaration
+ && $method->getName() === 'answer'
) {
$text = $node->getText();
- $code->edit($node, "$text.69");
+ $code->edit($node, "{$text}.69");
}
}
}
diff --git a/tests/Integration/TransformerAndAspectDependencyInjectionHandler/TransformerAndAspectDependencyInjectionHandlerTest.php b/tests/Integration/TransformerAndAspectDependencyInjectionHandler/TransformerAndAspectDependencyInjectionHandlerTest.php
index 8b960e7..678f57e 100644
--- a/tests/Integration/TransformerAndAspectDependencyInjectionHandler/TransformerAndAspectDependencyInjectionHandlerTest.php
+++ b/tests/Integration/TransformerAndAspectDependencyInjectionHandler/TransformerAndAspectDependencyInjectionHandlerTest.php
@@ -25,22 +25,14 @@ public function testTransformerAndAspectDependencyInjectionHandler(): void
Kernel::init();
$output = ob_get_clean();
+ static::assertIsString($output);
- $this->assertStringContainsString(
- 'Generating aspect instance: ' . Aspect::class,
- $output,
- );
- $this->assertStringContainsString(
- 'Generating transformer instance: ' . Transformer::class,
- $output,
- );
+ static::assertStringContainsString('Generating aspect instance: ' . Aspect::class, $output);
+ static::assertStringContainsString('Generating transformer instance: ' . Transformer::class, $output);
$this->assertWillBeWoven(Target::class);
$class = new Target();
- $this->assertSame(
- 420.69,
- $class->answer(),
- );
+ static::assertSame(420.69, $class->answer());
}
}
diff --git a/tests/Performance/Aspect/AddOneAspect.php b/tests/Performance/Aspect/AddOneAspect.php
index fee703f..7d2bdaf 100644
--- a/tests/Performance/Aspect/AddOneAspect.php
+++ b/tests/Performance/Aspect/AddOneAspect.php
@@ -1,4 +1,5 @@
proceed();
$invocation->setResult($result + 1);
diff --git a/tests/Performance/Kernel/MeasurePerformanceKernel.php b/tests/Performance/Kernel/MeasurePerformanceKernel.php
index 7dff232..b50d625 100644
--- a/tests/Performance/Kernel/MeasurePerformanceKernel.php
+++ b/tests/Performance/Kernel/MeasurePerformanceKernel.php
@@ -13,6 +13,7 @@ class MeasurePerformanceKernel extends AopKernel
protected Environment $environment = Environment::DEVELOPMENT;
/** @noinspection PhpFullyQualifiedNameUsageInspection */
+ /** @var array */
protected array $aspects = [
\Okapi\Aop\Tests\Performance\Aspect\AddOneAspect::class,
];
diff --git a/tests/Performance/MeasurePerformanceTest.php b/tests/Performance/MeasurePerformanceTest.php
index 9f93e0a..5bde915 100644
--- a/tests/Performance/MeasurePerformanceTest.php
+++ b/tests/Performance/MeasurePerformanceTest.php
@@ -3,17 +3,21 @@
namespace Okapi\Aop\Tests\Performance;
use Exception;
-use Okapi\Aop\Tests\Performance\Kernel\MeasurePerformanceKernel;
-use Okapi\Aop\Tests\Performance\Service\NumbersService;
+use Okapi\Aop\AopKernel;
+use Okapi\Aop\Tests\Performance\Service\NumbersServiceInterface;
use Okapi\Aop\Tests\Performance\Target\Numbers;
use Okapi\Aop\Tests\Util;
use Okapi\Filesystem\Filesystem;
-use PHPUnit\Framework\Attributes\{DataProvider, RunTestsInSeparateProcesses, Test};
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
+use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;
+use ReflectionClass;
+use Symfony\Component\Console\Helper\Table;
+use Symfony\Component\Console\Helper\TableStyle;
use Symfony\Component\Console\Input\ArgvInput;
-use Symfony\Component\Console\Style\SymfonyStyle;
-use Symfony\Component\Console\Helper\{Table, TableStyle};
use Symfony\Component\Console\Output\ConsoleOutput;
+use Symfony\Component\Console\Style\SymfonyStyle;
#[RunTestsInSeparateProcesses]
class MeasurePerformanceTest extends TestCase
@@ -22,52 +26,55 @@ class MeasurePerformanceTest extends TestCase
private bool $cached;
private bool $production;
- private CONST MEASURE_TYPE_NO_ASPECTS = 'No Aspects';
- private CONST MEASURE_TYPE_ASPECTS = 'Aspects';
- private CONST MEASURE_TYPE_CACHED_ASPECTS = 'Cached Aspects';
- private CONST MEASURE_TYPE_PRODUCTION = 'Production';
+ private const MEASURE_TYPE_NO_ASPECTS = 'No Aspects';
+ private const MEASURE_TYPE_ASPECTS = 'Aspects';
+ private const MEASURE_TYPE_CACHED_ASPECTS = 'Cached Aspects';
+ private const MEASURE_TYPE_PRODUCTION = 'Production';
+ /** @var array>> */
private array $measures = [
- self::MEASURE_TYPE_NO_ASPECTS => [],
- self::MEASURE_TYPE_ASPECTS => [],
+ self::MEASURE_TYPE_NO_ASPECTS => [],
+ self::MEASURE_TYPE_ASPECTS => [],
self::MEASURE_TYPE_CACHED_ASPECTS => [],
- self::MEASURE_TYPE_PRODUCTION => [],
+ self::MEASURE_TYPE_PRODUCTION => [],
];
private const MEASURE_TYPE_FROM_START_TO_END = 'From Start to End';
- private const MEASURE_TYPE_BOOT = 'Boot Time - Kernel::init()';
- private const MEASURE_TYPE_CLASS_LOADING = 'Class Loading Time';
- private const MEASURE_TYPE_EXECUTION = 'Execution Time';
+ private const MEASURE_TYPE_BOOT = 'Boot Time - Kernel::init()';
+ private const MEASURE_TYPE_CLASS_LOADING = 'Class Loading Time';
+ private const MEASURE_TYPE_EXECUTION = 'Execution Time';
- private const START_TIME = 'Start Time';
- private const END_TIME = 'End Time';
+ private const START_TIME = 'Start Time';
+ private const END_TIME = 'End Time';
private const START_MEMORY = 'Start Memory';
- private const END_MEMORY = 'End Memory';
+ private const END_MEMORY = 'End Memory';
- private const METRIC_TYPE_TIME = 'Time';
+ private const METRIC_TYPE_TIME = 'Time';
private const METRIC_TYPE_MEMORY = 'Memory';
+ /** @var non-empty-list */
public static array $aspectCountAndExecutionCount = [
- [1, 1], // Minimal
- [5, 5], // Small
- [20, 20], // Moderate
- [50, 50], // Medium
- [100, 100], // Common
- [500, 100], // Common: Aspects++
- [100, 500], // Common: Executions++
- [500, 500], // High
- [1000, 500], // High: Aspects++
- [500, 1000], // High: Executions++
+ [1, 1], // Minimal
+ [5, 5], // Small
+ [20, 20], // Moderate
+ [50, 50], // Medium
+ [100, 100], // Common
+ [500, 100], // Common: Aspects++
+ [100, 500], // Common: Executions++
+ [500, 500], // High
+ [1000, 500], // High: Aspects++
+ [500, 1000], // High: Executions++
[1000, 1000], // Very High
];
+ /** @return array */
public static function dataProvider(): array
{
$flags = [
- self::MEASURE_TYPE_NO_ASPECTS => [],
- self::MEASURE_TYPE_ASPECTS => ['useAspects' => true],
+ self::MEASURE_TYPE_NO_ASPECTS => [],
+ self::MEASURE_TYPE_ASPECTS => ['useAspects' => true],
self::MEASURE_TYPE_CACHED_ASPECTS => ['useAspects' => true, 'cached' => true],
- self::MEASURE_TYPE_PRODUCTION => ['useAspects' => true, 'cached' => true, 'production' => true],
+ self::MEASURE_TYPE_PRODUCTION => ['useAspects' => true, 'cached' => true, 'production' => true],
];
$data = [];
@@ -79,30 +86,30 @@ public static function dataProvider(): array
$aspectsLabel = $aspectCount === 1 ? 'aspect' : 'aspects';
$executionLabel = $executionCount === 1 ? 'execution' : 'executions';
- $dataProviderLabel = "$measureType: $aspectCount $aspectsLabel, $executionCount $executionLabel";
+ $dataProviderLabel = "{$measureType}: {$aspectCount} {$aspectsLabel}, {$executionCount} {$executionLabel}";
$data[$dataProviderLabel] = [
- 'aspectCount' => $aspectCount,
+ 'aspectCount' => $aspectCount,
'executionCount' => $executionCount,
- 'useAspects' => $flag['useAspects'] ?? false,
- 'cached' => $flag['cached'] ?? false,
- 'production' => $flag['production'] ?? false,
+ 'useAspects' => $flag['useAspects'] ?? false,
+ 'cached' => $flag['cached'] ?? false,
+ 'production' => $flag['production'] ?? false,
];
}
}
// Cleanup data
$data['Cleanup'] = [
- 'aspectCount' => 0,
+ 'aspectCount' => 0,
'executionCount' => 0,
];
// Number of tests should equal the number of generated data sets
$dataCount = count($data);
- $expectedDataCount = count(self::$aspectCountAndExecutionCount) * count($flags) + 1;
+ $expectedDataCount = (count(self::$aspectCountAndExecutionCount) * count($flags)) + 1;
if ($dataCount !== $expectedDataCount) {
/** @noinspection PhpUnhandledExceptionInspection */
- throw new Exception("Expected $expectedDataCount data sets, got $dataCount");
+ throw new Exception("Expected {$expectedDataCount} data sets, got {$dataCount}");
}
if (extension_loaded('xdebug')) {
@@ -129,15 +136,14 @@ public function measurePerformance(
$noFlags = !$useAspects && !$cached && !$production;
$lastMeasure = $useAspects && $cached && $production;
- $firstRun = $aspectCount === self::$aspectCountAndExecutionCount[0][0]
+ $firstRun =
+ $aspectCount === self::$aspectCountAndExecutionCount[0][0]
&& $executionCount === self::$aspectCountAndExecutionCount[0][1]
&& $noFlags;
- $shouldCleanCache = $firstRun || ($useAspects && !$cached);
+ $shouldCleanCache = $firstRun || $useAspects && !$cached;
- $lastRun = $aspectCount === 0
- && $executionCount === 0
- && $noFlags;
+ $lastRun = $aspectCount === 0 && $executionCount === 0 && $noFlags;
if ($firstRun) {
$this->cleanup();
@@ -153,38 +159,43 @@ public function measurePerformance(
return;
}
- /** @var class-string[] $services */
+ /** @var class-string[] $services */
$services = [];
if ($useAspects) {
// Create $aspectCount aspects and a kernel that uses them
$kernel = $this->createKernelAndAspects($aspectCount, $production);
- } else {
+ }
+ if (!$useAspects) {
// Emulate aspects by creating $aspectCount services
$services = $this->createServices($aspectCount);
}
$this->useAspects = $useAspects;
- $this->cached = $cached;
+ $this->cached = $cached;
$this->production = $production;
$this->startMeasure(self::MEASURE_TYPE_FROM_START_TO_END);
$this->startMeasure(self::MEASURE_TYPE_BOOT);
if ($useAspects) {
- /** @var MeasurePerformanceKernel $kernel */
+ /** @var class-string $kernel */
$kernel::init();
}
- $this-> endMeasure(self::MEASURE_TYPE_BOOT);
+ $this->endMeasure(self::MEASURE_TYPE_BOOT);
$this->startMeasure(self::MEASURE_TYPE_CLASS_LOADING);
$numbersClass = new Numbers();
- /** @var NumbersService[] $serviceInstances */
+ /** @var NumbersServiceInterface[] $serviceInstances */
$serviceInstances = [];
if (!$useAspects) {
foreach ($services as $service) {
- $serviceInstances[] = new $service();
+ $serviceClass = new ReflectionClass($service);
+ if (!$serviceClass->isInstantiable()) {
+ throw new Exception('Expected an instantiable benchmark service');
+ }
+ $serviceInstances[] = $serviceClass->newInstance();
}
}
@@ -205,7 +216,8 @@ public function measurePerformance(
// $expectedResults[] = $aspectCount;
// $actualResults[] = $result;
}
- } else {
+ }
+ if (!$useAspects) {
foreach (range(1, $aspectCount) as $i) {
$numbersService = $serviceInstances[$i - 1];
@@ -231,50 +243,46 @@ public function measurePerformance(
$this->saveMeasuresToFile();
if ($lastMeasure) {
- $this->printMeasures($this->dataName());
+ $this->printMeasures((string) $this->dataName());
}
$this->assertTrue(true);
}
/**
- * @return class-string
+ * @return class-string
*/
- private function createKernelAndAspects(
- int $aspectCount,
- bool $production
- ): string {
+ private function createKernelAndAspects(int $aspectCount, bool $production): string
+ {
$tempDirectory = __DIR__ . '/Temp';
if (!file_exists($tempDirectory)) {
Filesystem::mkdir($tempDirectory);
}
- $newKernelFilePath = "$tempDirectory/MeasurePerformanceKernel$aspectCount.php";
- $newKernelFileNamespace = "\\Okapi\\Aop\\Tests\\Performance\\Temp\\MeasurePerformanceKernel$aspectCount";
+ $newKernelFilePath = "{$tempDirectory}/MeasurePerformanceKernel{$aspectCount}.php";
+ /** @var class-string $newKernelFileNamespace */
+ $newKernelFileNamespace = "\\Okapi\\Aop\\Tests\\Performance\\Temp\\MeasurePerformanceKernel{$aspectCount}";
- static $kernelFile;
+ /** @var string|null $kernelFile */
+ static $kernelFile = null;
if (!$kernelFile) {
$kernelFile = Filesystem::readFile(__DIR__ . '/Kernel/MeasurePerformanceKernel.php');
}
$originalAspectLineNumber = 0;
- $originalAspectLine = '';
- $lines = explode("\n", $kernelFile);
+ $originalAspectLine = '';
+ $lines = explode("\n", $kernelFile);
foreach ($lines as $lineNumber => &$line) {
// Replace namespace
if (str_contains($line, 'namespace Okapi\\Aop\\Tests\\Performance\\Kernel')) {
- $line = str_replace(
- search: 'Kernel',
- replace: 'Temp',
- subject: $line,
- );
+ $line = str_replace(search: 'Kernel', replace: 'Temp', subject: $line);
}
// Replace class name
if (str_contains($line, 'class MeasurePerformanceKernel')) {
$line = str_replace(
search: 'MeasurePerformanceKernel',
- replace: "MeasurePerformanceKernel$aspectCount",
+ replace: "MeasurePerformanceKernel{$aspectCount}",
subject: $line,
);
}
@@ -282,7 +290,7 @@ private function createKernelAndAspects(
// Find the line where the "AddOneAspect" is added to the kernel
if (str_contains($line, 'AddOneAspect::class,')) {
$originalAspectLineNumber = $lineNumber;
- $originalAspectLine = $line;
+ $originalAspectLine = $line;
break;
}
@@ -300,17 +308,18 @@ private function createKernelAndAspects(
foreach (range(1, $aspectCount) as $aspectNumber) {
$aspects[] = str_replace(
search: 'Aspect\\AddOneAspect::class,',
- replace: "Temp\\AddOneAspect$aspectNumber::class,",
+ replace: "Temp\\AddOneAspect{$aspectNumber}::class,",
subject: $originalAspectLine,
);
// Read aspect file
- static $aspectFile;
+ /** @var string|null $aspectFile */
+ static $aspectFile = null;
if (!$aspectFile) {
$aspectFile = Filesystem::readFile(__DIR__ . '/Aspect/AddOneAspect.php');
}
- $newAspectFilePath = __DIR__ . "/Temp/AddOneAspect$aspectNumber.php";
+ $newAspectFilePath = __DIR__ . "/Temp/AddOneAspect{$aspectNumber}.php";
if (file_exists($newAspectFilePath)) {
continue;
}
@@ -327,15 +336,12 @@ private function createKernelAndAspects(
// Replace class name
$newAspectFile = str_replace(
search: 'class AddOneAspect',
- replace: "class AddOneAspect$aspectNumber",
+ replace: "class AddOneAspect{$aspectNumber}",
subject: $newAspectFile,
);
// Write aspect file
- Filesystem::writeFile(
- $newAspectFilePath,
- $newAspectFile,
- );
+ Filesystem::writeFile($newAspectFilePath, $newAspectFile);
$this->cacheFile($newAspectFilePath);
}
@@ -347,10 +353,7 @@ private function createKernelAndAspects(
$kernelFile = implode("\n", $lines);
// Write kernel file
- Filesystem::writeFile(
- $newKernelFilePath,
- $kernelFile,
- );
+ Filesystem::writeFile($newKernelFilePath, $kernelFile);
$this->cacheFile($newKernelFilePath);
@@ -360,7 +363,7 @@ private function createKernelAndAspects(
}
/**
- * @return class-string[]
+ * @return class-string[]
*/
private function createServices(int $serviceCount): array
{
@@ -372,15 +375,17 @@ private function createServices(int $serviceCount): array
$services = [];
foreach (range(1, $serviceCount) as $serviceNumber) {
// Read service file
- static $serviceFile;
+ /** @var string|null $serviceFile */
+ static $serviceFile = null;
if (!$serviceFile) {
$serviceFile = Filesystem::readFile(__DIR__ . '/Service/NumbersService.php');
}
- $serviceNamespace = "\\Okapi\\Aop\\Tests\\Performance\\Temp\\NumbersService$serviceNumber";
+ /** @var class-string $serviceNamespace */
+ $serviceNamespace = "\\Okapi\\Aop\\Tests\\Performance\\Temp\\NumbersService{$serviceNumber}";
$services[] = $serviceNamespace;
- $newServiceFilePath = __DIR__ . "/Temp/NumbersService$serviceNumber.php";
+ $newServiceFilePath = __DIR__ . "/Temp/NumbersService{$serviceNumber}.php";
if (file_exists($newServiceFilePath)) {
continue;
}
@@ -397,15 +402,12 @@ private function createServices(int $serviceCount): array
// Replace class name
$newServiceFile = str_replace(
search: 'class NumbersService',
- replace: "class NumbersService$serviceNumber",
+ replace: "class NumbersService{$serviceNumber}",
subject: $newServiceFile,
);
// Write service file
- Filesystem::writeFile(
- $newServiceFilePath,
- $newServiceFile,
- );
+ Filesystem::writeFile($newServiceFilePath, $newServiceFile);
$this->cacheFile($newServiceFilePath);
}
@@ -425,12 +427,12 @@ private function cacheFile(string $filename): void
private function dumpAutoload(): void
{
$workingDir = __DIR__ . '/../..';
- $workingDir = (DIRECTORY_SEPARATOR === '\\')
+ $workingDir = DIRECTORY_SEPARATOR === '\\'
? str_replace('/', '\\', $workingDir)
: str_replace('\\', '/', $workingDir);
ob_start();
- shell_exec("composer dump-autoload -d $workingDir -o -q");
+ shell_exec("composer dump-autoload -d {$workingDir} -o -q");
ob_end_clean();
}
@@ -456,20 +458,50 @@ private function saveMeasuresToFile(): void
{
$tempDirectory = __DIR__ . '/Temp';
- $measuresFile = "$tempDirectory/measures.json";
- if (!file_exists($measuresFile)) {
- $measures = $this->measures;
- } else {
- $measures = json_decode(Filesystem::readFile($measuresFile), true);
+ $measuresFile = "{$tempDirectory}/measures.json";
+ $measures = $this->measures;
+ if (file_exists($measuresFile)) {
+ $measures = $this->readMeasures($measuresFile);
$measures[$this->getMeasureType()] = $this->measures[$this->getMeasureType()];
}
// Save it every execution, because #[RunTestsInSeparateProcesses]
// will not store $this->measures between executions
- Filesystem::writeFile(
- $measuresFile,
- json_encode($measures, JSON_PRETTY_PRINT)
- );
+ Filesystem::writeFile($measuresFile, json_encode($measures, JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR));
+ }
+
+ /** @return array>> */
+ private function readMeasures(string $path): array
+ {
+ /** @var mixed $decoded */
+ $decoded = json_decode(Filesystem::readFile($path), true, flags: JSON_THROW_ON_ERROR);
+ if (!is_array($decoded)) {
+ throw new Exception('Expected measurement groups in ' . $path);
+ }
+
+ $measures = [];
+ /** @var mixed $group */
+ foreach ($decoded as $type => $group) {
+ if (!is_string($type) || !is_array($group)) {
+ throw new Exception('Invalid measurement group in ' . $path);
+ }
+ $measures[$type] = [];
+ /** @var mixed $metrics */
+ foreach ($group as $name => $metrics) {
+ if (!is_string($name) || !is_array($metrics)) {
+ throw new Exception('Invalid measurement in ' . $path);
+ }
+ $measures[$type][$name] = [];
+ /** @var mixed $value */
+ foreach ($metrics as $metric => $value) {
+ if (!is_string($metric) || !is_int($value) && !is_float($value)) {
+ throw new Exception('Invalid measurement metric in ' . $path);
+ }
+ $measures[$type][$name][$metric] = $value;
+ }
+ }
+ }
+ return $measures;
}
private function getMeasureType(): string
@@ -493,14 +525,11 @@ private function getMeasureType(): string
private function printMeasures(string $dataProviderLabel): void
{
- $this->measures = json_decode(
- json: Filesystem::readFile(__DIR__ . '/Temp/measures.json'),
- associative: true,
- );
+ $this->measures = $this->readMeasures(__DIR__ . '/Temp/measures.json');
// Remove the last measure, because it's the cleanup
$dataProviderLabel = str_replace(
- search: array_key_last($this->measures) . ': ',
+ search: (array_key_last($this->measures) ?? '') . ': ',
replace: '',
subject: $dataProviderLabel,
);
@@ -514,22 +543,22 @@ private function printMeasures(string $dataProviderLabel): void
$io->section($dataProviderLabel);
// First Table
- $output->writeln("Table 1: Without Aspects vs With Aspects ($dataProviderLabel)>");
+ $output->writeln("Table 1: Without Aspects vs With Aspects ({$dataProviderLabel})>");
$this->printTable($output, self::MEASURE_TYPE_ASPECTS);
// Second Table
$output->writeln('');
- $output->writeln("Table 2: Without Aspects vs With Cached Aspects ($dataProviderLabel)>");
+ $output->writeln("Table 2: Without Aspects vs With Cached Aspects ({$dataProviderLabel})>");
$this->printTable($output, self::MEASURE_TYPE_CACHED_ASPECTS);
// Third Table
$output->writeln('');
- $output->writeln("Table 3: Without Aspects vs Production ($dataProviderLabel)>");
+ $output->writeln("Table 3: Without Aspects vs Production ({$dataProviderLabel})>");
$this->printTable($output, self::MEASURE_TYPE_PRODUCTION);
// Fourth Table
$output->writeln('');
- $output->writeln("Table 4: With Cached Aspects vs Production ($dataProviderLabel)>");
+ $output->writeln("Table 4: With Cached Aspects vs Production ({$dataProviderLabel})>");
$this->printTable($output, self::MEASURE_TYPE_PRODUCTION, self::MEASURE_TYPE_CACHED_ASPECTS);
$output->writeln('');
@@ -538,7 +567,7 @@ private function printMeasures(string $dataProviderLabel): void
private function printTable(
ConsoleOutput $output,
string $comparisonAspect,
- string $compareToType = self::MEASURE_TYPE_NO_ASPECTS
+ string $compareToType = self::MEASURE_TYPE_NO_ASPECTS,
): void {
$table = new Table($output);
@@ -580,33 +609,32 @@ private function printTable(
$table->render();
}
+ /** @return list */
private function generateRowData(
string $measureType,
string $comparisonAspect,
string $compareToType,
- string $metricType
+ string $metricType,
): array {
// Get start and end metrics
- $startMetric = $metricType === self::METRIC_TYPE_TIME
- ? self::START_TIME
- : self::START_MEMORY;
+ $startMetric = $metricType === self::METRIC_TYPE_TIME ? self::START_TIME : self::START_MEMORY;
- $endMetric = $metricType === self::METRIC_TYPE_TIME
- ? self::END_TIME
- : self::END_MEMORY;
+ $endMetric = $metricType === self::METRIC_TYPE_TIME ? self::END_TIME : self::END_MEMORY;
// Calculate without aspects
- $withoutAspectsValue = $this->measures[$compareToType][$measureType][$endMetric]
+ $withoutAspectsValue =
+ $this->measures[$compareToType][$measureType][$endMetric]
- $this->measures[$compareToType][$measureType][$startMetric];
// Calculate with aspects
- $comparisonValue = $this->measures[$comparisonAspect][$measureType][$endMetric]
+ $comparisonValue =
+ $this->measures[$comparisonAspect][$measureType][$endMetric]
- $this->measures[$comparisonAspect][$measureType][$startMetric];
// For memory, convert to MB
if ($metricType === self::METRIC_TYPE_MEMORY) {
- $withoutAspectsValue /= (1024 * 1024);
- $comparisonValue /= (1024 * 1024);
+ $withoutAspectsValue /= 1024 * 1024;
+ $comparisonValue /= 1024 * 1024;
}
// Calculate difference
@@ -622,22 +650,19 @@ private function generateRowData(
// Prefix difference with + or -
$prefix = $difference > 0 ? '+' : '';
- $differenceText = "$prefix$difference";
+ $differenceText = "{$prefix}{$difference}";
// Append unit
- if ($metricType === self::METRIC_TYPE_TIME) {
- $append = ' s';
- } else {
- $append = ' MB';
- }
+ $append = $metricType === self::METRIC_TYPE_TIME ? ' s' : ' MB';
$withoutAspectsValue .= $append;
$comparisonValue .= $append;
$differenceText .= $append;
if ($difference > 0) {
- $differenceText = "$differenceText>";
- } elseif ($difference < 0) {
- $differenceText = "$differenceText>";
+ $differenceText = "{$differenceText}>";
+ }
+ if ($difference < 0) {
+ $differenceText = "{$differenceText}>";
}
return [
diff --git a/tests/Performance/Service/NumbersService.php b/tests/Performance/Service/NumbersService.php
index 560a130..c8dc967 100644
--- a/tests/Performance/Service/NumbersService.php
+++ b/tests/Performance/Service/NumbersService.php
@@ -4,7 +4,7 @@
use Okapi\Aop\Tests\Performance\Target\Numbers;
-class NumbersService
+class NumbersService implements \Okapi\Aop\Tests\Performance\Service\NumbersServiceInterface
{
public function addToNumbers(int $number, Numbers $numbers): void
{
diff --git a/tests/Performance/Service/NumbersServiceInterface.php b/tests/Performance/Service/NumbersServiceInterface.php
new file mode 100644
index 0000000..7de1725
--- /dev/null
+++ b/tests/Performance/Service/NumbersServiceInterface.php
@@ -0,0 +1,10 @@
+ */
private array $log = [];
public function log(string $message): void
@@ -15,6 +16,7 @@ public function log(string $message): void
$this->log[] = $message;
}
+ /** @return list */
public function getLogs(): array
{
return $this->log;
diff --git a/tests/Stubs/Etc/MailQueue.php b/tests/Stubs/Etc/MailQueue.php
index f5fab04..3deece0 100644
--- a/tests/Stubs/Etc/MailQueue.php
+++ b/tests/Stubs/Etc/MailQueue.php
@@ -8,6 +8,7 @@ class MailQueue
{
use Singleton;
+ /** @var list */
private array $mails = [];
public function addMail(string $mail): void
@@ -15,6 +16,7 @@ public function addMail(string $mail): void
$this->mails[] = $mail;
}
+ /** @return list */
public function getMails(): array
{
return $this->mails;
diff --git a/tests/Stubs/Etc/StackTrace.php b/tests/Stubs/Etc/StackTrace.php
index aaa3ba3..6dfe61c 100644
--- a/tests/Stubs/Etc/StackTrace.php
+++ b/tests/Stubs/Etc/StackTrace.php
@@ -8,6 +8,7 @@ class StackTrace
{
use Singleton;
+ /** @var list */
private array $stackTrace = [];
public function addTrace(string $trace): void
@@ -15,6 +16,7 @@ public function addTrace(string $trace): void
$this->stackTrace[] = $trace;
}
+ /** @return list */
public function getStackTrace(): array
{
return $this->stackTrace;
diff --git a/tests/Stubs/Kernel/EmptyKernel.php b/tests/Stubs/Kernel/EmptyKernel.php
index 5f2356c..e4621df 100644
--- a/tests/Stubs/Kernel/EmptyKernel.php
+++ b/tests/Stubs/Kernel/EmptyKernel.php
@@ -9,5 +9,6 @@ class EmptyKernel extends AopKernel
{
protected ?string $cacheDir = Util::CACHE_DIR;
+ /** @var array */
protected array $aspects = [];
}
diff --git a/tests/Util.php b/tests/Util.php
index 870ce3e..b2fb646 100644
--- a/tests/Util.php
+++ b/tests/Util.php
@@ -1,21 +1,17 @@
- $paths
+ * @return list}>
+ */
+function mago_type_issues(array $paths): array
+{
+ $stdout = mago_temp_file();
+ $stderr = mago_temp_file();
+ try {
+ $pipes = [];
+ $process = proc_open(
+ [
+ PHP_BINARY,
+ 'vendor/bin/mago',
+ '--config',
+ 'tools/mago/tests.toml',
+ 'analyze',
+ '--reporting-format',
+ 'json',
+ '--minimum-fail-level',
+ 'note',
+ ...$paths,
+ ],
+ [0 => ['pipe', 'r'], 1 => ['file', $stdout, 'w'], 2 => ['file', $stderr, 'w']],
+ $pipes,
+ dirname(__DIR__, 2),
+ );
+ if (!is_resource($process)) {
+ throw new RuntimeException('Cannot start Mago.');
+ }
+ if (array_key_exists(0, $pipes)) {
+ fclose($pipes[0]);
+ }
+ $status = proc_close($process);
+ $errors = trim(mago_read_file($stderr));
+ try {
+ /** @var array{issues: list}>} $report Mago JSON output schema. */
+ $report = json_decode(mago_read_file($stdout), true, flags: JSON_THROW_ON_ERROR);
+ } catch (JsonException $exception) {
+ throw new RuntimeException('Invalid Mago output: ' . $errors, previous: $exception);
+ }
+ if ($status !== ($report['issues'] === [] ? 0 : 1)) {
+ throw new RuntimeException('Unexpected Mago exit status: ' . $status . ' ' . $errors);
+ }
+ return $report['issues'];
+ } finally {
+ unlink($stdout);
+ unlink($stderr);
+ }
+}
+
+if (mago_type_issues(['tools/mago/tests/valid']) !== []) {
+ throw new RuntimeException('Valid dependency injection callbacks must pass analysis.');
+}
+
+$issues = mago_type_issues(['tools/mago/tests/valid', 'tools/mago/tests/invalid']);
+$actual = [];
+foreach ($issues as $issue) {
+ foreach ($issue['annotations'] as $annotation) {
+ if ($annotation['kind'] !== 'Primary') {
+ continue;
+ }
+ $actual[basename($annotation['span']['file_id']['name'])][] = $issue['code'];
+ break;
+ }
+}
+$expected = [
+ 'ScalarCallback.php' => ['invalid-return-statement'],
+ 'WrongBaseCallback.php' => ['invalid-return-statement'],
+ 'WrongManager.php' => ['invalid-argument'],
+ 'WrongReturn.php' => ['invalid-return-statement'],
+];
+ksort($actual);
+ksort($expected);
+if ($actual !== $expected || count($issues) !== 4) {
+ throw new RuntimeException(
+ 'Invalid callbacks must produce all four expected diagnostics: ' . json_encode($actual, JSON_THROW_ON_ERROR),
+ );
+}
+echo 'Mago type patch: valid callbacks accepted; all four invalid callbacks rejected.' . PHP_EOL;
diff --git a/tools/mago/patches/CodeTransformerKernel.php b/tools/mago/patches/CodeTransformerKernel.php
new file mode 100644
index 0000000..773fa38
--- /dev/null
+++ b/tools/mago/patches/CodeTransformerKernel.php
@@ -0,0 +1,20 @@
+): Transformer
+ */
+abstract class CodeTransformerKernel
+{
+ /** @return THandler|null */
+ protected function dependencyInjectionHandler(): ?Closure
+ {
+ return null;
+ }
+}
diff --git a/tools/mago/tests.toml b/tools/mago/tests.toml
new file mode 100644
index 0000000..3160a64
--- /dev/null
+++ b/tools/mago/tests.toml
@@ -0,0 +1,9 @@
+php-version = "8.1"
+
+[source]
+paths = ["tools/mago/tests/valid"]
+includes = ["src", "vendor"]
+patches = ["tools/mago/patches"]
+
+[analyzer]
+check-missing-type-hints = true
diff --git a/tools/mago/tests/invalid/ScalarCallback.php b/tools/mago/tests/invalid/ScalarCallback.php
new file mode 100644
index 0000000..c2a4a1d
--- /dev/null
+++ b/tools/mago/tests/invalid/ScalarCallback.php
@@ -0,0 +1,14 @@
+registerCustomDependencyInjectionHandler(
+ /** @param class-string $name */ static fn(string $name): string => 'invalid',
+ );
+}
diff --git a/tools/mago/tests/invalid/WrongReturn.php b/tools/mago/tests/invalid/WrongReturn.php
new file mode 100644
index 0000000..ce9d2d7
--- /dev/null
+++ b/tools/mago/tests/invalid/WrongReturn.php
@@ -0,0 +1,17 @@
+ $type
+ === ComponentType::ASPECT
+ ? new ExampleAspect()
+ : new ExampleTransformer();
+ }
+}
diff --git a/tools/mago/tests/valid/ValidManager.php b/tools/mago/tests/valid/ValidManager.php
new file mode 100644
index 0000000..8802c2e
--- /dev/null
+++ b/tools/mago/tests/valid/ValidManager.php
@@ -0,0 +1,14 @@
+registerCustomDependencyInjectionHandler(
+ /** @param class-string $name */ static fn(string $name): Transformer => new ExampleTransformer(),
+ );
+}