Skip to content

Commit 3e6b9ca

Browse files
authored
Merge pull request #64: Added Production/Development environment option
2 parents 1198af2 + 6ab28e8 commit 3e6b9ca

File tree

144 files changed

+1180
-715
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

144 files changed

+1180
-715
lines changed

.github/workflows/performance-tests.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
operating-system: [ ubuntu-latest ]
1616
php-version: [ '8.1', '8.2' ]
1717

18-
name: PHP ${{ matrix.php-version }} test on ${{ matrix.operating-system }}
18+
name: PHP ${{ matrix.php-version }} performance test on ${{ matrix.operating-system }}
1919

2020
steps:
2121
- name: Checkout Code
@@ -27,6 +27,7 @@ jobs:
2727
with:
2828
php-version: ${{ matrix.php-version }}
2929
coverage: none
30+
ini-values: opcache.enable_cli=1
3031

3132
- name: Check PHP version
3233
run: php -v
@@ -45,4 +46,4 @@ jobs:
4546
run: composer install --prefer-dist --no-progress
4647

4748
- name: PHPUnit Performance Tests
48-
run: vendor/bin/phpunit --testsuite=Performance
49+
run: vendor/bin/phpunit --testsuite=Performance --display-notices

.github/workflows/tests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
operating-system: [ ubuntu-latest ]
1717
php-version: [ '8.1', '8.2' ]
1818

19-
name: PHP ${{ matrix.php-version }} performance tests on ${{ matrix.operating-system }}
19+
name: PHP ${{ matrix.php-version }} tests on ${{ matrix.operating-system }}
2020

2121
steps:
2222
- name: Checkout Code
@@ -45,7 +45,7 @@ jobs:
4545
run: composer install --prefer-dist --no-progress
4646

4747
- name: PHPUnit Tests
48-
run: vendor/bin/phpunit --testsuite=Tests --coverage-clover ./tests/coverage.xml
48+
run: vendor/bin/phpunit --testsuite=Tests --coverage-clover ./tests/coverage.xml --display-notices
4949

5050
- name: Upload coverage reports to Codecov
5151
uses: codecov/codecov-action@v3

