Add tests for InstanceManager and remove Decorator hook logic (avoid complex Dice logic)
This commit is contained in:
parent
527622df4a
commit
93af6f0564
14 changed files with 218 additions and 390 deletions
|
@ -1,159 +0,0 @@
|
||||||
Friendica strategy and decorator Hooks
|
|
||||||
===========================================
|
|
||||||
|
|
||||||
* [Home](help)
|
|
||||||
|
|
||||||
## Strategy hooks
|
|
||||||
|
|
||||||
This type of hook is based on the [Strategy Design Pattern](https://refactoring.guru/design-patterns/strategy).
|
|
||||||
|
|
||||||
A strategy class defines a possible implementation of a given interface based on a unique name.
|
|
||||||
Every name is possible as long as it's unique and not `null`.
|
|
||||||
Using an empty name (`''`) is possible as well and should be used as the "default" implementation.
|
|
||||||
To register a strategy, use the [`ICanRegisterInstance`](../src/Core/Hooks/Capabilities/ICanRegisterInstances.php) interface.
|
|
||||||
|
|
||||||
After registration, a caller can automatically create this instance with the [`ICanCreateInstances`](../src/Core/Hooks/Capabilities/ICanCreateInstances.php) interface and the chosen name.
|
|
||||||
|
|
||||||
This is useful in case there are different, possible implementations for the same purpose, like for logging, locking, caching, ...
|
|
||||||
|
|
||||||
Normally, a config entry is used to choose the right implementation at runtime.
|
|
||||||
And if no config entry is set, the "default" implementation should be used.
|
|
||||||
|
|
||||||
### Example
|
|
||||||
|
|
||||||
```php
|
|
||||||
interface ExampleInterface
|
|
||||||
{
|
|
||||||
public function testMethod();
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ConcreteClassA implements ExampleInterface
|
|
||||||
{
|
|
||||||
public function testMethod()
|
|
||||||
{
|
|
||||||
echo "concrete class A";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ConcreteClassB implements ExampleInterface
|
|
||||||
{
|
|
||||||
public function testMethod()
|
|
||||||
{
|
|
||||||
echo "concrete class B";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @var \Friendica\Core\Hooks\Capabilities\ICanRegisterInstances $instanceRegister */
|
|
||||||
$instanceRegister->registerStrategy(ExampleInterface::class, ConcreteClassA::class, 'A');
|
|
||||||
$instanceRegister->registerStrategy(ExampleInterface::class, ConcreteClassB::class, 'B');
|
|
||||||
|
|
||||||
/** @var \Friendica\Core\Hooks\Capabilities\ICanCreateInstances $instanceManager */
|
|
||||||
/** @var ConcreteClassA $concreteClass */
|
|
||||||
$concreteClass = $instanceManager->createWithName(ExampleInterface::class, 'A');
|
|
||||||
|
|
||||||
$concreteClass->testMethod();
|
|
||||||
// output:
|
|
||||||
// "concrete class A";
|
|
||||||
```
|
|
||||||
|
|
||||||
## Decorator hooks
|
|
||||||
|
|
||||||
This type of hook is based on the [Decorator Design Pattern](https://refactoring.guru/design-patterns/decorator).
|
|
||||||
|
|
||||||
A decorator class extends a given strategy instance (see [Strategy hooks](#strategy-hooks)]).
|
|
||||||
To register a decorator, use the [`ICanRegisterInstance`](../src/Core/Hooks/Capabilities/ICanRegisterInstances.php) interface.
|
|
||||||
|
|
||||||
After registration, a caller can automatically create an instance with the [`ICanCreateInstances`](../src/Core/Hooks/Capabilities/ICanCreateInstances.php) interface and the decorator will wrap its logic around the call.
|
|
||||||
|
|
||||||
This is useful in case you want to extend a given class but the given class isn't responsible for these business logic. Or you want to extend an interface without knowing the concrete implementation.
|
|
||||||
For example profiling logger calls, Friendica is using a [`ProfilerLogger`](../src/Core/Logger/Type/ProfilerLogger.php), which wraps all other logging implementations and traces each log call.
|
|
||||||
|
|
||||||
Normally, a config entry is used to enable/disable decorator.
|
|
||||||
|
|
||||||
### Example
|
|
||||||
|
|
||||||
```php
|
|
||||||
interface ExampleInterface
|
|
||||||
{
|
|
||||||
public function testMethod();
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ConcreteClassA implements ExampleInterface
|
|
||||||
{
|
|
||||||
public function testMethod()
|
|
||||||
{
|
|
||||||
echo "concrete class A";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class DecoratorClassA implements ExampleInterface
|
|
||||||
{
|
|
||||||
/** @var ExampleInterface */
|
|
||||||
protected $example;
|
|
||||||
|
|
||||||
public function __construct(ExampleInterface $example)
|
|
||||||
{
|
|
||||||
$this->example = $example;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testMethod()
|
|
||||||
{
|
|
||||||
echo "decorated!\n";
|
|
||||||
$this->example->testMethod();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @var \Friendica\Core\Hooks\Capabilities\ICanRegisterInstances $instanceRegister */
|
|
||||||
$instanceRegister->registerStrategy(ExampleInterface::class, ConcreteClassA::class, 'A');
|
|
||||||
$instanceRegister->registerDecorator(ExampleInterface::class, DecoratorClassA::class);
|
|
||||||
|
|
||||||
/** @var \Friendica\Core\Hooks\Capabilities\ICanCreateInstances $instanceManager */
|
|
||||||
/** @var ConcreteClassA $concreteClass */
|
|
||||||
$concreteClass = $instanceManager->createWithName(ExampleInterface::class, 'A');
|
|
||||||
|
|
||||||
$concreteClass->testMethod();
|
|
||||||
// output:
|
|
||||||
// "decorated!"
|
|
||||||
// "concrete class A";
|
|
||||||
```
|
|
||||||
|
|
||||||
## hooks.config.php
|
|
||||||
|
|
||||||
To avoid registering all strategies and decorators manually inside the code, Friendica introduced the [`hooks.config.php`](../static/hooks.config.php) file.
|
|
||||||
|
|
||||||
There, you can register all kind of strategies and decorators in one file.
|
|
||||||
|
|
||||||
### [`HookType::STRATEGY`](../src/Core/Hooks/Capabilities/HookType.php)
|
|
||||||
|
|
||||||
For each given interface, a list of key-value pairs can be set, where the key is the concrete implementation class and the value is an array of unique names.
|
|
||||||
|
|
||||||
### [`HookType::DECORATOR`](../src/Core/Hooks/Capabilities/HookType.php)
|
|
||||||
|
|
||||||
For each given interface, a list of concrete decorator classes can be set.
|
|
||||||
|
|
||||||
### Example
|
|
||||||
|
|
||||||
```php
|
|
||||||
use Friendica\Core\Hooks\Capabilities\HookType as H;
|
|
||||||
|
|
||||||
return [
|
|
||||||
H::STRATEGY => [
|
|
||||||
ExampleInterface::class => [
|
|
||||||
ConcreteClassA::class => ['A'],
|
|
||||||
ConcreteClassB::class => ['B'],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
H::DECORATOR => [
|
|
||||||
ExampleInterface::class => [
|
|
||||||
DecoratorClassA::class,
|
|
||||||
],
|
|
||||||
],
|
|
||||||
];
|
|
||||||
```
|
|
||||||
|
|
||||||
## Addons
|
|
||||||
|
|
||||||
The hook logic is useful for decoupling the Friendica core logic, but its primary goal is to modularize Friendica in creating addons.
|
|
||||||
|
|
||||||
Therefor you can either use the interfaces directly as shown above, or you can place your own `hooks.config.php` file inside a `static` directory directly under your addon core directory.
|
|
||||||
Friendica will automatically search these config files for each **activated** addon and register the given hooks.
|
|
89
doc/StrategyHooks.md
Normal file
89
doc/StrategyHooks.md
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
Friendica strategy Hooks
|
||||||
|
===========================================
|
||||||
|
|
||||||
|
* [Home](help)
|
||||||
|
|
||||||
|
## Strategy hooks
|
||||||
|
|
||||||
|
This type of hook is based on the [Strategy Design Pattern](https://refactoring.guru/design-patterns/strategy).
|
||||||
|
|
||||||
|
A strategy class defines a possible implementation of a given interface based on a unique name.
|
||||||
|
Every name is possible as long as it's unique and not `null`.
|
||||||
|
Using an empty name (`''`) is possible as well and should be used as the "default" implementation.
|
||||||
|
To register a strategy, use the [`ICanRegisterInstance`](../src/Core/Hooks/Capabilities/ICanRegisterInstances.php) interface.
|
||||||
|
|
||||||
|
After registration, a caller can automatically create this instance with the [`ICanCreateInstances`](../src/Core/Hooks/Capabilities/ICanCreateInstances.php) interface and the chosen name.
|
||||||
|
|
||||||
|
This is useful in case there are different, possible implementations for the same purpose, like for logging, locking, caching, ...
|
||||||
|
|
||||||
|
Normally, a config entry is used to choose the right implementation at runtime.
|
||||||
|
And if no config entry is set, the "default" implementation should be used.
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
```php
|
||||||
|
interface ExampleInterface
|
||||||
|
{
|
||||||
|
public function testMethod();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ConcreteClassA implements ExampleInterface
|
||||||
|
{
|
||||||
|
public function testMethod()
|
||||||
|
{
|
||||||
|
echo "concrete class A";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ConcreteClassB implements ExampleInterface
|
||||||
|
{
|
||||||
|
public function testMethod()
|
||||||
|
{
|
||||||
|
echo "concrete class B";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var \Friendica\Core\Hooks\Capabilities\ICanRegisterInstances $instanceRegister */
|
||||||
|
$instanceRegister->registerStrategy(ExampleInterface::class, ConcreteClassA::class, 'A');
|
||||||
|
$instanceRegister->registerStrategy(ExampleInterface::class, ConcreteClassB::class, 'B');
|
||||||
|
|
||||||
|
/** @var \Friendica\Core\Hooks\Capabilities\ICanCreateInstances $instanceManager */
|
||||||
|
/** @var ConcreteClassA $concreteClass */
|
||||||
|
$concreteClass = $instanceManager->create(ExampleInterface::class, 'A');
|
||||||
|
|
||||||
|
$concreteClass->testMethod();
|
||||||
|
// output:
|
||||||
|
// "concrete class A";
|
||||||
|
```
|
||||||
|
|
||||||
|
## hooks.config.php
|
||||||
|
|
||||||
|
To avoid registering all strategies manually inside the code, Friendica introduced the [`hooks.config.php`](../static/hooks.config.php) file.
|
||||||
|
|
||||||
|
There, you can register all kind of strategies in one file.
|
||||||
|
|
||||||
|
### [`HookType::STRATEGY`](../src/Core/Hooks/Capabilities/HookType.php)
|
||||||
|
|
||||||
|
For each given interface, a list of key-value pairs can be set, where the key is the concrete implementation class and the value is an array of unique names.
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
```php
|
||||||
|
use Friendica\Core\Hooks\Capabilities\BehavioralHookType as H;
|
||||||
|
|
||||||
|
return [
|
||||||
|
H::STRATEGY => [
|
||||||
|
ExampleInterface::class => [
|
||||||
|
ConcreteClassA::class => ['A'],
|
||||||
|
ConcreteClassB::class => ['B'],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
## Addons
|
||||||
|
|
||||||
|
The hook logic is useful for decoupling the Friendica core logic, but its primary goal is to modularize Friendica in creating addons.
|
||||||
|
|
||||||
|
Therefor you can either use the interfaces directly as shown above, or you can place your own `hooks.config.php` file inside a `static` directory directly under your addon core directory.
|
||||||
|
Friendica will automatically search these config files for each **activated** addon and register the given hooks.
|
|
@ -21,7 +21,11 @@
|
||||||
|
|
||||||
namespace Friendica\Core\Hooks\Capabilities;
|
namespace Friendica\Core\Hooks\Capabilities;
|
||||||
|
|
||||||
interface HookType
|
/**
|
||||||
|
* An enum of hook types, based on behavioral design patterns
|
||||||
|
* @see https://refactoring.guru/design-patterns/behavioral-patterns
|
||||||
|
*/
|
||||||
|
interface BehavioralHookType
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Defines the key for the list of strategy-hooks.
|
* Defines the key for the list of strategy-hooks.
|
||||||
|
@ -29,11 +33,5 @@ interface HookType
|
||||||
* @see https://refactoring.guru/design-patterns/strategy
|
* @see https://refactoring.guru/design-patterns/strategy
|
||||||
*/
|
*/
|
||||||
const STRATEGY = 'strategy';
|
const STRATEGY = 'strategy';
|
||||||
/**
|
|
||||||
* Defines the key for the list of decorator-hooks.
|
|
||||||
*
|
|
||||||
* @see https://refactoring.guru/design-patterns/decorator
|
|
||||||
*/
|
|
||||||
const DECORATOR = 'decorator';
|
|
||||||
const EVENT = 'event';
|
const EVENT = 'event';
|
||||||
}
|
}
|
|
@ -22,7 +22,7 @@
|
||||||
namespace Friendica\Core\Hooks\Capabilities;
|
namespace Friendica\Core\Hooks\Capabilities;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* creates special instance and decorator treatments for given classes
|
* creates special instances for given classes
|
||||||
*/
|
*/
|
||||||
interface ICanCreateInstances
|
interface ICanCreateInstances
|
||||||
{
|
{
|
||||||
|
@ -31,27 +31,11 @@ interface ICanCreateInstances
|
||||||
*
|
*
|
||||||
* The instance will be build based on the registered strategy and the (unique) name
|
* The instance will be build based on the registered strategy and the (unique) name
|
||||||
*
|
*
|
||||||
* In case, there are registered decorators for this class as well, all decorators of the list will be wrapped
|
|
||||||
* around the instance before returning it
|
|
||||||
*
|
|
||||||
* @param string $class The fully-qualified name of the given class or interface which will get returned
|
* @param string $class The fully-qualified name of the given class or interface which will get returned
|
||||||
* @param string $name An arbitrary identifier to find a concrete instance strategy.
|
* @param string $name An arbitrary identifier to find a concrete instance strategy.
|
||||||
* @param array $arguments Additional arguments, which can be passed to the constructor of "$class" at runtime
|
* @param array $arguments Additional arguments, which can be passed to the constructor of "$class" at runtime
|
||||||
*
|
*
|
||||||
* @return object The concrete instance of the type "$class"
|
* @return object The concrete instance of the type "$class"
|
||||||
*/
|
*/
|
||||||
public function createWithName(string $class, string $name, array $arguments = []): object;
|
public function create(string $class, string $name, array $arguments = []): object;
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a new instance of a given class
|
|
||||||
*
|
|
||||||
* In case, there are registered decorators for this class as well, all decorators of the list will be wrapped
|
|
||||||
* around the instance before returning it
|
|
||||||
*
|
|
||||||
* @param string $class The fully-qualified name of the given class or interface which will get returned
|
|
||||||
* @param array $arguments Additional arguments, which can be passed to the constructor of "$class" at runtime
|
|
||||||
*
|
|
||||||
* @return object The concrete instance of the type "$class"
|
|
||||||
*/
|
|
||||||
public function create(string $class, array $arguments = []): object;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace Friendica\Core\Hooks\Capabilities;
|
||||||
use Friendica\Core\Hooks\Exceptions\HookRegisterArgumentException;
|
use Friendica\Core\Hooks\Exceptions\HookRegisterArgumentException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register strategies and decorator/treatment handling for given classes
|
* Register strategies for given classes
|
||||||
*/
|
*/
|
||||||
interface ICanRegisterInstances
|
interface ICanRegisterInstances
|
||||||
{
|
{
|
||||||
|
@ -43,21 +43,4 @@ interface ICanRegisterInstances
|
||||||
* @throws HookRegisterArgumentException in case the given class for the interface isn't valid or already set
|
* @throws HookRegisterArgumentException in case the given class for the interface isn't valid or already set
|
||||||
*/
|
*/
|
||||||
public function registerStrategy(string $interface, string $class, ?string $name = null): self;
|
public function registerStrategy(string $interface, string $class, ?string $name = null): self;
|
||||||
|
|
||||||
/**
|
|
||||||
* Register a new decorator for a given class or interface
|
|
||||||
*
|
|
||||||
* @see https://refactoring.guru/design-patterns/decorator
|
|
||||||
*
|
|
||||||
* @note Decorator attach new behaviors to classes without changing them or without letting them know about it.
|
|
||||||
*
|
|
||||||
* @param string $class The fully-qualified class or interface name, which gets decorated by a class
|
|
||||||
* @param string $decoratorClass The fully-qualified name of the class which mimics the given class or interface and adds new functionality
|
|
||||||
* A placeholder for dependencies is possible as well
|
|
||||||
*
|
|
||||||
* @return $this This interface for chain-calls
|
|
||||||
*
|
|
||||||
* @throws HookRegisterArgumentException in case the given class for the class or interface isn't valid
|
|
||||||
*/
|
|
||||||
public function registerDecorator(string $class, string $decoratorClass): self;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,6 @@ use Friendica\Core\Hooks\Util\HookFileManager;
|
||||||
class DiceInstanceManager implements ICanCreateInstances, ICanRegisterInstances
|
class DiceInstanceManager implements ICanCreateInstances, ICanRegisterInstances
|
||||||
{
|
{
|
||||||
protected $instance = [];
|
protected $instance = [];
|
||||||
protected $decorator = [];
|
|
||||||
|
|
||||||
/** @var Dice */
|
/** @var Dice */
|
||||||
protected $dice;
|
protected $dice;
|
||||||
|
@ -60,52 +59,12 @@ class DiceInstanceManager implements ICanCreateInstances, ICanRegisterInstances
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
public function registerDecorator(string $class, string $decoratorClass): ICanRegisterInstances
|
public function create(string $class, string $name, array $arguments = []): object
|
||||||
{
|
|
||||||
$this->decorator[$class][] = $decoratorClass;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
|
||||||
public function create(string $class, array $arguments = []): object
|
|
||||||
{
|
|
||||||
$instanceClassName = $class;
|
|
||||||
$instanceRule = $this->dice->getRule($instanceClassName) ?? [];
|
|
||||||
|
|
||||||
$instanceRule = array_replace_recursive($instanceRule, [
|
|
||||||
'constructParams' => $arguments,
|
|
||||||
]);
|
|
||||||
|
|
||||||
$this->dice = $this->dice->addRule($instanceClassName, $instanceRule);
|
|
||||||
|
|
||||||
foreach ($this->decorator[$class] ?? [] as $decorator) {
|
|
||||||
$dependencyRule = $this->dice->getRule($decorator);
|
|
||||||
for ($i = 0; $i < count($dependencyRule['call'] ?? []); $i++) {
|
|
||||||
$dependencyRule['call'][$i][1] = [[Dice::INSTANCE => $instanceClassName]];
|
|
||||||
}
|
|
||||||
$dependencyRule['constructParams'] = $arguments;
|
|
||||||
$dependencyRule['substitutions'] = [
|
|
||||||
$class => $instanceClassName,
|
|
||||||
];
|
|
||||||
|
|
||||||
$this->dice = $this->dice->addRule($decorator, $dependencyRule);
|
|
||||||
|
|
||||||
$instanceClassName = $decorator;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->dice->create($instanceClassName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
|
||||||
public function createWithName(string $class, string $name, array $arguments = []): object
|
|
||||||
{
|
{
|
||||||
if (empty($this->instance[$class][$name])) {
|
if (empty($this->instance[$class][$name])) {
|
||||||
throw new HookInstanceException(sprintf('The class with the name %s isn\'t registered for the class or interface %s', $name, $class));
|
throw new HookInstanceException(sprintf('The class with the name %s isn\'t registered for the class or interface %s', $name, $class));
|
||||||
}
|
}
|
||||||
|
|
||||||
$instanceClassName = $this->instance[$class][$name];
|
return $this->dice->create($this->instance[$class][$name], $arguments);
|
||||||
|
|
||||||
return $this->create($instanceClassName, $arguments);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
namespace Friendica\Core\Hooks\Util;
|
namespace Friendica\Core\Hooks\Util;
|
||||||
|
|
||||||
use Friendica\Core\Addon\Capabilities\ICanLoadAddons;
|
use Friendica\Core\Addon\Capabilities\ICanLoadAddons;
|
||||||
use Friendica\Core\Hooks\Capabilities\HookType;
|
use Friendica\Core\Hooks\Capabilities\BehavioralHookType;
|
||||||
use Friendica\Core\Hooks\Capabilities\ICanRegisterInstances;
|
use Friendica\Core\Hooks\Capabilities\ICanRegisterInstances;
|
||||||
use Friendica\Core\Hooks\Exceptions\HookConfigException;
|
use Friendica\Core\Hooks\Exceptions\HookConfigException;
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ class HookFileManager
|
||||||
|
|
||||||
foreach ($this->hookConfig as $hookType => $classList) {
|
foreach ($this->hookConfig as $hookType => $classList) {
|
||||||
switch ($hookType) {
|
switch ($hookType) {
|
||||||
case HookType::STRATEGY:
|
case BehavioralHookType::STRATEGY:
|
||||||
foreach ($classList as $interface => $strategy) {
|
foreach ($classList as $interface => $strategy) {
|
||||||
foreach ($strategy as $dependencyName => $names) {
|
foreach ($strategy as $dependencyName => $names) {
|
||||||
if (is_array($names)) {
|
if (is_array($names)) {
|
||||||
|
@ -76,17 +76,6 @@ class HookFileManager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case HookType::DECORATOR:
|
|
||||||
foreach ($classList as $interface => $decorators) {
|
|
||||||
if (is_array($decorators)) {
|
|
||||||
foreach ($decorators as $decorator) {
|
|
||||||
$instanceRegister->registerDecorator($interface, $decorator);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$instanceRegister->registerDecorator($interface, $decorators);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,8 @@ namespace Friendica\Core\Logger\Factory;
|
||||||
use Friendica\Core\Config\Capability\IManageConfigValues;
|
use Friendica\Core\Config\Capability\IManageConfigValues;
|
||||||
use Friendica\Core\Hooks\Capabilities\ICanCreateInstances;
|
use Friendica\Core\Hooks\Capabilities\ICanCreateInstances;
|
||||||
use Friendica\Core\Logger\Capabilities\LogChannel;
|
use Friendica\Core\Logger\Capabilities\LogChannel;
|
||||||
|
use Friendica\Core\Logger\Type\ProfilerLogger as ProfilerLoggerClass;
|
||||||
|
use Friendica\Util\Profiler;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use Psr\Log\NullLogger;
|
use Psr\Log\NullLogger;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
@ -41,7 +43,7 @@ class Logger
|
||||||
$this->channel = $channel;
|
$this->channel = $channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function create(ICanCreateInstances $createInstances, IManageConfigValues $config): LoggerInterface
|
public function create(ICanCreateInstances $createInstances, IManageConfigValues $config, Profiler $profiler): LoggerInterface
|
||||||
{
|
{
|
||||||
if (empty($config->get('system', 'debugging') ?? false)) {
|
if (empty($config->get('system', 'debugging') ?? false)) {
|
||||||
return new NullLogger();
|
return new NullLogger();
|
||||||
|
@ -50,7 +52,13 @@ class Logger
|
||||||
$name = $config->get('system', 'logger_config') ?? '';
|
$name = $config->get('system', 'logger_config') ?? '';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return $createInstances->createWithName(LoggerInterface::class, $name, [$this->channel]);
|
/** @var LoggerInterface $logger */
|
||||||
|
$logger = $createInstances->create(LoggerInterface::class, $name, [$this->channel]);
|
||||||
|
if ($config->get('system', 'profiling') ?? false) {
|
||||||
|
return new ProfilerLoggerClass($logger, $profiler);
|
||||||
|
} else {
|
||||||
|
return $logger;
|
||||||
|
}
|
||||||
} catch (Throwable $e) {
|
} catch (Throwable $e) {
|
||||||
// No logger ...
|
// No logger ...
|
||||||
return new NullLogger();
|
return new NullLogger();
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use Friendica\Core\Hooks\Capabilities\HookType as H;
|
use Friendica\Core\Hooks\Capabilities\BehavioralHookType as H;
|
||||||
use Friendica\Core\Logger\Type;
|
use Friendica\Core\Logger\Type;
|
||||||
use Psr\Log;
|
use Psr\Log;
|
||||||
|
|
||||||
|
@ -31,9 +31,4 @@ return [
|
||||||
Type\StreamLogger::class => ['stream'],
|
Type\StreamLogger::class => ['stream'],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
H::DECORATOR => [
|
|
||||||
Log\LoggerInterface::class => [
|
|
||||||
Type\ProfilerLogger::class,
|
|
||||||
],
|
|
||||||
],
|
|
||||||
];
|
];
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
namespace Friendica\Test\Util\Hooks\InstanceMocks;
|
namespace Friendica\Test\Util\Hooks\InstanceMocks;
|
||||||
|
|
||||||
class FakeInstance
|
class FakeInstance implements IAmADecoratedInterface
|
||||||
{
|
{
|
||||||
protected $aText = null;
|
protected $aText = null;
|
||||||
protected $cBool = null;
|
protected $cBool = null;
|
||||||
|
@ -39,6 +39,8 @@ class FakeInstance
|
||||||
$this->aText = $aText;
|
$this->aText = $aText;
|
||||||
$this->cBool = $cBool;
|
$this->cBool = $cBool;
|
||||||
$this->bText = $bText;
|
$this->bText = $bText;
|
||||||
|
|
||||||
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAText(): ?string
|
public function getAText(): ?string
|
||||||
|
|
|
@ -25,14 +25,14 @@ class FakeInstanceDecorator implements IAmADecoratedInterface
|
||||||
{
|
{
|
||||||
public static $countInstance = 0;
|
public static $countInstance = 0;
|
||||||
|
|
||||||
|
const PREFIX = 'prefix1';
|
||||||
|
|
||||||
/** @var IAmADecoratedInterface */
|
/** @var IAmADecoratedInterface */
|
||||||
protected $orig;
|
protected $orig;
|
||||||
protected $prefix = '';
|
|
||||||
|
|
||||||
public function __construct(IAmADecoratedInterface $orig, string $prefix = '')
|
public function __construct(IAmADecoratedInterface $orig)
|
||||||
{
|
{
|
||||||
$this->orig = $orig;
|
$this->orig = $orig;
|
||||||
$this->prefix = $prefix;
|
|
||||||
|
|
||||||
self::$countInstance++;
|
self::$countInstance++;
|
||||||
}
|
}
|
||||||
|
@ -44,16 +44,16 @@ class FakeInstanceDecorator implements IAmADecoratedInterface
|
||||||
|
|
||||||
public function getAText(): ?string
|
public function getAText(): ?string
|
||||||
{
|
{
|
||||||
return $this->prefix . $this->orig->getAText();
|
return static::PREFIX . $this->orig->getAText();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBText(): ?string
|
public function getBText(): ?string
|
||||||
{
|
{
|
||||||
return $this->prefix . $this->orig->getBText();
|
return static::PREFIX . $this->orig->getBText();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getCBool(): ?bool
|
public function getCBool(): ?bool
|
||||||
{
|
{
|
||||||
return $this->prefix . $this->orig->getCBool();
|
return static::PREFIX . $this->orig->getCBool();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ class AddonLoaderTest extends MockedTest
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
\Friendica\Core\Hooks\Capabilities\HookType::STRATEGY => [
|
\Friendica\Core\Hooks\Capabilities\BehavioralHookType::STRATEGY => [
|
||||||
\Psr\Log\LoggerInterface::class => [
|
\Psr\Log\LoggerInterface::class => [
|
||||||
\Psr\Log\NullLogger::class => [''],
|
\Psr\Log\NullLogger::class => [''],
|
||||||
],
|
],
|
||||||
|
@ -79,7 +79,7 @@ EOF;
|
||||||
'addon/testaddon1/static/hooks.config.php' => $this->content,
|
'addon/testaddon1/static/hooks.config.php' => $this->content,
|
||||||
],
|
],
|
||||||
'assertion' => [
|
'assertion' => [
|
||||||
\Friendica\Core\Hooks\Capabilities\HookType::STRATEGY => [
|
\Friendica\Core\Hooks\Capabilities\BehavioralHookType::STRATEGY => [
|
||||||
\Psr\Log\LoggerInterface::class => [
|
\Psr\Log\LoggerInterface::class => [
|
||||||
\Psr\Log\NullLogger::class => [''],
|
\Psr\Log\NullLogger::class => [''],
|
||||||
],
|
],
|
||||||
|
@ -94,7 +94,7 @@ EOF;
|
||||||
'addon/testaddon2/static/hooks.config.php' => $this->content,
|
'addon/testaddon2/static/hooks.config.php' => $this->content,
|
||||||
],
|
],
|
||||||
'assertion' => [
|
'assertion' => [
|
||||||
\Friendica\Core\Hooks\Capabilities\HookType::STRATEGY => [
|
\Friendica\Core\Hooks\Capabilities\BehavioralHookType::STRATEGY => [
|
||||||
\Psr\Log\LoggerInterface::class => [
|
\Psr\Log\LoggerInterface::class => [
|
||||||
\Psr\Log\NullLogger::class => ['', ''],
|
\Psr\Log\NullLogger::class => ['', ''],
|
||||||
],
|
],
|
||||||
|
@ -118,7 +118,7 @@ EOF;
|
||||||
'addon/testaddon2/static/hooks.config.php' => $this->content,
|
'addon/testaddon2/static/hooks.config.php' => $this->content,
|
||||||
],
|
],
|
||||||
'assertion' => [
|
'assertion' => [
|
||||||
\Friendica\Core\Hooks\Capabilities\HookType::STRATEGY => [
|
\Friendica\Core\Hooks\Capabilities\BehavioralHookType::STRATEGY => [
|
||||||
\Psr\Log\LoggerInterface::class => [
|
\Psr\Log\LoggerInterface::class => [
|
||||||
\Psr\Log\NullLogger::class => [''],
|
\Psr\Log\NullLogger::class => [''],
|
||||||
],
|
],
|
||||||
|
|
|
@ -22,25 +22,27 @@
|
||||||
namespace Friendica\Test\src\Core\Hooks\Model;
|
namespace Friendica\Test\src\Core\Hooks\Model;
|
||||||
|
|
||||||
use Dice\Dice;
|
use Dice\Dice;
|
||||||
|
use Friendica\Core\Hooks\Exceptions\HookInstanceException;
|
||||||
|
use Friendica\Core\Hooks\Exceptions\HookRegisterArgumentException;
|
||||||
use Friendica\Core\Hooks\Model\DiceInstanceManager;
|
use Friendica\Core\Hooks\Model\DiceInstanceManager;
|
||||||
|
use Friendica\Core\Hooks\Util\HookFileManager;
|
||||||
use Friendica\Test\MockedTest;
|
use Friendica\Test\MockedTest;
|
||||||
use Friendica\Test\Util\Hooks\InstanceMocks\FakeInstance;
|
use Friendica\Test\Util\Hooks\InstanceMocks\FakeInstance;
|
||||||
use Friendica\Test\Util\Hooks\InstanceMocks\FakeInstanceDecorator;
|
use Friendica\Test\Util\Hooks\InstanceMocks\FakeInstanceDecorator;
|
||||||
use Friendica\Test\Util\Hooks\InstanceMocks\IAmADecoratedInterface;
|
use Friendica\Test\Util\Hooks\InstanceMocks\IAmADecoratedInterface;
|
||||||
|
use Mockery\MockInterface;
|
||||||
|
|
||||||
class InstanceManagerTest extends MockedTest
|
class InstanceManagerTest extends MockedTest
|
||||||
{
|
{
|
||||||
public function testEqualButNotSameInstance()
|
/** @var HookFileManager|MockInterface */
|
||||||
|
protected $hookFileManager;
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
$instance = new DiceInstanceManager(new Dice());
|
parent::setUp();
|
||||||
|
|
||||||
$instance->registerStrategy(IAmADecoratedInterface::class, 'fake', FakeInstance::class);
|
$this->hookFileManager = \Mockery::mock(HookFileManager::class);
|
||||||
|
$this->hookFileManager->shouldReceive('setupHooks')->withAnyArgs();
|
||||||
$getInstanceA = $instance->createWithName(IAmADecoratedInterface::class, 'fake');
|
|
||||||
$getInstanceB = $instance->createWithName(IAmADecoratedInterface::class, 'fake');
|
|
||||||
|
|
||||||
self::assertEquals($getInstanceA, $getInstanceB);
|
|
||||||
self::assertNotSame($getInstanceA, $getInstanceB);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function tearDown(): void
|
protected function tearDown(): void
|
||||||
|
@ -50,6 +52,19 @@ class InstanceManagerTest extends MockedTest
|
||||||
parent::tearDown();
|
parent::tearDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testEqualButNotSameInstance()
|
||||||
|
{
|
||||||
|
$instance = new DiceInstanceManager(new Dice(), $this->hookFileManager);
|
||||||
|
|
||||||
|
$instance->registerStrategy(IAmADecoratedInterface::class, FakeInstance::class, 'fake');
|
||||||
|
|
||||||
|
$getInstanceA = $instance->create(IAmADecoratedInterface::class, 'fake');
|
||||||
|
$getInstanceB = $instance->create(IAmADecoratedInterface::class, 'fake');
|
||||||
|
|
||||||
|
self::assertEquals($getInstanceA, $getInstanceB);
|
||||||
|
self::assertNotSame($getInstanceA, $getInstanceB);
|
||||||
|
}
|
||||||
|
|
||||||
public function dataTests(): array
|
public function dataTests(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
@ -79,9 +94,9 @@ class InstanceManagerTest extends MockedTest
|
||||||
/**
|
/**
|
||||||
* @dataProvider dataTests
|
* @dataProvider dataTests
|
||||||
*/
|
*/
|
||||||
public function testInstanceWithConstructorAnonymArgs(string $aString = null, bool $cBool = null, string $bString = null)
|
public function testInstanceWithArgs(string $aString = null, bool $cBool = null, string $bString = null)
|
||||||
{
|
{
|
||||||
$instance = new DiceInstanceManager(new Dice());
|
$instance = new DiceInstanceManager(new Dice(), $this->hookFileManager);
|
||||||
|
|
||||||
$args = [];
|
$args = [];
|
||||||
|
|
||||||
|
@ -95,45 +110,12 @@ class InstanceManagerTest extends MockedTest
|
||||||
$args[] = $cBool;
|
$args[] = $cBool;
|
||||||
}
|
}
|
||||||
|
|
||||||
$instance->registerStrategy(IAmADecoratedInterface::class, 'fake', FakeInstance::class, $args);
|
$instance->registerStrategy(IAmADecoratedInterface::class, FakeInstance::class, 'fake');
|
||||||
|
|
||||||
/** @var IAmADecoratedInterface $getInstanceA */
|
/** @var IAmADecoratedInterface $getInstanceA */
|
||||||
$getInstanceA = $instance->createWithName(IAmADecoratedInterface::class, 'fake');
|
$getInstanceA = $instance->create(IAmADecoratedInterface::class, 'fake', $args);
|
||||||
/** @var IAmADecoratedInterface $getInstanceB */
|
/** @var IAmADecoratedInterface $getInstanceB */
|
||||||
$getInstanceB = $instance->createWithName(IAmADecoratedInterface::class, 'fake');
|
$getInstanceB = $instance->create(IAmADecoratedInterface::class, 'fake', $args);
|
||||||
|
|
||||||
self::assertEquals($getInstanceA, $getInstanceB);
|
|
||||||
self::assertNotSame($getInstanceA, $getInstanceB);
|
|
||||||
self::assertEquals($aString, $getInstanceA->getAText());
|
|
||||||
self::assertEquals($aString, $getInstanceB->getAText());
|
|
||||||
self::assertEquals($bString, $getInstanceA->getBText());
|
|
||||||
self::assertEquals($bString, $getInstanceB->getBText());
|
|
||||||
self::assertEquals($cBool, $getInstanceA->getCBool());
|
|
||||||
self::assertEquals($cBool, $getInstanceB->getCBool());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dataProvider dataTests
|
|
||||||
*/
|
|
||||||
public function testInstanceConstructorAndGetInstanceWithNamedArgs(string $aString = null, bool $cBool = null, string $bString = null)
|
|
||||||
{
|
|
||||||
$instance = new DiceInstanceManager(new Dice());
|
|
||||||
|
|
||||||
$args = [];
|
|
||||||
|
|
||||||
if (isset($aString)) {
|
|
||||||
$args[] = $aString;
|
|
||||||
}
|
|
||||||
if (isset($cBool)) {
|
|
||||||
$args[] = $cBool;
|
|
||||||
}
|
|
||||||
|
|
||||||
$instance->registerStrategy(IAmADecoratedInterface::class, 'fake', FakeInstance::class, $args);
|
|
||||||
|
|
||||||
/** @var IAmADecoratedInterface $getInstanceA */
|
|
||||||
$getInstanceA = $instance->createWithName(IAmADecoratedInterface::class, 'fake', [$bString]);
|
|
||||||
/** @var IAmADecoratedInterface $getInstanceB */
|
|
||||||
$getInstanceB = $instance->createWithName(IAmADecoratedInterface::class, 'fake', [$bString]);
|
|
||||||
|
|
||||||
self::assertEquals($getInstanceA, $getInstanceB);
|
self::assertEquals($getInstanceA, $getInstanceB);
|
||||||
self::assertNotSame($getInstanceA, $getInstanceB);
|
self::assertNotSame($getInstanceA, $getInstanceB);
|
||||||
|
@ -150,24 +132,27 @@ class InstanceManagerTest extends MockedTest
|
||||||
*/
|
*/
|
||||||
public function testInstanceWithTwoStrategies(string $aString = null, bool $cBool = null, string $bString = null)
|
public function testInstanceWithTwoStrategies(string $aString = null, bool $cBool = null, string $bString = null)
|
||||||
{
|
{
|
||||||
$instance = new DiceInstanceManager(new Dice());
|
$instance = new DiceInstanceManager(new Dice(), $this->hookFileManager);
|
||||||
|
|
||||||
$args = [];
|
$args = [];
|
||||||
|
|
||||||
if (isset($aString)) {
|
if (isset($aString)) {
|
||||||
$args[] = $aString;
|
$args[] = $aString;
|
||||||
}
|
}
|
||||||
|
if (isset($bString)) {
|
||||||
|
$args[] = $bString;
|
||||||
|
}
|
||||||
if (isset($cBool)) {
|
if (isset($cBool)) {
|
||||||
$args[] = $cBool;
|
$args[] = $cBool;
|
||||||
}
|
}
|
||||||
|
|
||||||
$instance->registerStrategy(IAmADecoratedInterface::class, 'fake', FakeInstance::class, $args);
|
$instance->registerStrategy(IAmADecoratedInterface::class, FakeInstance::class, 'fake');
|
||||||
$instance->registerStrategy(IAmADecoratedInterface::class, 'fake23', FakeInstance::class, $args);
|
$instance->registerStrategy(IAmADecoratedInterface::class, FakeInstance::class, 'fake23');
|
||||||
|
|
||||||
/** @var IAmADecoratedInterface $getInstanceA */
|
/** @var IAmADecoratedInterface $getInstanceA */
|
||||||
$getInstanceA = $instance->createWithName(IAmADecoratedInterface::class, 'fake', [$bString]);
|
$getInstanceA = $instance->create(IAmADecoratedInterface::class, 'fake', $args);
|
||||||
/** @var IAmADecoratedInterface $getInstanceB */
|
/** @var IAmADecoratedInterface $getInstanceB */
|
||||||
$getInstanceB = $instance->createWithName(IAmADecoratedInterface::class, 'fake23', [$bString]);
|
$getInstanceB = $instance->create(IAmADecoratedInterface::class, 'fake23', $args);
|
||||||
|
|
||||||
self::assertEquals($getInstanceA, $getInstanceB);
|
self::assertEquals($getInstanceA, $getInstanceB);
|
||||||
self::assertNotSame($getInstanceA, $getInstanceB);
|
self::assertNotSame($getInstanceA, $getInstanceB);
|
||||||
|
@ -180,79 +165,74 @@ class InstanceManagerTest extends MockedTest
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider dataTests
|
* Test the exception in case the interface was already registered
|
||||||
*/
|
*/
|
||||||
public function testDecorator(string $aString = null, bool $cBool = null, string $bString = null)
|
public function testDoubleRegister()
|
||||||
{
|
{
|
||||||
$instance = new DiceInstanceManager(new Dice());
|
self::expectException(HookRegisterArgumentException::class);
|
||||||
|
self::expectExceptionMessage(sprintf('A class with the name %s is already set for the interface %s', 'fake', IAmADecoratedInterface::class));
|
||||||
|
|
||||||
$args = [];
|
$instance = new DiceInstanceManager(new Dice(), $this->hookFileManager);
|
||||||
|
$instance->registerStrategy(IAmADecoratedInterface::class, FakeInstance::class, 'fake');
|
||||||
if (isset($aString)) {
|
$instance->registerStrategy(IAmADecoratedInterface::class, FakeInstance::class, 'fake');
|
||||||
$args[] = $aString;
|
|
||||||
}
|
|
||||||
if (isset($cBool)) {
|
|
||||||
$args[] = $cBool;
|
|
||||||
}
|
|
||||||
|
|
||||||
$prefix = 'prefix1';
|
|
||||||
|
|
||||||
$instance->registerStrategy(IAmADecoratedInterface::class, 'fake', FakeInstance::class, $args);
|
|
||||||
$instance->registerStrategy(IAmADecoratedInterface::class, 'fake23', FakeInstance::class, $args);
|
|
||||||
$instance->registerDecorator(IAmADecoratedInterface::class, FakeInstanceDecorator::class, [$prefix]);
|
|
||||||
|
|
||||||
/** @var IAmADecoratedInterface $getInstanceA */
|
|
||||||
$getInstanceA = $instance->createWithName(IAmADecoratedInterface::class, 'fake', [$bString]);
|
|
||||||
/** @var IAmADecoratedInterface $getInstanceB */
|
|
||||||
$getInstanceB = $instance->createWithName(IAmADecoratedInterface::class, 'fake23', [$bString]);
|
|
||||||
|
|
||||||
self::assertEquals(2, FakeInstanceDecorator::$countInstance);
|
|
||||||
self::assertEquals($getInstanceA, $getInstanceB);
|
|
||||||
self::assertNotSame($getInstanceA, $getInstanceB);
|
|
||||||
self::assertEquals($prefix . $aString, $getInstanceA->getAText());
|
|
||||||
self::assertEquals($prefix . $aString, $getInstanceB->getAText());
|
|
||||||
self::assertEquals($prefix . $bString, $getInstanceA->getBText());
|
|
||||||
self::assertEquals($prefix . $bString, $getInstanceB->getBText());
|
|
||||||
self::assertEquals($prefix . $cBool, $getInstanceA->getCBool());
|
|
||||||
self::assertEquals($prefix . $cBool, $getInstanceB->getCBool());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Test the exception in case the name of the instance isn't registered
|
||||||
|
*/
|
||||||
|
public function testWrongInstanceName()
|
||||||
|
{
|
||||||
|
self::expectException(HookInstanceException::class );
|
||||||
|
self::expectExceptionMessage(sprintf('The class with the name %s isn\'t registered for the class or interface %s', 'fake', IAmADecoratedInterface::class));
|
||||||
|
|
||||||
|
$instance = new DiceInstanceManager(new Dice(), $this->hookFileManager);
|
||||||
|
$instance->create(IAmADecoratedInterface::class, 'fake');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test in case there are already some rules
|
||||||
|
*
|
||||||
* @dataProvider dataTests
|
* @dataProvider dataTests
|
||||||
*/
|
*/
|
||||||
public function testTwoDecoratorWithPrefix(string $aString = null, bool $cBool = null, string $bString = null)
|
public function testWithGivenRules(string $aString = null, bool $cBool = null, string $bString = null)
|
||||||
{
|
{
|
||||||
$instance = new DiceInstanceManager(new Dice());
|
|
||||||
|
|
||||||
$args = [];
|
$args = [];
|
||||||
|
|
||||||
if (isset($aString)) {
|
if (isset($aString)) {
|
||||||
$args[] = $aString;
|
$args[] = $aString;
|
||||||
}
|
}
|
||||||
|
if (isset($bString)) {
|
||||||
|
$args[] = $bString;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dice = (new Dice())->addRules([
|
||||||
|
FakeInstance::class => [
|
||||||
|
'constructParams' => $args,
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$args = [];
|
||||||
|
|
||||||
if (isset($cBool)) {
|
if (isset($cBool)) {
|
||||||
$args[] = $cBool;
|
$args[] = $cBool;
|
||||||
}
|
}
|
||||||
|
|
||||||
$prefix = 'prefix1';
|
$instance = new DiceInstanceManager($dice, $this->hookFileManager);
|
||||||
|
|
||||||
$instance->registerStrategy(IAmADecoratedInterface::class, 'fake', FakeInstance::class, $args);
|
$instance->registerStrategy(IAmADecoratedInterface::class, FakeInstance::class, 'fake');
|
||||||
$instance->registerStrategy(IAmADecoratedInterface::class, 'fake23', FakeInstance::class, $args);
|
|
||||||
$instance->registerDecorator(IAmADecoratedInterface::class, FakeInstanceDecorator::class, [$prefix]);
|
|
||||||
$instance->registerDecorator(IAmADecoratedInterface::class, FakeInstanceDecorator::class);
|
|
||||||
|
|
||||||
/** @var IAmADecoratedInterface $getInstanceA */
|
/** @var IAmADecoratedInterface $getInstanceA */
|
||||||
$getInstanceA = $instance->createWithName(IAmADecoratedInterface::class, 'fake', [$bString]);
|
$getInstanceA = $instance->create(IAmADecoratedInterface::class, 'fake', $args);
|
||||||
/** @var IAmADecoratedInterface $getInstanceB */
|
/** @var IAmADecoratedInterface $getInstanceB */
|
||||||
$getInstanceB = $instance->createWithName(IAmADecoratedInterface::class, 'fake23', [$bString]);
|
$getInstanceB = $instance->create(IAmADecoratedInterface::class, 'fake', $args);
|
||||||
|
|
||||||
self::assertEquals(4, FakeInstanceDecorator::$countInstance);
|
|
||||||
self::assertEquals($getInstanceA, $getInstanceB);
|
self::assertEquals($getInstanceA, $getInstanceB);
|
||||||
self::assertNotSame($getInstanceA, $getInstanceB);
|
self::assertNotSame($getInstanceA, $getInstanceB);
|
||||||
self::assertEquals($prefix . $aString, $getInstanceA->getAText());
|
self::assertEquals($aString, $getInstanceA->getAText());
|
||||||
self::assertEquals($prefix . $aString, $getInstanceB->getAText());
|
self::assertEquals($aString, $getInstanceB->getAText());
|
||||||
self::assertEquals($prefix . $bString, $getInstanceA->getBText());
|
self::assertEquals($bString, $getInstanceA->getBText());
|
||||||
self::assertEquals($prefix . $bString, $getInstanceB->getBText());
|
self::assertEquals($bString, $getInstanceB->getBText());
|
||||||
self::assertEquals($prefix . $cBool, $getInstanceA->getCBool());
|
self::assertEquals($cBool, $getInstanceA->getCBool());
|
||||||
self::assertEquals($prefix . $cBool, $getInstanceB->getCBool());
|
self::assertEquals($cBool, $getInstanceB->getCBool());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,12 +31,12 @@ class HookFileManagerTest extends MockedTest
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
\Friendica\Core\Hooks\Capabilities\HookType::STRATEGY => [
|
\Friendica\Core\Hooks\Capabilities\BehavioralHookType::STRATEGY => [
|
||||||
\Psr\Log\LoggerInterface::class => [
|
\Psr\Log\LoggerInterface::class => [
|
||||||
\Psr\Log\NullLogger::class => [''],
|
\Psr\Log\NullLogger::class => [''],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
\Friendica\Core\Hooks\Capabilities\HookType::DECORATOR => [
|
\Friendica\Core\Hooks\Capabilities\BehavioralHookType::DECORATOR => [
|
||||||
\Psr\Log\LoggerInterface::class => [
|
\Psr\Log\LoggerInterface::class => [
|
||||||
\Psr\Log\NullLogger::class,
|
\Psr\Log\NullLogger::class,
|
||||||
],
|
],
|
||||||
|
@ -56,12 +56,12 @@ EOF,
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
\Friendica\Core\Hooks\Capabilities\HookType::STRATEGY => [
|
\Friendica\Core\Hooks\Capabilities\BehavioralHookType::STRATEGY => [
|
||||||
\Psr\Log\LoggerInterface::class => [
|
\Psr\Log\LoggerInterface::class => [
|
||||||
\Psr\Log\NullLogger::class => '',
|
\Psr\Log\NullLogger::class => '',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
\Friendica\Core\Hooks\Capabilities\HookType::DECORATOR => [
|
\Friendica\Core\Hooks\Capabilities\BehavioralHookType::DECORATOR => [
|
||||||
\Psr\Log\LoggerInterface::class => \Psr\Log\NullLogger::class,
|
\Psr\Log\LoggerInterface::class => \Psr\Log\NullLogger::class,
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
@ -79,7 +79,7 @@ EOF,
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
\Friendica\Core\Hooks\Capabilities\HookType::STRATEGY => [
|
\Friendica\Core\Hooks\Capabilities\BehavioralHookType::STRATEGY => [
|
||||||
\Psr\Log\LoggerInterface::class => [
|
\Psr\Log\LoggerInterface::class => [
|
||||||
\Psr\Log\NullLogger::class => [''],
|
\Psr\Log\NullLogger::class => [''],
|
||||||
],
|
],
|
||||||
|
@ -87,7 +87,7 @@ return [
|
||||||
];
|
];
|
||||||
EOF,
|
EOF,
|
||||||
'addonsArray' => [
|
'addonsArray' => [
|
||||||
\Friendica\Core\Hooks\Capabilities\HookType::STRATEGY => [
|
\Friendica\Core\Hooks\Capabilities\BehavioralHookType::STRATEGY => [
|
||||||
\Psr\Log\LoggerInterface::class => [
|
\Psr\Log\LoggerInterface::class => [
|
||||||
\Psr\Log\NullLogger::class => ['null'],
|
\Psr\Log\NullLogger::class => ['null'],
|
||||||
],
|
],
|
||||||
|
@ -104,7 +104,7 @@ EOF,
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
\Friendica\Core\Hooks\Capabilities\HookType::STRATEGY => [
|
\Friendica\Core\Hooks\Capabilities\BehavioralHookType::STRATEGY => [
|
||||||
\Psr\Log\LoggerInterface::class => [
|
\Psr\Log\LoggerInterface::class => [
|
||||||
\Psr\Log\NullLogger::class => [''],
|
\Psr\Log\NullLogger::class => [''],
|
||||||
],
|
],
|
||||||
|
@ -112,7 +112,7 @@ return [
|
||||||
];
|
];
|
||||||
EOF,
|
EOF,
|
||||||
'addonsArray' => [
|
'addonsArray' => [
|
||||||
\Friendica\Core\Hooks\Capabilities\HookType::STRATEGY => [
|
\Friendica\Core\Hooks\Capabilities\BehavioralHookType::STRATEGY => [
|
||||||
\Psr\Log\LoggerInterface::class => [
|
\Psr\Log\LoggerInterface::class => [
|
||||||
\Psr\Log\NullLogger::class => 'null',
|
\Psr\Log\NullLogger::class => 'null',
|
||||||
],
|
],
|
||||||
|
@ -130,7 +130,7 @@ EOF,
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
\Friendica\Core\Hooks\Capabilities\HookType::STRATEGY => [
|
\Friendica\Core\Hooks\Capabilities\BehavioralHookType::STRATEGY => [
|
||||||
\Psr\Log\LoggerInterface::class => [
|
\Psr\Log\LoggerInterface::class => [
|
||||||
\Psr\Log\NullLogger::class => [''],
|
\Psr\Log\NullLogger::class => [''],
|
||||||
],
|
],
|
||||||
|
@ -138,7 +138,7 @@ return [
|
||||||
];
|
];
|
||||||
EOF,
|
EOF,
|
||||||
'addonsArray' => [
|
'addonsArray' => [
|
||||||
\Friendica\Core\Hooks\Capabilities\HookType::STRATEGY => [
|
\Friendica\Core\Hooks\Capabilities\BehavioralHookType::STRATEGY => [
|
||||||
\Psr\Log\LoggerInterface::class => [
|
\Psr\Log\LoggerInterface::class => [
|
||||||
\Psr\Log\NullLogger::class => [''],
|
\Psr\Log\NullLogger::class => [''],
|
||||||
],
|
],
|
||||||
|
@ -163,7 +163,7 @@ return [
|
||||||
];
|
];
|
||||||
EOF,
|
EOF,
|
||||||
'addonsArray' => [
|
'addonsArray' => [
|
||||||
\Friendica\Core\Hooks\Capabilities\HookType::STRATEGY => [
|
\Friendica\Core\Hooks\Capabilities\BehavioralHookType::STRATEGY => [
|
||||||
\Psr\Log\LoggerInterface::class => [
|
\Psr\Log\LoggerInterface::class => [
|
||||||
\Psr\Log\NullLogger::class => [''],
|
\Psr\Log\NullLogger::class => [''],
|
||||||
],
|
],
|
||||||
|
|
Loading…
Reference in a new issue