Added Decorator and observer Patterns along with UnitTest for Observer
This commit is contained in:
parent
dabbf541dc
commit
f76eb08fe0
8
.idea/laravel-idea.xml
Normal file
8
.idea/laravel-idea.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="InertiaPackage">
|
||||||
|
<option name="directoryPaths">
|
||||||
|
<list />
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -3,6 +3,7 @@
|
|||||||
<component name="NewModuleRootManager">
|
<component name="NewModuleRootManager">
|
||||||
<content url="file://$MODULE_DIR$">
|
<content url="file://$MODULE_DIR$">
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" packagePrefix="App\Tests\" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/clue/ndjson-react" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/clue/ndjson-react" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/composer" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/composer" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/evenement/evenement" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/evenement/evenement" />
|
||||||
@ -36,6 +37,30 @@
|
|||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/service-contracts" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/service-contracts" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/stopwatch" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/stopwatch" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/string" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/string" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/myclabs/deep-copy" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/nikic/php-parser" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phar-io/manifest" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phar-io/version" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-code-coverage" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-file-iterator" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-invoker" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-text-template" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-timer" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/phpunit" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/cli-parser" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/comparator" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/complexity" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/environment" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/exporter" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/global-state" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/lines-of-code" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/object-enumerator" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/object-reflector" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/recursion-context" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/type" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/version" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/staabm/side-effects-detector" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/theseer/tokenizer" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
@ -71,6 +71,30 @@
|
|||||||
<path value="$PROJECT_DIR$/vendor/friendsofphp/php-cs-fixer" />
|
<path value="$PROJECT_DIR$/vendor/friendsofphp/php-cs-fixer" />
|
||||||
<path value="$PROJECT_DIR$/vendor/react/stream" />
|
<path value="$PROJECT_DIR$/vendor/react/stream" />
|
||||||
<path value="$PROJECT_DIR$/vendor/fidry/cpu-core-counter" />
|
<path value="$PROJECT_DIR$/vendor/fidry/cpu-core-counter" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/nikic/php-parser" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/myclabs/deep-copy" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/phar-io/manifest" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/phar-io/version" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/staabm/side-effects-detector" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/theseer/tokenizer" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/phpunit/php-code-coverage" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/phpunit/php-file-iterator" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/phpunit/php-invoker" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/phpunit/php-text-template" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/phpunit/php-timer" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/phpunit/phpunit" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/sebastian/global-state" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/sebastian/complexity" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/sebastian/recursion-context" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/sebastian/object-enumerator" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/sebastian/object-reflector" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/sebastian/cli-parser" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/sebastian/lines-of-code" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/sebastian/type" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/sebastian/version" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/sebastian/comparator" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/sebastian/exporter" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/sebastian/environment" />
|
||||||
</include_path>
|
</include_path>
|
||||||
</component>
|
</component>
|
||||||
<component name="PhpProjectSharedConfiguration" php_language_level="8.3" />
|
<component name="PhpProjectSharedConfiguration" php_language_level="8.3" />
|
||||||
@ -82,6 +106,11 @@
|
|||||||
<component name="PhpStanOptionsConfiguration">
|
<component name="PhpStanOptionsConfiguration">
|
||||||
<option name="transferred" value="true" />
|
<option name="transferred" value="true" />
|
||||||
</component>
|
</component>
|
||||||
|
<component name="PhpUnit">
|
||||||
|
<phpunit_settings>
|
||||||
|
<PhpUnitSettings custom_loader_path="$PROJECT_DIR$/vendor/autoload.php" />
|
||||||
|
</phpunit_settings>
|
||||||
|
</component>
|
||||||
<component name="Psalm">
|
<component name="Psalm">
|
||||||
<Psalm_settings>
|
<Psalm_settings>
|
||||||
<psalm_fixer_by_interpreter asDefaultInterpreter="true" interpreter_id="6adcaaf8-6d8b-41cc-8523-d95f7e166ea1" timeout="60000" />
|
<psalm_fixer_by_interpreter asDefaultInterpreter="true" interpreter_id="6adcaaf8-6d8b-41cc-8523-d95f7e166ea1" timeout="60000" />
|
||||||
|
10
.idea/phpspec.xml
Normal file
10
.idea/phpspec.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="PHPSpec">
|
||||||
|
<suites>
|
||||||
|
<PhpSpecSuiteConfiguration>
|
||||||
|
<option name="myPath" value="$PROJECT_DIR$" />
|
||||||
|
</PhpSpecSuiteConfiguration>
|
||||||
|
</suites>
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -9,4 +9,9 @@
|
|||||||
|
|
||||||
declare(strict_types = 1);
|
declare(strict_types = 1);
|
||||||
|
|
||||||
dump('Decorator');
|
use Pattern\Structural\Decorator\{BasicInspection, OilChange, TireRotation};
|
||||||
|
|
||||||
|
$service = new TireRotation(new OilChange(new BasicInspection()));
|
||||||
|
|
||||||
|
echo $service->getDescription() . ': $';
|
||||||
|
echo $service->getCost();
|
||||||
|
@ -5,6 +5,11 @@
|
|||||||
"": "src/"
|
"": "src/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"autoload-dev": {
|
||||||
|
"psr-4": {
|
||||||
|
"App\\Tests\\": "tests/"
|
||||||
|
}
|
||||||
|
},
|
||||||
"authors": [
|
"authors": [
|
||||||
{
|
{
|
||||||
"name": "Yevhen Odynets",
|
"name": "Yevhen Odynets",
|
||||||
@ -16,7 +21,8 @@
|
|||||||
"ext-simplexml": "*"
|
"ext-simplexml": "*"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"friendsofphp/php-cs-fixer": "^3.76"
|
"friendsofphp/php-cs-fixer": "^3.76",
|
||||||
|
"phpunit/phpunit": "^12.2"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"cs": "php-cs-fixer --config=./.php-cs-fixer.php check -v",
|
"cs": "php-cs-fixer --config=./.php-cs-fixer.php check -v",
|
||||||
|
1549
composer.lock
generated
1549
composer.lock
generated
File diff suppressed because it is too large
Load Diff
83
src/Pattern/Behavioral/Observer/User.php
Normal file
83
src/Pattern/Behavioral/Observer/User.php
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-06
|
||||||
|
* @time: 13:55
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace Pattern\Behavioral\Observer;
|
||||||
|
|
||||||
|
use SplObjectStorage;
|
||||||
|
use SplObserver;
|
||||||
|
use SplSubject;
|
||||||
|
|
||||||
|
class User implements SplSubject
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private string $name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var SplObjectStorage
|
||||||
|
*/
|
||||||
|
private SplObjectStorage $observers;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->observers = new SplObjectStorage();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attach an observer
|
||||||
|
*/
|
||||||
|
public function attach(SplObserver $observer): void
|
||||||
|
{
|
||||||
|
$this->observers->attach($observer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detach an observer
|
||||||
|
*/
|
||||||
|
public function detach(SplObserver $observer): void
|
||||||
|
{
|
||||||
|
$this->observers->detach($observer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getName(): string
|
||||||
|
{
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $name
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setName(string $name): void
|
||||||
|
{
|
||||||
|
$this->name = $name;
|
||||||
|
|
||||||
|
$this->notify();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify an observer
|
||||||
|
*/
|
||||||
|
public function notify(): void
|
||||||
|
{
|
||||||
|
/** @var SplObserver $observer */
|
||||||
|
foreach ($this->observers as $observer) {
|
||||||
|
var_dump($observer);
|
||||||
|
$observer->update($this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
31
src/Pattern/Behavioral/Observer/UserObserver.php
Normal file
31
src/Pattern/Behavioral/Observer/UserObserver.php
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-06
|
||||||
|
* @time: 14:06
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace Pattern\Behavioral\Observer;
|
||||||
|
|
||||||
|
use SplObserver;
|
||||||
|
use SplSubject;
|
||||||
|
|
||||||
|
class UserObserver implements SplObserver
|
||||||
|
{
|
||||||
|
private array $namesLog = [];
|
||||||
|
|
||||||
|
public function update(SplSubject $subject): void
|
||||||
|
{
|
||||||
|
/** @var User $subject */
|
||||||
|
$this->namesLog[] = $subject->getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getNamesLog(): array
|
||||||
|
{
|
||||||
|
return $this->namesLog;
|
||||||
|
}
|
||||||
|
}
|
25
src/Pattern/Structural/Decorator/BasicInspection.php
Normal file
25
src/Pattern/Structural/Decorator/BasicInspection.php
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-06
|
||||||
|
* @time: 11:38
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace Pattern\Structural\Decorator;
|
||||||
|
|
||||||
|
class BasicInspection implements CarServiceInterface
|
||||||
|
{
|
||||||
|
public function getCost(): float
|
||||||
|
{
|
||||||
|
return 25.14;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return 'Basic inspection';
|
||||||
|
}
|
||||||
|
}
|
@ -1,22 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @package: patterns
|
|
||||||
* @author: Yevhen Odynets
|
|
||||||
* @date: 2025-07-04
|
|
||||||
* @time: 10:42
|
|
||||||
*/
|
|
||||||
|
|
||||||
declare(strict_types = 1);
|
|
||||||
|
|
||||||
namespace Pattern\Structural\Decorator;
|
|
||||||
|
|
||||||
class BorderDecorator implements ShapeInterface
|
|
||||||
{
|
|
||||||
public function __construct(private ShapeInterface $shape) {}
|
|
||||||
|
|
||||||
public function draw(): void
|
|
||||||
{
|
|
||||||
echo '<div style="width: 8rem; height: 8rem; border: .5rem solid orange"></div>';
|
|
||||||
}
|
|
||||||
}
|
|
19
src/Pattern/Structural/Decorator/CarServiceInterface.php
Normal file
19
src/Pattern/Structural/Decorator/CarServiceInterface.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-06
|
||||||
|
* @time: 11:53
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace Pattern\Structural\Decorator;
|
||||||
|
|
||||||
|
interface CarServiceInterface
|
||||||
|
{
|
||||||
|
public function getCost(): float;
|
||||||
|
|
||||||
|
public function getDescription(): string;
|
||||||
|
}
|
@ -1,20 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @package: patterns
|
|
||||||
* @author: Yevhen Odynets
|
|
||||||
* @date: 2025-07-04
|
|
||||||
* @time: 10:41
|
|
||||||
*/
|
|
||||||
|
|
||||||
declare(strict_types = 1);
|
|
||||||
|
|
||||||
namespace Pattern\Structural\Decorator;
|
|
||||||
|
|
||||||
class Circle implements ShapeInterface
|
|
||||||
{
|
|
||||||
public function draw(): void
|
|
||||||
{
|
|
||||||
// TODO: Implement draw() method.
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @package: patterns
|
|
||||||
* @author: Yevhen Odynets
|
|
||||||
* @date: 2025-07-04
|
|
||||||
* @time: 10:43
|
|
||||||
*/
|
|
||||||
|
|
||||||
declare(strict_types = 1);
|
|
||||||
|
|
||||||
namespace Pattern\Structural\Decorator;
|
|
||||||
|
|
||||||
class EmailDecorator implements ShapeInterface
|
|
||||||
{
|
|
||||||
public function __construct(private ShapeInterface $shape) {}
|
|
||||||
|
|
||||||
public function draw(): void
|
|
||||||
{
|
|
||||||
// TODO: Implement draw() method.
|
|
||||||
}
|
|
||||||
}
|
|
27
src/Pattern/Structural/Decorator/OilChange.php
Normal file
27
src/Pattern/Structural/Decorator/OilChange.php
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-06
|
||||||
|
* @time: 12:08
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace Pattern\Structural\Decorator;
|
||||||
|
|
||||||
|
class OilChange implements CarServiceInterface
|
||||||
|
{
|
||||||
|
public function __construct(protected CarServiceInterface $carService) {}
|
||||||
|
|
||||||
|
public function getCost(): float
|
||||||
|
{
|
||||||
|
return 29.89 + $this->carService->getCost();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return $this->carService->getDescription() . ', and oil change';
|
||||||
|
}
|
||||||
|
}
|
@ -1,17 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @package: patterns
|
|
||||||
* @author: Yevhen Odynets
|
|
||||||
* @date: 2025-07-04
|
|
||||||
* @time: 10:38
|
|
||||||
*/
|
|
||||||
|
|
||||||
declare(strict_types = 1);
|
|
||||||
|
|
||||||
namespace Pattern\Structural\Decorator;
|
|
||||||
|
|
||||||
interface ShapeInterface
|
|
||||||
{
|
|
||||||
public function draw(): void;
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @package: patterns
|
|
||||||
* @author: Yevhen Odynets
|
|
||||||
* @date: 2025-07-04
|
|
||||||
* @time: 10:47
|
|
||||||
*/
|
|
||||||
|
|
||||||
declare(strict_types = 1);
|
|
||||||
|
|
||||||
namespace Pattern\Structural\Decorator;
|
|
||||||
|
|
||||||
class SmileDecorator implements ShapeInterface
|
|
||||||
{
|
|
||||||
public function __construct(private ShapeInterface $shape) {}
|
|
||||||
|
|
||||||
public function draw(): void
|
|
||||||
{
|
|
||||||
// TODO: Implement draw() method.
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @package: patterns
|
|
||||||
* @author: Yevhen Odynets
|
|
||||||
* @date: 2025-07-04
|
|
||||||
* @time: 10:41
|
|
||||||
*/
|
|
||||||
|
|
||||||
declare(strict_types = 1);
|
|
||||||
|
|
||||||
namespace Pattern\Structural\Decorator;
|
|
||||||
|
|
||||||
class Square implements ShapeInterface
|
|
||||||
{
|
|
||||||
public function draw(): void
|
|
||||||
{
|
|
||||||
// TODO: Implement draw() method.
|
|
||||||
}
|
|
||||||
}
|
|
26
src/Pattern/Structural/Decorator/TireRotation.php
Normal file
26
src/Pattern/Structural/Decorator/TireRotation.php
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-06
|
||||||
|
* @time: 12:41
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
namespace Pattern\Structural\Decorator;
|
||||||
|
|
||||||
|
class TireRotation implements CarServiceInterface
|
||||||
|
{
|
||||||
|
public function __construct(protected CarServiceInterface $carService) {}
|
||||||
|
|
||||||
|
public function getCost(): float
|
||||||
|
{
|
||||||
|
return 25.14 + $this->carService->getCost();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return $this->carService->getDescription() . ', and tire rotation';
|
||||||
|
}
|
||||||
|
}
|
43
tests/ObserverTest.php
Normal file
43
tests/ObserverTest.php
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-06
|
||||||
|
* @time: 13:31
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace App\Tests;
|
||||||
|
|
||||||
|
use Pattern\Behavioral\Observer\User;
|
||||||
|
use Pattern\Behavioral\Observer\UserObserver;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class ObserverTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testObserver(): void
|
||||||
|
{
|
||||||
|
$user = new User();
|
||||||
|
|
||||||
|
/** These names will be skipped and not be added to the log of names */
|
||||||
|
$user->setName("Just a name");
|
||||||
|
$user->setName("Some new name");
|
||||||
|
|
||||||
|
$userObserver = new UserObserver();
|
||||||
|
$user->attach($userObserver);
|
||||||
|
|
||||||
|
/** After creating a new instance of UserObserver::class
|
||||||
|
* and attached it to User::class instance,
|
||||||
|
* these names will be added to the log of names */
|
||||||
|
$user->setName("Another new name");
|
||||||
|
$user->setName("Once again new name");
|
||||||
|
$user->setName("Possibly other new name");
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
["Another new name", "Once again new name", "Possibly other new name"],
|
||||||
|
$userObserver->getNamesLog()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user