README.md

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ composer require okapi/aop
104104
- [How it works](#how-it-works)
105105
- [Testing](#testing)
106106
- [Contributing](#contributing)
107-
- [Roadmap](#roadmap)
108107

109108

110109

@@ -793,12 +792,6 @@ class EverythingAspect
793792

794793

795794

796-
## Roadmap
797-
798-
See [Roadmap](https://github.com/okapi-web/php-aop/issues/9) for more details.
799-
800-
801-
802795
## Show your support
803796

804797
Give a ⭐ if this project helped you!

composer.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "okapi/aop",
33
"description": "PHP AOP is a PHP library that provides a powerful Aspect Oriented Programming (AOP) implementation for PHP.",
4-
"version": "1.2.6",
4+
"version": "1.2.7",
55
"type": "library",
66
"homepage": "https://github.com/okapi-web/php-aop",
77
"license": "MIT",
@@ -19,14 +19,14 @@
1919
"php-aop"
2020
],
2121
"scripts": {
22-
"test": "phpunit --testsuite=Tests",
23-
"test-performance": "phpunit --testsuite=Performance",
24-
"test-coverage": "phpunit --coverage-html tests/coverage"
22+
"test": "phpunit --testsuite=Tests --display-notices",
23+
"test-performance": "phpunit --testsuite=Performance --display-notices",
24+
"test-coverage": "phpunit --testsuite=Tests --coverage-html tests/coverage --display-notices"
2525
},
2626
"require": {
2727
"php": ">=8.1",
2828
"nette/php-generator": "^4.0",
29-
"okapi/code-transformer": "^1.3",
29+
"okapi/code-transformer": "^1.3.4",
3030
"okapi/wildcards": "^1.0",
3131
"okapi/singleton": "^1.0",
3232
"php-di/php-di": "^7.0"

phpunit.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
<testsuites>
88
<testsuite name="Tests">
99
<directory>tests/Functional</directory>
10+
<directory>tests/Integration</directory>
1011
</testsuite>
1112

1213
<testsuite name="Performance">

src/AopKernel.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@
3030
*
3131
* The AOP Kernel is the heart of the AOP library.
3232
* It manages an environment for Aspect Oriented Programming.
33+
*
34+
* 1. Extend this class and define a list of aspects in the {@link $aspects}
35+
* property.
36+
* 2. Call the {@link init()} method early in the application lifecycle.
37+
*
38+
* If you want to modify the kernel options dynamically, override the
39+
* {@link configureOptions()} method.
3340
*/
3441
abstract class AopKernel extends CodeTransformerKernel
3542
{

src/Core/AutoloadInterceptor/ClassLoader.php

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Okapi\Aop\Core\Matcher\AspectMatcher;
77
use Okapi\CodeTransformer\Core\AutoloadInterceptor;
88
use Okapi\CodeTransformer\Core\AutoloadInterceptor\ClassLoader as CodeTransformerClassLoader;
9+
use Okapi\CodeTransformer\Core\Options\Environment;
910
use Okapi\CodeTransformer\Core\StreamFilter;
1011
use Okapi\CodeTransformer\Core\StreamFilter\FilterInjector;
1112
use Okapi\Path\Path;
@@ -35,6 +36,8 @@ class ClassLoader extends CodeTransformerClassLoader
3536
* @param class-string $namespacedClass
3637
*
3738
* @return false|string
39+
*
40+
* @noinspection PhpStatementHasEmptyBodyInspection
3841
*/
3942
public function findFile($namespacedClass): false|string
4043
{
@@ -58,13 +61,28 @@ public function findFile($namespacedClass): false|string
5861
// Query cache state
5962
$cacheState = $this->cacheStateManager->queryCacheState($filePath);
6063

61-
// If the cache is cached and up to date
62-
if ($cacheState?->isFresh() && !$this->options->isDebug()) {
64+
// When debugging, bypass the caching mechanism
65+
if ($this->options->isDebug()) {
66+
// ...
67+
}
68+
69+
// In production mode, use the cache without checking if it is fresh
70+
elseif ($this->options->getEnvironment() === Environment::PRODUCTION
71+
&& $cacheState
72+
) {
6373
// Use the cached file if aspects have been applied
6474
// Or return the original file if no aspects have been applied
6575
return $cacheState->getFilePath() ?? $filePath;
6676
}
6777

78+
// In development mode, check if the cache is fresh
79+
elseif ($this->options->getEnvironment() === Environment::DEVELOPMENT
80+
&& $cacheState
81+
&& $cacheState->isFresh()
82+
) {
83+
return $cacheState->getFilePath() ?? $filePath;
84+
}
85+
6886

6987
// Match the aspects
7088
$matchedAspects = $this->aspectMatcher->matchByClassLoader(

src/Core/Container/AspectManager.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,9 @@ public function loadAspect(mixed $aspectClassName): void
112112
{
113113
// Check if the aspect is already loaded
114114
if (array_key_exists($aspectClassName, $this->aspectAdviceContainers)) {
115+
// @codeCoverageIgnoreStart
115116
return;
117+
// @codeCoverageIgnoreEnd
116118
}
117119

118120
// Validate the aspect

src/Core/Invocation/AdviceChainAwareTrait.php

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,12 @@ public function setAdviceChain(AdviceChain $adviceChain): void
2828
/**
2929
* Call next advice or target method.
3030
*
31-
* @param bool $allowRepeatedCalls <br>If {@see true}, the original method
32-
* will be called again.<br>
33-
* If {@see false}, the original method will
34-
* be called only once and every subsequent
35-
* call will return the same result.<br>
36-
* Default: {@see false}<br>
37-
* <b>WARNING: May cause unexpected behavior
38-
* and side effects.</b>
31+
* @param bool $allowRepeatedCalls
32+
* <br>If {@see true}, the original method will be called again.<br>
33+
* If {@see false}, the original method will be called only once and every
34+
* subsequent call will return the same result.<br>
35+
* Default: {@see false}<br>
36+
* <b>WARNING: May cause unexpected behavior and side effects.</b>
3937
*
4038
* @return mixed
4139
*/

tests/ClassLoaderMockTrait.php

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<?php
2+
3+
namespace Okapi\Aop\Tests;
4+
5+
use Okapi\Aop\Core\AutoloadInterceptor\ClassLoader;
6+
use Okapi\Aop\Core\Cache\CachePaths;
7+
use Okapi\CodeTransformer\Core\DI;
8+
use Okapi\CodeTransformer\Core\StreamFilter;
9+
use Okapi\CodeTransformer\Core\StreamFilter\FilterInjector;
10+
use Okapi\Path\Path;
11+
use PHPUnit\Framework\Assert;
12+
use ReflectionProperty;
13+
14+
trait ClassLoaderMockTrait
15+
{
16+
private ?ClassLoader $classLoader = null;
17+
18+
private function findClassMock(string $class): string
19+
{
20+
if (!isset($this->classLoader)) {
21+
$this->findClassLoader();
22+
}
23+
24+
return $this->classLoader->findFile($class);
25+
}
26+
27+
private function findOriginalClassMock(string $class): string
28+
{
29+
if (!isset($this->classLoader)) {
30+
$this->findClassLoader();
31+
}
32+
33+
$original = new ReflectionProperty(ClassLoader::class, 'originalClassLoader');
34+
$original = $original->getValue($this->classLoader);
35+
return $original->findFile($class);
36+
}
37+
38+
private function findClassLoader(): void
39+
{
40+
foreach (spl_autoload_functions() as $function) {
41+
if (is_array($function) && $function[0] instanceof ClassLoader) {
42+
$this->classLoader = $function[0];
43+
break;
44+
}
45+
}
46+
}
47+
48+
public function assertWillBeWoven(string $className): void
49+
{
50+
$originalFilePath = Path::resolve($this->findOriginalClassMock($className));
51+
52+
$wovenPath =
53+
FilterInjector::PHP_FILTER_READ .
54+
StreamFilter::FILTER_ID . '/resource=' .
55+
$originalFilePath;
56+
57+
$filePathMock = $this->findClassMock($className);
58+
59+
Assert::assertEquals(
60+
$wovenPath,
61+
$filePathMock,
62+
"$className will not be woven",
63+
);
64+
}
65+
66+
public function assertAspectLoadedFromCache(string $className): void
67+
{
68+
$filePath = $this->findOriginalClassMock($className);
69+
$cachePaths = DI::get(CachePaths::class);
70+
$cachePath = $cachePaths->getProxyCachePath($filePath);
71+
$filePathMock = $this->findClassMock($className);
72+
73+
Assert::assertEquals(
74+
$cachePath,
75+
$filePathMock,
76+
"$className will not be loaded from cache",
77+
);
78+
}
79+
80+
public function assertAspectNotApplied(string $className): void
81+
{
82+
$originalFilePath = Path::resolve($this->findOriginalClassMock($className));
83+
$filePathMock = $this->findClassMock($className);
84+
85+
Assert::assertEquals(
86+
$originalFilePath,
87+
$filePathMock,
88+
"$className will be woven",
89+
);
90+
}
91+
}

0 commit comments

Comments
 (0)