diff --git a/.laminas-ci.json b/.laminas-ci.json
index bce3fa21..b76cebb6 100644
--- a/.laminas-ci.json
+++ b/.laminas-ci.json
@@ -1,5 +1,15 @@
{
"ignore_php_platform_requirements": {
"8.1": true
- }
+ },
+ "additional_checks": [
+ {
+ "name": "Psalm for psr/container v1",
+ "job": {
+ "php": "@lowest",
+ "dependencies": "locked",
+ "command": "composer require -W psr/container:^1 && vendor/bin/psalm --stats --output-format=github --no-cache"
+ }
+ }
+ ]
}
diff --git a/composer.json b/composer.json
index 0582510b..289670db 100644
--- a/composer.json
+++ b/composer.json
@@ -26,21 +26,18 @@
},
"sort-packages": true,
"allow-plugins": {
- "dealerdirect/phpcodesniffer-composer-installer": true,
- "composer/package-versions-deprecated": true,
- "laminas/laminas-dependency-plugin": true
+ "dealerdirect/phpcodesniffer-composer-installer": true
}
},
"require": {
"php": "~7.4.0 || ~8.0.0 || ~8.1.0",
+ "composer-plugin-api": "^2.0",
"laminas/laminas-stdlib": "^3.2.1",
- "psr/container": "^1.0"
+ "psr/container": "^1.1 || ^2.0.2"
},
"require-dev": {
- "composer/package-versions-deprecated": "^1.0",
"laminas/laminas-coding-standard": "~2.3.0",
"laminas/laminas-container-config-test": "^0.6",
- "laminas/laminas-dependency-plugin": "^2.1.2",
"mikey179/vfsstream": "^1.6.10@alpha",
"ocramius/proxy-manager": "^2.11",
"phpbench/phpbench": "^1.1",
@@ -50,7 +47,7 @@
"vimeo/psalm": "^4.8"
},
"provide": {
- "psr/container-implementation": "^1.0"
+ "psr/container-implementation": "^1.1 || ^2.0"
},
"conflict": {
"ext-psr": "*",
diff --git a/composer.lock b/composer.lock
index 4b13efd2..f2d02622 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "3c3716ae3129e05fa4378e1889b98dbe",
+ "content-hash": "95886a4e7c8b9e7fbe376b2094639f27",
"packages": [
{
"name": "laminas/laminas-stdlib",
@@ -67,22 +67,27 @@
},
{
"name": "psr/container",
- "version": "1.1.2",
+ "version": "2.0.2",
"source": {
"type": "git",
"url": "https://github.com/php-fig/container.git",
- "reference": "513e0666f7216c7459170d56df27dfcefe1689ea"
+ "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea",
- "reference": "513e0666f7216c7459170d56df27dfcefe1689ea",
+ "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963",
+ "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963",
"shasum": ""
},
"require": {
"php": ">=7.4.0"
},
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
"autoload": {
"psr-4": {
"Psr\\Container\\": "src/"
@@ -109,9 +114,9 @@
],
"support": {
"issues": "https://github.com/php-fig/container/issues",
- "source": "https://github.com/php-fig/container/tree/1.1.2"
+ "source": "https://github.com/php-fig/container/tree/2.0.2"
},
- "time": "2021-11-05T16:50:12+00:00"
+ "time": "2021-11-05T16:47:00+00:00"
}
],
"packages-dev": [
@@ -1190,59 +1195,6 @@
],
"time": "2022-03-21T11:08:05+00:00"
},
- {
- "name": "laminas/laminas-dependency-plugin",
- "version": "2.2.0",
- "source": {
- "type": "git",
- "url": "https://github.com/laminas/laminas-dependency-plugin.git",
- "reference": "73cfb63ddca9d6bfedad5e0a038f6d55063975a3"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/laminas/laminas-dependency-plugin/zipball/73cfb63ddca9d6bfedad5e0a038f6d55063975a3",
- "reference": "73cfb63ddca9d6bfedad5e0a038f6d55063975a3",
- "shasum": ""
- },
- "require": {
- "composer-plugin-api": "^1.1 || ^2.0",
- "php": "^7.3 || ~8.0.0 || ~8.1.0"
- },
- "require-dev": {
- "composer/composer": "^1.9 || ^2.0",
- "laminas/laminas-coding-standard": "^2.2.1",
- "mikey179/vfsstream": "^1.6.10@alpha",
- "phpunit/phpunit": "^9.5.5",
- "psalm/plugin-phpunit": "^0.15.1",
- "roave/security-advisories": "dev-master",
- "vimeo/psalm": "^4.5"
- },
- "type": "composer-plugin",
- "extra": {
- "class": "Laminas\\DependencyPlugin\\DependencyRewriterPluginDelegator"
- },
- "autoload": {
- "psr-4": {
- "Laminas\\DependencyPlugin\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "description": "Replace zendframework and zfcampus packages with their Laminas Project equivalents.",
- "support": {
- "issues": "https://github.com/laminas/laminas-dependency-plugin/issues",
- "source": "https://github.com/laminas/laminas-dependency-plugin/tree/2.2.0"
- },
- "funding": [
- {
- "url": "https://funding.communitybridge.org/projects/laminas-project",
- "type": "community_bridge"
- }
- ],
- "time": "2021-09-08T17:51:35+00:00"
- },
{
"name": "mikey179/vfsstream",
"version": "v1.6.11-alpha.0",
@@ -4871,37 +4823,29 @@
},
{
"name": "symfony/service-contracts",
- "version": "v2.5.2",
+ "version": "v1.1.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/service-contracts.git",
- "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c"
+ "reference": "191afdcb5804db960d26d8566b7e9a2843cab3a0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/service-contracts/zipball/4b426aac47d6427cc1a1d0f7e2ac724627f5966c",
- "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c",
+ "url": "https://api.github.com/repos/symfony/service-contracts/zipball/191afdcb5804db960d26d8566b7e9a2843cab3a0",
+ "reference": "191afdcb5804db960d26d8566b7e9a2843cab3a0",
"shasum": ""
},
"require": {
- "php": ">=7.2.5",
- "psr/container": "^1.1",
- "symfony/deprecation-contracts": "^2.1|^3"
- },
- "conflict": {
- "ext-psr": "<1.1|>=2"
+ "php": "^7.1.3"
},
"suggest": {
+ "psr/container": "",
"symfony/service-implementation": ""
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "2.5-dev"
- },
- "thanks": {
- "name": "symfony/contracts",
- "url": "https://github.com/symfony/contracts"
+ "dev-master": "1.1-dev"
}
},
"autoload": {
@@ -4934,23 +4878,9 @@
"standards"
],
"support": {
- "source": "https://github.com/symfony/service-contracts/tree/v2.5.2"
+ "source": "https://github.com/symfony/service-contracts/tree/v1.1.2"
},
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2022-05-30T19:17:29+00:00"
+ "time": "2019-05-28T07:50:59+00:00"
},
{
"name": "symfony/string",
@@ -5427,7 +5357,8 @@
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
- "php": "~7.4.0 || ~8.0.0 || ~8.1.0"
+ "php": "~7.4.0 || ~8.0.0 || ~8.1.0",
+ "composer-plugin-api": "^2.0"
},
"platform-dev": [],
"platform-overrides": {
diff --git a/phpcs.xml.dist b/phpcs.xml.dist
index a8083863..021c54c3 100644
--- a/phpcs.xml.dist
+++ b/phpcs.xml.dist
@@ -16,6 +16,8 @@
bin
src
test
+
+ src/AbstractUntypedContainerImplementation.php
test/TestAsset/laminas-code/*.php
diff --git a/psalm-baseline.xml b/psalm-baseline.xml
index 8ea35319..cd08d409 100644
--- a/psalm-baseline.xml
+++ b/psalm-baseline.xml
@@ -141,10 +141,6 @@
$config['services']
$config['shared']
-
- $name
- $name
-
(bool) $flag
(bool) $flag
diff --git a/psalm.xml.dist b/psalm.xml.dist
index d71e2eec..05e6a1b7 100644
--- a/psalm.xml.dist
+++ b/psalm.xml.dist
@@ -47,6 +47,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/AbstractPluginManager.php b/src/AbstractPluginManager.php
index fe8a85d4..53fc86e7 100644
--- a/src/AbstractPluginManager.php
+++ b/src/AbstractPluginManager.php
@@ -174,8 +174,7 @@ public function get($name, ?array $options = null)
}
/**
- * {@inheritDoc}
- *
+ * @param mixed $instance
* @psalm-assert InstanceType $instance
*/
public function validate($instance)
diff --git a/src/AbstractTypedContainerImplementation.php b/src/AbstractTypedContainerImplementation.php
new file mode 100644
index 00000000..fe7db2c0
--- /dev/null
+++ b/src/AbstractTypedContainerImplementation.php
@@ -0,0 +1,63 @@
+hasService($id);
+ }
+
+ /**
+ * Finds an entry of the container by its identifier and returns it.
+ *
+ * @param string $id Identifier of the entry to look for.
+ * @psalm-param string|class-string $id
+ * @throws NotFoundExceptionInterface No entry was found for **this** identifier.
+ * @throws ContainerExceptionInterface Error while retrieving the entry.
+ * @return mixed Entry.
+ */
+ public function get(string $id)
+ {
+ return $this->getService($id);
+ }
+
+ /**
+ * @internal
+ *
+ * @psalm-param string|class-string $name
+ */
+ abstract protected function hasService(string $name): bool;
+
+ /**
+ * @internal
+ *
+ * @psalm-param string|class-string $name
+ * @throws NotFoundExceptionInterface No entry was found for **this** identifier.
+ * @throws ContainerExceptionInterface Error while retrieving the entry.
+ * @return mixed
+ */
+ abstract protected function getService(string $name);
+}
diff --git a/src/AbstractUntypedContainerImplementation.php b/src/AbstractUntypedContainerImplementation.php
new file mode 100644
index 00000000..22a62f13
--- /dev/null
+++ b/src/AbstractUntypedContainerImplementation.php
@@ -0,0 +1,72 @@
+hasService($id);
+ }
+
+ /**
+ * Finds an entry of the container by its identifier and returns it.
+ *
+ * @param string $id Identifier of the entry to look for.
+ * @psalm-param string|class-string $id
+ *
+ * @throws NotFoundExceptionInterface No entry was found for **this** identifier.
+ * @throws ContainerExceptionInterface Error while retrieving the entry.
+ *
+ * @return mixed Entry.
+ */
+ public function get($id)
+ {
+ return $this->getService($id);
+ }
+
+ /**
+ * @internal
+ *
+ * @psalm-param string|class-string $name
+ */
+ abstract protected function hasService(string $name): bool;
+
+ /**
+ * @internal
+ *
+ * @psalm-param string|class-string $name
+ * @throws NotFoundExceptionInterface No entry was found for **this** identifier.
+ * @throws ContainerExceptionInterface Error while retrieving the entry.
+ * @return mixed
+ */
+ abstract protected function getService(string $name);
+}
diff --git a/src/ServiceManager.php b/src/ServiceManager.php
index c87879c1..e0fb69fe 100644
--- a/src/ServiceManager.php
+++ b/src/ServiceManager.php
@@ -19,6 +19,7 @@
use ProxyManager\GeneratorStrategy\FileWriterGeneratorStrategy;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface;
+use Psr\Container\NotFoundExceptionInterface;
use function array_intersect;
use function array_key_exists;
@@ -61,8 +62,9 @@
* @psalm-import-type InitializersConfigurationType from ConfigInterface
* @psalm-import-type LazyServicesConfigurationType from ConfigInterface
* @psalm-type ServiceManagerConfiguration = array{shared_by_default?:bool}&ServiceManagerConfigurationType
+ * phpcs:disable WebimpressCodingStandard.PHP.CorrectClassNameCase.Invalid
*/
-class ServiceManager implements ServiceLocatorInterface
+class ServiceManager extends AbstractContainerImplementation implements ServiceLocatorInterface
{
/** @var Factory\AbstractFactoryInterface[] */
protected $abstractFactories = [];
@@ -187,9 +189,25 @@ public function getServiceLocator()
}
/**
- * {@inheritDoc}
+ * @internal
+ *
+ * @psalm-param string|class-string $name
+ */
+ protected function hasService(string $name): bool
+ {
+ // Check static services and factories first to speedup the most common requests.
+ return $this->staticServiceOrFactoryCanCreate($name) || $this->abstractFactoryCanCreate($name);
+ }
+
+ /**
+ * @internal
+ *
+ * @psalm-param string|class-string $name
+ * @throws NotFoundExceptionInterface No entry was found for **this** identifier.
+ * @throws ContainerExceptionInterface Error while retrieving the entry.
+ * @return mixed
*/
- public function get($name)
+ protected function getService(string $name)
{
// We start by checking if we have cached the requested service;
// this is the fastest method.
@@ -257,18 +275,6 @@ public function build($name, ?array $options = null)
return $this->doCreate($name, $options);
}
- /**
- * {@inheritDoc}
- *
- * @param string|class-string $name
- * @return bool
- */
- public function has($name)
- {
- // Check static services and factories first to speedup the most common requests.
- return $this->staticServiceOrFactoryCanCreate($name) || $this->abstractFactoryCanCreate($name);
- }
-
/**
* Indicate whether or not the instance is immutable.
*
diff --git a/src/autoload.php b/src/autoload.php
index 76bd64e0..1e5fbfc1 100644
--- a/src/autoload.php
+++ b/src/autoload.php
@@ -3,6 +3,9 @@
declare(strict_types=1);
+namespace Laminas\ServiceManager;
+
+use Composer\InstalledVersions;
use Interop\Container\Containerinterface as InteropContainerInterface;
use Interop\Container\Exception\ContainerException as InteropContainerException;
use Interop\Container\Exception\NotFoundException as InteropNotFoundException;
@@ -10,6 +13,11 @@
use Psr\Container\ContainerInterface;
use Psr\Container\NotFoundExceptionInterface;
+use function assert;
+use function class_alias;
+use function interface_exists;
+use function version_compare;
+
if (! interface_exists(InteropContainerInterface::class, false)) {
class_alias(ContainerInterface::class, InteropContainerInterface::class);
}
@@ -19,3 +27,16 @@ class_alias(ContainerExceptionInterface::class, InteropContainerException::class
if (! interface_exists(InteropNotFoundException::class, false)) {
class_alias(NotFoundExceptionInterface::class, InteropNotFoundException::class);
}
+
+$installedContainerVersion = InstalledVersions::getVersion('psr/container');
+
+assert(
+ $installedContainerVersion !== null,
+ 'psr/container is required by `composer.json` and therefore this method should not return `null`.'
+);
+
+if (version_compare($installedContainerVersion, '2', '<')) {
+ class_alias(AbstractUntypedContainerImplementation::class, AbstractContainerImplementation::class);
+} else {
+ class_alias(AbstractTypedContainerImplementation::class, AbstractContainerImplementation::class);
+}
diff --git a/test/AbstractFactory/ReflectionBasedAbstractFactoryTest.php b/test/AbstractFactory/ReflectionBasedAbstractFactoryTest.php
index 015d0668..b406e333 100644
--- a/test/AbstractFactory/ReflectionBasedAbstractFactoryTest.php
+++ b/test/AbstractFactory/ReflectionBasedAbstractFactoryTest.php
@@ -7,23 +7,20 @@
use ArrayAccess;
use Laminas\ServiceManager\AbstractFactory\ReflectionBasedAbstractFactory;
use Laminas\ServiceManager\Exception\ServiceNotFoundException;
+use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
-use Prophecy\PhpUnit\ProphecyTrait;
-use Prophecy\Prophecy\ObjectProphecy;
use Psr\Container\ContainerInterface;
use function sprintf;
class ReflectionBasedAbstractFactoryTest extends TestCase
{
- use ProphecyTrait;
-
- /** @var ObjectProphecy */
- private ObjectProphecy $container;
+ /** @var MockObject&ContainerInterface */
+ private ContainerInterface $container;
public function setUp(): void
{
- $this->container = $this->prophesize(ContainerInterface::class);
+ $this->container = $this->createMock(ContainerInterface::class);
}
public function nonClassRequestedNames(): array
@@ -39,14 +36,14 @@ public function nonClassRequestedNames(): array
public function testCanCreateReturnsFalseForNonClassRequestedNames(string $requestedName): void
{
$factory = new ReflectionBasedAbstractFactory();
- $this->assertFalse($factory->canCreate($this->container->reveal(), $requestedName));
+ $this->assertFalse($factory->canCreate($this->container, $requestedName));
}
public function testCanCreateReturnsFalseWhenConstructorIsPrivate(): void
{
$this->assertFalse(
(new ReflectionBasedAbstractFactory())->canCreate(
- $this->container->reveal(),
+ $this->container,
TestAsset\ClassWithPrivateConstructor::class
),
'ReflectionBasedAbstractFactory should not be able to instantiate a class with a private constructor'
@@ -57,7 +54,7 @@ public function testCanCreateReturnsTrueWhenClassHasNoConstructor(): void
{
$this->assertTrue(
(new ReflectionBasedAbstractFactory())->canCreate(
- $this->container->reveal(),
+ $this->container,
TestAsset\ClassWithNoConstructor::class
),
'ReflectionBasedAbstractFactory should be able to instantiate a class without a constructor'
@@ -67,21 +64,24 @@ public function testCanCreateReturnsTrueWhenClassHasNoConstructor(): void
public function testFactoryInstantiatesClassDirectlyIfItHasNoConstructor(): void
{
$factory = new ReflectionBasedAbstractFactory();
- $instance = $factory($this->container->reveal(), TestAsset\ClassWithNoConstructor::class);
+ $instance = $factory($this->container, TestAsset\ClassWithNoConstructor::class);
$this->assertInstanceOf(TestAsset\ClassWithNoConstructor::class, $instance);
}
public function testFactoryInstantiatesClassDirectlyIfConstructorHasNoArguments(): void
{
$factory = new ReflectionBasedAbstractFactory();
- $instance = $factory($this->container->reveal(), TestAsset\ClassWithEmptyConstructor::class);
+ $instance = $factory($this->container, TestAsset\ClassWithEmptyConstructor::class);
$this->assertInstanceOf(TestAsset\ClassWithEmptyConstructor::class, $instance);
}
public function testFactoryRaisesExceptionWhenUnableToResolveATypeHintedService(): void
{
- $this->container->has(TestAsset\SampleInterface::class)->willReturn(false);
- $this->container->has('config')->willReturn(false);
+ $this->container
+ ->method('has')
+ ->withConsecutive(['config'], [TestAsset\SampleInterface::class])
+ ->willReturn(false);
+
$factory = new ReflectionBasedAbstractFactory();
$this->expectException(ServiceNotFoundException::class);
$this->expectExceptionMessage(sprintf(
@@ -89,7 +89,7 @@ public function testFactoryRaisesExceptionWhenUnableToResolveATypeHintedService(
TestAsset\ClassWithTypeHintedConstructorParameter::class,
TestAsset\SampleInterface::class
));
- $factory($this->container->reveal(), TestAsset\ClassWithTypeHintedConstructorParameter::class);
+ $factory($this->container, TestAsset\ClassWithTypeHintedConstructorParameter::class);
}
public function testFactoryRaisesExceptionForScalarParameters(): void
@@ -100,45 +100,57 @@ public function testFactoryRaisesExceptionForScalarParameters(): void
'Unable to create service "%s"; unable to resolve parameter "foo" to a class, interface, or array type',
TestAsset\ClassWithScalarParameters::class
));
- $factory($this->container->reveal(), TestAsset\ClassWithScalarParameters::class);
+ $factory($this->container, TestAsset\ClassWithScalarParameters::class);
}
public function testFactoryInjectsConfigServiceForConfigArgumentsTypeHintedAsArray(): void
{
$config = ['foo' => 'bar'];
- $this->container->has('config')->willReturn(true);
- $this->container->get('config')->willReturn($config);
+ $this->container->method('has')->with('config')->willReturn(true);
+ $this->container->method('get')->with('config')->willReturn($config);
$factory = new ReflectionBasedAbstractFactory();
- $instance = $factory($this->container->reveal(), TestAsset\ClassAcceptingConfigToConstructor::class);
+ $instance = $factory($this->container, TestAsset\ClassAcceptingConfigToConstructor::class);
$this->assertInstanceOf(TestAsset\ClassAcceptingConfigToConstructor::class, $instance);
$this->assertEquals($config, $instance->config);
}
public function testFactoryCanInjectKnownTypeHintedServices(): void
{
- $sample = $this->prophesize(TestAsset\SampleInterface::class)->reveal();
- $this->container->has('config')->willReturn(false);
- $this->container->has(TestAsset\SampleInterface::class)->willReturn(true);
- $this->container->get(TestAsset\SampleInterface::class)->willReturn($sample);
+ $sample = $this->createStub(TestAsset\SampleInterface::class);
+ $this->container
+ ->method('has')
+ ->withConsecutive(['config'], [TestAsset\SampleInterface::class])
+ ->willReturnOnConsecutiveCalls(false, true);
+
+ $this->container
+ ->expects(self::once())
+ ->method('get')
+ ->with(TestAsset\SampleInterface::class)
+ ->willReturn($sample);
$factory = new ReflectionBasedAbstractFactory();
- $instance = $factory($this->container->reveal(), TestAsset\ClassWithTypeHintedConstructorParameter::class);
+ $instance = $factory($this->container, TestAsset\ClassWithTypeHintedConstructorParameter::class);
$this->assertInstanceOf(TestAsset\ClassWithTypeHintedConstructorParameter::class, $instance);
$this->assertSame($sample, $instance->sample);
}
public function testFactoryResolvesTypeHintsForServicesToWellKnownServiceNames(): void
{
- $this->container->has('config')->willReturn(false);
+ $this->container
+ ->method('has')
+ ->withConsecutive(['config'], ['ValidatorManager'])
+ ->willReturnOnConsecutiveCalls(false, true);
- $validators = $this->prophesize(TestAsset\ValidatorPluginManager::class)->reveal();
- $this->container->has('ValidatorManager')->willReturn(true);
- $this->container->get('ValidatorManager')->willReturn($validators);
+ $validators = $this->createStub(TestAsset\ValidatorPluginManager::class);
+ $this->container
+ ->method('get')
+ ->with('ValidatorManager')
+ ->willReturn($validators);
$factory = new ReflectionBasedAbstractFactory([TestAsset\ValidatorPluginManager::class => 'ValidatorManager']);
$instance = $factory(
- $this->container->reveal(),
+ $this->container,
TestAsset\ClassAcceptingWellKnownServicesAsConstructorParameters::class
);
$this->assertInstanceOf(
@@ -150,20 +162,22 @@ public function testFactoryResolvesTypeHintsForServicesToWellKnownServiceNames()
public function testFactoryCanSupplyAMixOfParameterTypes(): void
{
- $validators = $this->prophesize(TestAsset\ValidatorPluginManager::class)->reveal();
- $this->container->has('ValidatorManager')->willReturn(true);
- $this->container->get('ValidatorManager')->willReturn($validators);
-
- $sample = $this->prophesize(TestAsset\SampleInterface::class)->reveal();
- $this->container->has(TestAsset\SampleInterface::class)->willReturn(true);
- $this->container->get(TestAsset\SampleInterface::class)->willReturn($sample);
+ $validators = $this->createStub(TestAsset\ValidatorPluginManager::class);
+ $this->container
+ ->method('has')
+ ->withConsecutive(['config'], [TestAsset\SampleInterface::class], ['ValidatorManager'])
+ ->willReturn(true);
+ $sample = $this->createStub(TestAsset\SampleInterface::class);
$config = ['foo' => 'bar'];
- $this->container->has('config')->willReturn(true);
- $this->container->get('config')->willReturn($config);
+
+ $this->container
+ ->method('get')
+ ->withConsecutive([TestAsset\SampleInterface::class], ['ValidatorManager'], ['config'])
+ ->willReturnOnConsecutiveCalls($sample, $validators, $config);
$factory = new ReflectionBasedAbstractFactory([TestAsset\ValidatorPluginManager::class => 'ValidatorManager']);
- $instance = $factory($this->container->reveal(), TestAsset\ClassWithMixedConstructorParameters::class);
+ $instance = $factory($this->container, TestAsset\ClassWithMixedConstructorParameters::class);
$this->assertInstanceOf(TestAsset\ClassWithMixedConstructorParameters::class, $instance);
$this->assertEquals($config, $instance->config);
@@ -174,10 +188,10 @@ public function testFactoryCanSupplyAMixOfParameterTypes(): void
public function testFactoryWillUseDefaultValueWhenPresentForScalarArgument(): void
{
- $this->container->has('config')->willReturn(false);
+ $this->container->method('has')->with('config')->willReturn(false);
$factory = new ReflectionBasedAbstractFactory();
$instance = $factory(
- $this->container->reveal(),
+ $this->container,
TestAsset\ClassWithScalarDependencyDefiningDefaultValue::class
);
$this->assertInstanceOf(TestAsset\ClassWithScalarDependencyDefiningDefaultValue::class, $instance);
@@ -189,11 +203,13 @@ public function testFactoryWillUseDefaultValueWhenPresentForScalarArgument(): vo
*/
public function testFactoryWillUseDefaultValueForTypeHintedArgument(): void
{
- $this->container->has('config')->willReturn(false);
- $this->container->has(ArrayAccess::class)->willReturn(false);
+ $this->container
+ ->method('has')
+ ->withConsecutive(['config'], [ArrayAccess::class])
+ ->willReturn(false);
$factory = new ReflectionBasedAbstractFactory();
$instance = $factory(
- $this->container->reveal(),
+ $this->container,
TestAsset\ClassWithTypehintedDefaultValue::class
);
$this->assertInstanceOf(TestAsset\ClassWithTypehintedDefaultValue::class, $instance);
diff --git a/test/AbstractPluginManagerTest.php b/test/AbstractPluginManagerTest.php
index 15801d83..4dfe9c43 100644
--- a/test/AbstractPluginManagerTest.php
+++ b/test/AbstractPluginManagerTest.php
@@ -17,7 +17,6 @@
use LaminasTest\ServiceManager\TestAsset\SimplePluginManager;
use LaminasTest\ServiceManager\TestAsset\V2v3PluginManager;
use PHPUnit\Framework\TestCase;
-use Prophecy\PhpUnit\ProphecyTrait;
use Psr\Container\ContainerInterface;
use stdClass;
@@ -33,7 +32,6 @@
class AbstractPluginManagerTest extends TestCase
{
use CommonServiceLocatorBehaviorsTrait;
- use ProphecyTrait;
public function createContainer(array $config = []): ServiceManager
{
@@ -43,8 +41,7 @@ public function createContainer(array $config = []): ServiceManager
public function testInjectCreationContextInFactories(): void
{
- $invokableFactory = $this->getMockBuilder(FactoryInterface::class)
- ->getMock();
+ $invokableFactory = $this->createMock(FactoryInterface::class);
$config = [
'factories' => [
@@ -52,8 +49,7 @@ public function testInjectCreationContextInFactories(): void
],
];
- $container = $this->getMockBuilder(ContainerInterface::class)
- ->getMock();
+ $container = $this->createStub(ContainerInterface::class);
$pluginManager = new SimplePluginManager($container, $config);
$invokableFactory->expects($this->once())
@@ -75,8 +71,7 @@ public function testValidateInstance(): void
],
];
- $container = $this->getMockBuilder(ContainerInterface::class)
- ->getMock();
+ $container = $this->createStub(ContainerInterface::class);
$pluginManager = new SimplePluginManager($container, $config);
// Assert no exception is triggered because the plugin manager validate ObjectWithOptions
@@ -95,8 +90,7 @@ public function testCachesInstanceByDefaultIfNoOptionsArePassed(): void
],
];
- $container = $this->getMockBuilder(ContainerInterface::class)
- ->getMock();
+ $container = $this->createStub(ContainerInterface::class);
$pluginManager = new SimplePluginManager($container, $config);
$first = $pluginManager->get(InvokableObject::class);
@@ -128,8 +122,7 @@ public function testReturnsDiscreteInstancesIfOptionsAreProvidedRegardlessOfShar
];
$options = ['foo' => 'bar'];
- $container = $this->getMockBuilder(ContainerInterface::class)
- ->getMock();
+ $container = $this->createStub(ContainerInterface::class);
$pluginManager = new SimplePluginManager($container, $config);
$first = $pluginManager->get(InvokableObject::class, $options);
@@ -235,13 +228,13 @@ public function testPassingNoInitialConstructorArgumentSetsPluginManagerAsCreati
*/
public function testCanPassConfigInterfaceAsFirstConstructorArgumentWithDeprecationNotice(): void
{
- $config = $this->prophesize(ConfigInterface::class);
- $config->toArray()->willReturn([]);
+ $config = $this->createStub(ConfigInterface::class);
+ $config->method('toArray')->willReturn([]);
set_error_handler(function ($errno, $errstr) {
$this->assertEquals(E_USER_DEPRECATED, $errno);
}, E_USER_DEPRECATED);
- $pluginManager = new TestAsset\LenientPluginManager($config->reveal());
+ $pluginManager = new TestAsset\LenientPluginManager($config);
restore_error_handler();
$this->assertSame($pluginManager, $pluginManager->getCreationContext());
@@ -278,13 +271,15 @@ public function testPassingNonContainerNonConfigNonNullFirstConstructorArgumentR
*/
public function testPassingConfigInstanceAsFirstConstructorArgumentSkipsSecondArgumentWithDeprecationNotice(): void
{
- $config = $this->prophesize(ConfigInterface::class);
- $config->toArray()->willReturn(['services' => [self::class => $this]]);
+ $config = $this->createMock(ConfigInterface::class);
+ $config
+ ->method('toArray')
+ ->willReturn(['services' => [self::class => $this]]);
set_error_handler(function ($errno, $errstr) {
$this->assertEquals(E_USER_DEPRECATED, $errno);
}, E_USER_DEPRECATED);
- $pluginManager = new TestAsset\LenientPluginManager($config->reveal(), ['services' => [self::class => []]]);
+ $pluginManager = new TestAsset\LenientPluginManager($config, ['services' => [self::class => []]]);
restore_error_handler();
$this->assertSame($this, $pluginManager->get(self::class));
@@ -378,12 +373,18 @@ public function testAbstractFactoryGetsCreationContext(): void
{
$serviceManager = new ServiceManager();
$pluginManager = new SimplePluginManager($serviceManager);
- $abstractFactory = $this->prophesize(AbstractFactoryInterface::class);
- $abstractFactory->canCreate($serviceManager, 'foo')
+ $abstractFactory = $this->createMock(AbstractFactoryInterface::class);
+ $abstractFactory
+ ->method('canCreate')
+ ->with($serviceManager, 'foo')
->willReturn(true);
- $abstractFactory->__invoke($serviceManager, 'foo', null)
+
+ $abstractFactory
+ ->method('__invoke')
+ ->with($serviceManager, 'foo', null)
->willReturn(new InvokableObject());
- $pluginManager->addAbstractFactory($abstractFactory->reveal());
+
+ $pluginManager->addAbstractFactory($abstractFactory);
$this->assertInstanceOf(InvokableObject::class, $pluginManager->get('foo'));
}
diff --git a/test/ConfigTest.php b/test/ConfigTest.php
index 1e456005..a157f791 100644
--- a/test/ConfigTest.php
+++ b/test/ConfigTest.php
@@ -7,15 +7,12 @@
use Laminas\ServiceManager\Config;
use Laminas\ServiceManager\ServiceManager;
use PHPUnit\Framework\TestCase;
-use Prophecy\PhpUnit\ProphecyTrait;
/**
* @covers Laminas\ServiceManager\Config
*/
class ConfigTest extends TestCase
{
- use ProphecyTrait;
-
public function testMergeArrays(): void
{
$config = [
@@ -103,12 +100,12 @@ public function testPassesKnownServiceConfigKeysToServiceManagerWithConfigMethod
'baz' => 'bat',
];
- $services = $this->prophesize(ServiceManager::class);
- $services->configure($expected)->willReturn('CALLED');
+ $services = $this->createMock(ServiceManager::class);
+ $services->method('configure')->with($expected)->willReturn('CALLED');
/** @psalm-suppress InvalidArgument Keeping this invalid configuration to ensure BC compatibility. */
$configuration = new Config($config);
- $this->assertEquals('CALLED', $configuration->configureServiceManager($services->reveal()));
+ $this->assertEquals('CALLED', $configuration->configureServiceManager($services));
return [
'array' => $expected,