mirror of
https://github.com/DesignPatternsPHP/DesignPatternsPHP.git
synced 2025-07-28 18:50:11 +02:00
add psalm and travis check
This commit is contained in:
@@ -24,3 +24,4 @@ install:
|
|||||||
script:
|
script:
|
||||||
- vendor/bin/phpunit
|
- vendor/bin/phpunit
|
||||||
- vendor/bin/phpcs .
|
- vendor/bin/phpcs .
|
||||||
|
- vendor/bin/psalm --show-info=false
|
||||||
|
@@ -5,7 +5,10 @@ namespace DesignPatterns\Behavioral\ChainOfResponsibilities\Tests;
|
|||||||
use DesignPatterns\Behavioral\ChainOfResponsibilities\Handler;
|
use DesignPatterns\Behavioral\ChainOfResponsibilities\Handler;
|
||||||
use DesignPatterns\Behavioral\ChainOfResponsibilities\Responsible\HttpInMemoryCacheHandler;
|
use DesignPatterns\Behavioral\ChainOfResponsibilities\Responsible\HttpInMemoryCacheHandler;
|
||||||
use DesignPatterns\Behavioral\ChainOfResponsibilities\Responsible\SlowDatabaseHandler;
|
use DesignPatterns\Behavioral\ChainOfResponsibilities\Responsible\SlowDatabaseHandler;
|
||||||
|
use PHPUnit\Framework\MockObject\MockObject;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Psr\Http\Message\RequestInterface;
|
||||||
|
use Psr\Http\Message\UriInterface;
|
||||||
|
|
||||||
class ChainTest extends TestCase
|
class ChainTest extends TestCase
|
||||||
{
|
{
|
||||||
@@ -24,11 +27,11 @@ class ChainTest extends TestCase
|
|||||||
|
|
||||||
public function testCanRequestKeyInFastStorage()
|
public function testCanRequestKeyInFastStorage()
|
||||||
{
|
{
|
||||||
$uri = $this->createMock('Psr\Http\Message\UriInterface');
|
$uri = $this->createMock(UriInterface::class);
|
||||||
$uri->method('getPath')->willReturn('/foo/bar');
|
$uri->method('getPath')->willReturn('/foo/bar');
|
||||||
$uri->method('getQuery')->willReturn('index=1');
|
$uri->method('getQuery')->willReturn('index=1');
|
||||||
|
|
||||||
$request = $this->createMock('Psr\Http\Message\RequestInterface');
|
$request = $this->createMock(RequestInterface::class);
|
||||||
$request->method('getMethod')
|
$request->method('getMethod')
|
||||||
->willReturn('GET');
|
->willReturn('GET');
|
||||||
$request->method('getUri')->willReturn($uri);
|
$request->method('getUri')->willReturn($uri);
|
||||||
@@ -38,11 +41,11 @@ class ChainTest extends TestCase
|
|||||||
|
|
||||||
public function testCanRequestKeyInSlowStorage()
|
public function testCanRequestKeyInSlowStorage()
|
||||||
{
|
{
|
||||||
$uri = $this->createMock('Psr\Http\Message\UriInterface');
|
$uri = $this->createMock(UriInterface::class);
|
||||||
$uri->method('getPath')->willReturn('/foo/baz');
|
$uri->method('getPath')->willReturn('/foo/baz');
|
||||||
$uri->method('getQuery')->willReturn('');
|
$uri->method('getQuery')->willReturn('');
|
||||||
|
|
||||||
$request = $this->createMock('Psr\Http\Message\RequestInterface');
|
$request = $this->createMock(RequestInterface::class);
|
||||||
$request->method('getMethod')
|
$request->method('getMethod')
|
||||||
->willReturn('GET');
|
->willReturn('GET');
|
||||||
$request->method('getUri')->willReturn($uri);
|
$request->method('getUri')->willReturn($uri);
|
||||||
|
@@ -2,25 +2,27 @@
|
|||||||
|
|
||||||
namespace DesignPatterns\Behavioral\Observer;
|
namespace DesignPatterns\Behavioral\Observer;
|
||||||
|
|
||||||
|
use SplSubject;
|
||||||
|
|
||||||
class UserObserver implements \SplObserver
|
class UserObserver implements \SplObserver
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var User[]
|
* @var SplSubject[]
|
||||||
*/
|
*/
|
||||||
private $changedUsers = [];
|
private $changedUsers = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* It is called by the Subject, usually by SplSubject::notify()
|
* It is called by the Subject, usually by SplSubject::notify()
|
||||||
*
|
*
|
||||||
* @param \SplSubject $subject
|
* @param SplSubject $subject
|
||||||
*/
|
*/
|
||||||
public function update(\SplSubject $subject)
|
public function update(SplSubject $subject)
|
||||||
{
|
{
|
||||||
$this->changedUsers[] = clone $subject;
|
$this->changedUsers[] = clone $subject;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return User[]
|
* @return SplSubject[]
|
||||||
*/
|
*/
|
||||||
public function getChangedUsers(): array
|
public function getChangedUsers(): array
|
||||||
{
|
{
|
||||||
|
@@ -10,7 +10,7 @@ class AndSpecification implements Specification
|
|||||||
private $specifications;
|
private $specifications;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Specification[] ...$specifications
|
* @param Specification[] $specifications
|
||||||
*/
|
*/
|
||||||
public function __construct(Specification ...$specifications)
|
public function __construct(Specification ...$specifications)
|
||||||
{
|
{
|
||||||
|
@@ -10,14 +10,14 @@ class OrSpecification implements Specification
|
|||||||
private $specifications;
|
private $specifications;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Specification[] ...$specifications
|
* @param Specification[] $specifications
|
||||||
*/
|
*/
|
||||||
public function __construct(Specification ...$specifications)
|
public function __construct(Specification ...$specifications)
|
||||||
{
|
{
|
||||||
$this->specifications = $specifications;
|
$this->specifications = $specifications;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* if at least one specification is true, return true, else return false
|
* if at least one specification is true, return true, else return false
|
||||||
*/
|
*/
|
||||||
public function isSatisfiedBy(Item $item): bool
|
public function isSatisfiedBy(Item $item): bool
|
||||||
|
@@ -5,12 +5,12 @@ namespace DesignPatterns\Creational\AbstractFactory;
|
|||||||
class ShippableProduct implements Product
|
class ShippableProduct implements Product
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var float
|
* @var int
|
||||||
*/
|
*/
|
||||||
private $productPrice;
|
private $productPrice;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var float
|
* @var int
|
||||||
*/
|
*/
|
||||||
private $shippingCosts;
|
private $shippingCosts;
|
||||||
|
|
||||||
|
@@ -6,6 +6,6 @@ class FormatNumber implements Formatter
|
|||||||
{
|
{
|
||||||
public function format(string $input): string
|
public function format(string $input): string
|
||||||
{
|
{
|
||||||
return number_format($input);
|
return number_format((int) $input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
namespace DesignPatterns\Creational\StaticFactory\Tests;
|
namespace DesignPatterns\Creational\StaticFactory\Tests;
|
||||||
|
|
||||||
|
use DesignPatterns\Creational\StaticFactory\FormatNumber;
|
||||||
|
use DesignPatterns\Creational\StaticFactory\FormatString;
|
||||||
use DesignPatterns\Creational\StaticFactory\StaticFactory;
|
use DesignPatterns\Creational\StaticFactory\StaticFactory;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
@@ -9,18 +11,12 @@ class StaticFactoryTest extends TestCase
|
|||||||
{
|
{
|
||||||
public function testCanCreateNumberFormatter()
|
public function testCanCreateNumberFormatter()
|
||||||
{
|
{
|
||||||
$this->assertInstanceOf(
|
$this->assertInstanceOf(FormatNumber::class, StaticFactory::factory('number'));
|
||||||
'DesignPatterns\Creational\StaticFactory\FormatNumber',
|
|
||||||
StaticFactory::factory('number')
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCanCreateStringFormatter()
|
public function testCanCreateStringFormatter()
|
||||||
{
|
{
|
||||||
$this->assertInstanceOf(
|
$this->assertInstanceOf(FormatString::class, StaticFactory::factory('string'));
|
||||||
'DesignPatterns\Creational\StaticFactory\FormatString',
|
|
||||||
StaticFactory::factory('string')
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testException()
|
public function testException()
|
||||||
|
@@ -2,10 +2,12 @@
|
|||||||
|
|
||||||
namespace DesignPatterns\More\EAV;
|
namespace DesignPatterns\More\EAV;
|
||||||
|
|
||||||
|
use SplObjectStorage;
|
||||||
|
|
||||||
class Entity
|
class Entity
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var \SplObjectStorage
|
* @var SplObjectStorage<Value,Value>
|
||||||
*/
|
*/
|
||||||
private $values;
|
private $values;
|
||||||
|
|
||||||
@@ -20,7 +22,7 @@ class Entity
|
|||||||
*/
|
*/
|
||||||
public function __construct(string $name, $values)
|
public function __construct(string $name, $values)
|
||||||
{
|
{
|
||||||
$this->values = new \SplObjectStorage();
|
$this->values = new SplObjectStorage();
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
|
|
||||||
foreach ($values as $value) {
|
foreach ($values as $value) {
|
||||||
|
@@ -24,6 +24,6 @@ class Value
|
|||||||
|
|
||||||
public function __toString(): string
|
public function __toString(): string
|
||||||
{
|
{
|
||||||
return sprintf('%s: %s', $this->attribute, $this->name);
|
return sprintf('%s: %s', (string) $this->attribute, $this->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,18 +5,17 @@ namespace DesignPatterns\More\ServiceLocator;
|
|||||||
class ServiceLocator
|
class ServiceLocator
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var array|Service[]
|
* @var string[][]
|
||||||
*/
|
*/
|
||||||
private $services = [];
|
private $services = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array|Service[]
|
* @var Service[]
|
||||||
*/
|
*/
|
||||||
private $instantiated = [];
|
private $instantiated = [];
|
||||||
|
|
||||||
public function addInstance(string $class, Service $service)
|
public function addInstance(string $class, Service $service)
|
||||||
{
|
{
|
||||||
$this->services[$class] = $service;
|
|
||||||
$this->instantiated[$class] = $service;
|
$this->instantiated[$class] = $service;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,6 +54,10 @@ class ServiceLocator
|
|||||||
throw new \OutOfRangeException('Too many arguments given');
|
throw new \OutOfRangeException('Too many arguments given');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!$object instanceof Service) {
|
||||||
|
throw new \InvalidArgumentException('Could not register service: is no instance of Service');
|
||||||
|
}
|
||||||
|
|
||||||
$this->instantiated[$class] = $object;
|
$this->instantiated[$class] = $object;
|
||||||
|
|
||||||
return $object;
|
return $object;
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace DesignPatterns\Structural\Facade\Tests;
|
namespace DesignPatterns\Structural\Facade\Tests;
|
||||||
|
|
||||||
|
use DesignPatterns\Structural\Facade\Bios;
|
||||||
use DesignPatterns\Structural\Facade\Facade;
|
use DesignPatterns\Structural\Facade\Facade;
|
||||||
use DesignPatterns\Structural\Facade\OperatingSystem;
|
use DesignPatterns\Structural\Facade\OperatingSystem;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
@@ -10,27 +11,20 @@ class FacadeTest extends TestCase
|
|||||||
{
|
{
|
||||||
public function testComputerOn()
|
public function testComputerOn()
|
||||||
{
|
{
|
||||||
/** @var OperatingSystem|\PHPUnit_Framework_MockObject_MockObject $os */
|
$os = $this->createMock(OperatingSystem::class);
|
||||||
$os = $this->createMock('DesignPatterns\Structural\Facade\OperatingSystem');
|
|
||||||
|
|
||||||
$os->method('getName')
|
$os->method('getName')
|
||||||
->will($this->returnValue('Linux'));
|
->will($this->returnValue('Linux'));
|
||||||
|
|
||||||
$bios = $this->getMockBuilder('DesignPatterns\Structural\Facade\Bios')
|
$bios = $this->createMock(Bios::class);
|
||||||
->setMethods(['launch', 'execute', 'waitForKeyPress'])
|
|
||||||
->disableAutoload()
|
|
||||||
->getMock();
|
|
||||||
|
|
||||||
$bios->expects($this->once())
|
$bios->method('launch')
|
||||||
->method('launch')
|
|
||||||
->with($os);
|
->with($os);
|
||||||
|
|
||||||
|
/** @noinspection PhpParamsInspection */
|
||||||
$facade = new Facade($bios, $os);
|
$facade = new Facade($bios, $os);
|
||||||
|
|
||||||
// the facade interface is simple
|
|
||||||
$facade->turnOn();
|
$facade->turnOn();
|
||||||
|
|
||||||
// but you can also access the underlying components
|
|
||||||
$this->assertSame('Linux', $os->getName());
|
$this->assertSame('Linux', $os->getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -20,6 +20,6 @@ class HeavyBankAccount implements BankAccount
|
|||||||
// years and decades ago must be fetched from a database or web service
|
// years and decades ago must be fetched from a database or web service
|
||||||
// and the balance must be calculated from it
|
// and the balance must be calculated from it
|
||||||
|
|
||||||
return array_sum($this->transactions);
|
return (int) array_sum($this->transactions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -9,9 +9,6 @@ use PHPUnit\Framework\TestCase;
|
|||||||
|
|
||||||
class RegistryTest extends TestCase
|
class RegistryTest extends TestCase
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @var Service|MockObject
|
|
||||||
*/
|
|
||||||
private $service;
|
private $service;
|
||||||
|
|
||||||
protected function setUp(): void
|
protected function setUp(): void
|
||||||
@@ -21,6 +18,7 @@ class RegistryTest extends TestCase
|
|||||||
|
|
||||||
public function testSetAndGetLogger()
|
public function testSetAndGetLogger()
|
||||||
{
|
{
|
||||||
|
/** @noinspection PhpParamsInspection */
|
||||||
Registry::set(Registry::LOGGER, $this->service);
|
Registry::set(Registry::LOGGER, $this->service);
|
||||||
|
|
||||||
$this->assertSame($this->service, Registry::get(Registry::LOGGER));
|
$this->assertSame($this->service, Registry::get(Registry::LOGGER));
|
||||||
|
@@ -16,7 +16,9 @@
|
|||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^8",
|
"phpunit/phpunit": "^8",
|
||||||
"squizlabs/php_codesniffer": "^3",
|
"squizlabs/php_codesniffer": "^3",
|
||||||
"flyeralarm/php-code-validator": "^2.2"
|
"flyeralarm/php-code-validator": "^2.2",
|
||||||
|
"vimeo/psalm": "^3.4",
|
||||||
|
"psalm/plugin-phpunit": "^0.7.0"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
|
1111
composer.lock
generated
1111
composer.lock
generated
File diff suppressed because it is too large
Load Diff
60
psalm.xml
Normal file
60
psalm.xml
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<psalm
|
||||||
|
totallyTyped="false"
|
||||||
|
resolveFromConfigFile="true"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="https://getpsalm.org/schema/config"
|
||||||
|
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
|
||||||
|
>
|
||||||
|
<projectFiles>
|
||||||
|
<directory name="Behavioral"/>
|
||||||
|
<directory name="Creational"/>
|
||||||
|
<directory name="More"/>
|
||||||
|
<directory name="Structural"/>
|
||||||
|
<ignoreFiles>
|
||||||
|
<directory name="vendor"/>
|
||||||
|
</ignoreFiles>
|
||||||
|
</projectFiles>
|
||||||
|
|
||||||
|
<issueHandlers>
|
||||||
|
<LessSpecificReturnType errorLevel="info"/>
|
||||||
|
|
||||||
|
<!-- level 3 issues - slightly lazy code writing, but provably low false-negatives -->
|
||||||
|
|
||||||
|
<DeprecatedMethod errorLevel="info"/>
|
||||||
|
<DeprecatedProperty errorLevel="info"/>
|
||||||
|
<DeprecatedClass errorLevel="info"/>
|
||||||
|
<DeprecatedConstant errorLevel="info"/>
|
||||||
|
<DeprecatedFunction errorLevel="info"/>
|
||||||
|
<DeprecatedInterface errorLevel="info"/>
|
||||||
|
<DeprecatedTrait errorLevel="info"/>
|
||||||
|
|
||||||
|
<InternalMethod errorLevel="info"/>
|
||||||
|
<InternalProperty errorLevel="info"/>
|
||||||
|
<InternalClass errorLevel="info"/>
|
||||||
|
|
||||||
|
<MissingClosureReturnType errorLevel="info"/>
|
||||||
|
<MissingReturnType errorLevel="info"/>
|
||||||
|
<MissingPropertyType errorLevel="info"/>
|
||||||
|
<InvalidDocblock errorLevel="info"/>
|
||||||
|
<MisplacedRequiredParam errorLevel="info"/>
|
||||||
|
|
||||||
|
<PropertyNotSetInConstructor errorLevel="info"/>
|
||||||
|
<MissingConstructor errorLevel="info"/>
|
||||||
|
<MissingClosureParamType errorLevel="info"/>
|
||||||
|
<MissingParamType errorLevel="info"/>
|
||||||
|
|
||||||
|
<RedundantCondition errorLevel="info"/>
|
||||||
|
|
||||||
|
<DocblockTypeContradiction errorLevel="info"/>
|
||||||
|
<RedundantConditionGivenDocblockType errorLevel="info"/>
|
||||||
|
|
||||||
|
<UnresolvableInclude errorLevel="info"/>
|
||||||
|
|
||||||
|
<RawObjectIteration errorLevel="info"/>
|
||||||
|
|
||||||
|
<InvalidStringClass errorLevel="info"/>
|
||||||
|
</issueHandlers>
|
||||||
|
<plugins>
|
||||||
|
<pluginClass class="Psalm\PhpUnitPlugin\Plugin"/></plugins>
|
||||||
|
</psalm>
|
Reference in New Issue
Block a user