diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 90608f0..8ebe78e 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -6,7 +6,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
- php: [ '8.0', '8.1', '8.2', '8.3', '8.4' ]
+ php: [ '8.2', '8.3', '8.4', '8.5' ]
steps:
- uses: actions/checkout@master
diff --git a/Makefile b/Makefile
index 4f33df0..89d71d8 100644
--- a/Makefile
+++ b/Makefile
@@ -1,14 +1,8 @@
.PHONY: tests
tests: vendor
- php -d zend.assertions=1 -d assert.exception=1 vendor/bin/peridot ./specs
+ php vendor/bin/pest
-vendor: composer.json composer.phar
- php composer.phar install
+vendor: composer.json
+ composer install
touch vendor
-
-composer.phar:
- php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
- php -r "if (hash_file('sha384', 'composer-setup.php') === 'dac665fdc30fdd8ec78b38b9800061b4150413ff2e3b6f88543c636f7cd84f6db9189d43a81e5503cda447da73c7e5b6') { echo 'Installer verified'.PHP_EOL; } else { echo 'Installer corrupt'.PHP_EOL; unlink('composer-setup.php'); exit(1); }"
- php composer-setup.php
- php -r "unlink('composer-setup.php');"
\ No newline at end of file
diff --git a/composer.json b/composer.json
index 00739ad..9eda63e 100644
--- a/composer.json
+++ b/composer.json
@@ -9,14 +9,14 @@
"auto-wiring"
],
"require": {
- "php": "^8.0",
+ "php": "^8.2",
"psr/container": "^2.0",
"technically/null-container": "^2.0",
- "technically/callable-reflection": "^0.4.2"
+ "technically/callable-reflection": "^0.5.0"
},
"require-dev": {
- "peridot-php/peridot": "^1.19",
- "technically/array-container": "^2.0"
+ "technically/array-container": "^2.0",
+ "pestphp/pest": "^2.0 || ^3.0 || ^4.0"
},
"license": "MIT",
"authors": [
@@ -33,7 +33,12 @@
},
"autoload-dev": {
"psr-4": {
- "Technically\\DependencyResolver\\Specs\\": "specs"
+ "Technically\\DependencyResolver\\Tests\\": "tests"
+ }
+ },
+ "config": {
+ "allow-plugins": {
+ "pestphp/pest-plugin": true
}
}
}
diff --git a/phpunit.xml b/phpunit.xml
new file mode 100644
index 0000000..37c9c51
--- /dev/null
+++ b/phpunit.xml
@@ -0,0 +1,17 @@
+
+
+
+
+ ./tests
+
+
+
+
+ src
+
+
+
diff --git a/specs/Fixtures/MyAbstractClass.php b/specs/Fixtures/MyAbstractClass.php
deleted file mode 100644
index dccc695..0000000
--- a/specs/Fixtures/MyAbstractClass.php
+++ /dev/null
@@ -1,8 +0,0 @@
-parent = $parent;
- }
-}
diff --git a/src/Contracts/DependencyResolver.php b/src/Contracts/DependencyResolver.php
index 7582f3b..bcd369d 100644
--- a/src/Contracts/DependencyResolver.php
+++ b/src/Contracts/DependencyResolver.php
@@ -17,8 +17,9 @@ interface DependencyResolver
* It can be either found in the container or constructed on the fly,
* recursively auto-resolving the required parameters.
*
- * @param class-string $className
- * @return mixed
+ * @template T
+ * @param class-string $className
+ * @return T
*
* @throws InvalidArgumentException If the class does not exist.
* @throws ContainerExceptionInterface If an error occurs while retrieving the existing entry from the container.
@@ -33,9 +34,10 @@ public function resolve(string $className): mixed;
* Even if the container already has the instance bound,
* it will still be instantiated.
*
- * @param class-string $className
+ * @template T
+ * @param class-string $className
* @param array $bindings
- * @return mixed
+ * @return T
*
* @throws ClassCannotBeInstantiated
* @throws CannotAutowireDependencyArgument
diff --git a/src/DependencyResolver.php b/src/DependencyResolver.php
index 9ec9f8b..5b02801 100644
--- a/src/DependencyResolver.php
+++ b/src/DependencyResolver.php
@@ -25,8 +25,9 @@ public function __construct(?ContainerInterface $container = null)
}
/**
- * @param class-string $className
- * @return mixed
+ * @template T
+ * @param class-string $className
+ * @return T
*
* @throws InvalidArgumentException If class does not exist.
* @throws ContainerExceptionInterface If error occurs while retrieving the existing entry from the container.
@@ -47,9 +48,10 @@ public function resolve(string $className): mixed
}
/**
- * @param class-string $className
+ * @template T
+ * @param class-string $className
* @param array $bindings
- * @return mixed
+ * @return T
*
* @throws ClassCannotBeInstantiated
* @throws CannotAutowireDependencyArgument
@@ -125,7 +127,6 @@ private function resolveParameters(array $parameters, array $bindings = []): arr
}
/**
- * @param ParameterReflection $parameter
* @return mixed|null
*
* @throws CannotAutowireArgument
@@ -136,7 +137,7 @@ private function resolveParameter(ParameterReflection $parameter): mixed
if ($type->isClassRequirement() && $this->container->has($class = $type->getClassRequirement())) {
try {
return $this->container->get($class);
- } catch (ContainerExceptionInterface $exception) {
+ } catch (ContainerExceptionInterface) {
throw new CannotAutowireArgument($parameter->getName());
}
}
@@ -155,7 +156,7 @@ private function resolveParameter(ParameterReflection $parameter): mixed
$class = $type->getClassRequirement();
try {
return $this->construct($class);
- } catch (DependencyResolutionException $exception) {
+ } catch (DependencyResolutionException) {
// try another one
}
}
diff --git a/src/Exceptions/CannotAutowireArgument.php b/src/Exceptions/CannotAutowireArgument.php
index 510c340..bf65c32 100644
--- a/src/Exceptions/CannotAutowireArgument.php
+++ b/src/Exceptions/CannotAutowireArgument.php
@@ -15,7 +15,7 @@ final class CannotAutowireArgument extends DependencyResolutionException
* @param string $argumentName
* @param Throwable|null $previous
*/
- public function __construct(string $argumentName, Throwable $previous = null)
+ public function __construct(string $argumentName, Throwable | null $previous = null)
{
$this->argumentName = $argumentName;
diff --git a/src/Exceptions/CannotAutowireDependencyArgument.php b/src/Exceptions/CannotAutowireDependencyArgument.php
index c1af508..ab5f139 100644
--- a/src/Exceptions/CannotAutowireDependencyArgument.php
+++ b/src/Exceptions/CannotAutowireDependencyArgument.php
@@ -21,12 +21,12 @@ final class CannotAutowireDependencyArgument extends DependencyResolutionExcepti
* @param string $argumentName
* @param Throwable|null $previous
*/
- public function __construct(string $dependencyName, string $argumentName, Throwable $previous = null)
+ public function __construct(string $dependencyName, string $argumentName, Throwable | null $previous = null)
{
$this->dependencyName = $dependencyName;
$this->argumentName = $argumentName;
- parent::__construct("Could not autowire argument `{$argumentName}` for `${dependencyName}`.", 0, $previous);
+ parent::__construct("Could not autowire argument `{$argumentName}` for `{$dependencyName}`.", 0, $previous);
}
/**
diff --git a/src/Exceptions/ClassCannotBeInstantiated.php b/src/Exceptions/ClassCannotBeInstantiated.php
index ab485cb..e291332 100644
--- a/src/Exceptions/ClassCannotBeInstantiated.php
+++ b/src/Exceptions/ClassCannotBeInstantiated.php
@@ -13,7 +13,7 @@ public function __construct(string $className)
{
$this->className = $className;
- parent::__construct("Class (${className}) cannot be instantiated.");
+ parent::__construct("Class ({$className}) cannot be instantiated.");
}
/**
diff --git a/specs/DependencyResolver.spec.php b/tests/DependencyResolver.spec.php
similarity index 75%
rename from specs/DependencyResolver.spec.php
rename to tests/DependencyResolver.spec.php
index 518b954..2edfb45 100644
--- a/specs/DependencyResolver.spec.php
+++ b/tests/DependencyResolver.spec.php
@@ -6,6 +6,6 @@
it('should instantiate', function () {
$resolver = new DependencyResolver();
- assert($resolver instanceof DependencyResolver);
+ expect($resolver)->toBeInstanceOf(DependencyResolver::class);
});
});
diff --git a/specs/DependencyResolver::call.spec.php b/tests/DependencyResolver::call.spec.php
similarity index 76%
rename from specs/DependencyResolver::call.spec.php
rename to tests/DependencyResolver::call.spec.php
index 77c61a7..50fc189 100644
--- a/specs/DependencyResolver::call.spec.php
+++ b/tests/DependencyResolver::call.spec.php
@@ -3,9 +3,9 @@
use Psr\Container\ContainerInterface;
use Technically\ArrayContainer\ArrayContainer;
use Technically\DependencyResolver\DependencyResolver;
-use Technically\DependencyResolver\Specs\Fixtures\MyInstanceMethodService;
-use Technically\DependencyResolver\Specs\Fixtures\MyInvokableService;
-use Technically\DependencyResolver\Specs\Fixtures\MyStaticMethodService;
+use Technically\DependencyResolver\Tests\Fixtures\MyInstanceMethodService;
+use Technically\DependencyResolver\Tests\Fixtures\MyInvokableService;
+use Technically\DependencyResolver\Tests\Fixtures\MyStaticMethodService;
use Technically\NullContainer\NullContainer;
describe('DependencyResolver::call()', function () {
@@ -16,7 +16,7 @@
$value = $resolver->call('my_global_function', ['value' => $resolver]);
- assert($value === true);
+ expect($value)->toBeTrue();
});
it('should call Closures resolving dependencies', function () {
@@ -24,15 +24,15 @@
$resolver = new DependencyResolver($container);
$container->set(DependencyResolver::class, $resolver);
- [$r, $m, $n] = $resolver->call(function (DependencyResolver $resolver, string $message, int $else = null) {
+ [$r, $m, $n] = $resolver->call(function (DependencyResolver $resolver, string $message, ?int $else = null) {
return [$resolver, $message, $else];
}, [
'message' => 'Hello'
]);
- assert($r === $resolver);
- assert($m === 'Hello');
- assert($n === null);
+ expect($r)->toBe($resolver);
+ expect($m)->toBe('Hello');
+ expect($n)->toBeNull();
});
it('should call static method array resolving dependencies', function () {
@@ -44,9 +44,9 @@
'message' => 'Hello'
]);
- assert($r === $resolver);
- assert($m === 'Hello');
- assert($n === null);
+ expect($r)->toBe($resolver);
+ expect($m)->toBe('Hello');
+ expect($n)->toBeNull();
});
it('should call static method string resolving dependencies', function () {
@@ -58,9 +58,9 @@
'message' => 'Hello'
]);
- assert($r === $resolver);
- assert($m === 'Hello');
- assert($n === null);
+ expect($r)->toBe($resolver);
+ expect($m)->toBe('Hello');
+ expect($n)->toBeNull();
});
it('should call instance methods resolving dependencies', function () {
@@ -72,9 +72,9 @@
'message' => 'Hello'
]);
- assert($r === $resolver);
- assert($m === 'Hello');
- assert($n === null);
+ expect($r)->toBe($resolver);
+ expect($m)->toBe('Hello');
+ expect($n)->toBeNull();
});
it('should call invokable objects resolving dependencies', function () {
@@ -86,9 +86,9 @@
'message' => 'Hello'
]);
- assert($r === $resolver);
- assert($m === 'Hello');
- assert($n === null);
+ expect($r)->toBe($resolver);
+ expect($m)->toBe('Hello');
+ expect($n)->toBeNull();
});
it('should resolve typed variadic parameters', function () {
@@ -100,8 +100,8 @@
return $containers;
});
- assert(is_array($ret));
- assert(count($ret) === 1);
+ expect($ret)->toBeArray();
+ expect($ret)->toHaveCount(1);
});
it('should call function by passing variadic parameter value explicitly', function () {
@@ -117,8 +117,8 @@
'containers' => [$null],
]);
- assert(is_array($ret));
- assert(count($ret) === 1);
- assert($ret === [$null]);
+ expect($ret)->toBeArray();
+ expect($ret)->toHaveCount(1);
+ expect($ret)->toBe([$null]);
});
});
diff --git a/specs/DependencyResolver::construct.spec.php b/tests/DependencyResolver::construct.spec.php
similarity index 54%
rename from specs/DependencyResolver::construct.spec.php
rename to tests/DependencyResolver::construct.spec.php
index 6733631..d837da0 100644
--- a/specs/DependencyResolver::construct.spec.php
+++ b/tests/DependencyResolver::construct.spec.php
@@ -5,16 +5,16 @@
use Technically\DependencyResolver\DependencyResolver;
use Technically\DependencyResolver\Exceptions\CannotAutowireDependencyArgument;
use Technically\DependencyResolver\Exceptions\ClassCannotBeInstantiated;
-use Technically\DependencyResolver\Specs\Fixtures\MyAbstractClass;
-use Technically\DependencyResolver\Specs\Fixtures\MyConcreteContainerService;
-use Technically\DependencyResolver\Specs\Fixtures\MyAbstractContainerService;
-use Technically\DependencyResolver\Specs\Fixtures\MyNullableArgumentService;
-use Technically\DependencyResolver\Specs\Fixtures\MyOptionalArgumentService;
-use Technically\DependencyResolver\Specs\Fixtures\MyParentDependencyService;
-use Technically\DependencyResolver\Specs\Fixtures\MySelfDependencyService;
-use Technically\DependencyResolver\Specs\Fixtures\MyUnionTypeDependencyService;
-use Technically\DependencyResolver\Specs\Fixtures\MyUnresolvableScalarArgumentService;
-use Technically\DependencyResolver\Specs\Fixtures\MyUntypedArgumentService;
+use Technically\DependencyResolver\Tests\Fixtures\MyAbstractClass;
+use Technically\DependencyResolver\Tests\Fixtures\MyConcreteContainerService;
+use Technically\DependencyResolver\Tests\Fixtures\MyAbstractContainerService;
+use Technically\DependencyResolver\Tests\Fixtures\MyNullableArgumentService;
+use Technically\DependencyResolver\Tests\Fixtures\MyOptionalArgumentService;
+use Technically\DependencyResolver\Tests\Fixtures\MyParentDependencyService;
+use Technically\DependencyResolver\Tests\Fixtures\MySelfDependencyService;
+use Technically\DependencyResolver\Tests\Fixtures\MyUnionTypeDependencyService;
+use Technically\DependencyResolver\Tests\Fixtures\MyUnresolvableScalarArgumentService;
+use Technically\DependencyResolver\Tests\Fixtures\MyUntypedArgumentService;
describe('DependencyResolver::construct()', function () {
it('should instantiate a class using the bindings passed', function () {
@@ -25,8 +25,8 @@
'container' => $container,
]);
- assert($resolved instanceof MyAbstractContainerService);
- assert($resolved->container === $container);
+ expect($resolved)->toBeInstanceOf(MyAbstractContainerService::class);
+ expect($resolved->container)->toBe($container);
});
it('should instantiate a class resolving dependencies from container, if possible', function () {
@@ -36,8 +36,8 @@
$resolved = $resolver->construct(MyAbstractContainerService::class);
- assert($resolved instanceof MyAbstractContainerService);
- assert($resolved->container === $container);
+ expect($resolved)->toBeInstanceOf(MyAbstractContainerService::class);
+ expect($resolved->container)->toBe($container);
});
it('should instantiate a class resolving self type dependency', function () {
@@ -50,10 +50,10 @@
$resolved = $resolver->construct(MySelfDependencyService::class);
- assert($resolved instanceof MySelfDependencyService);
- assert($resolved !== $service);
- assert($resolved->parent instanceof MySelfDependencyService);
- assert($resolved->parent === $service);
+ expect($resolved)->toBeInstanceOf(MySelfDependencyService::class);
+ expect($resolved)->not->toBe($service);
+ expect($resolved->parent)->toBeInstanceOf(MySelfDependencyService::class);
+ expect($resolved->parent)->toBe($service);
});
it('should instantiate a class resolving parent type dependency', function () {
@@ -66,9 +66,9 @@
$resolved = $resolver->construct(MyParentDependencyService::class);
- assert($resolved instanceof MyParentDependencyService);
- assert($resolved->parent instanceof MySelfDependencyService);
- assert($resolved->parent === $service);
+ expect($resolved)->toBeInstanceOf(MyParentDependencyService::class);
+ expect($resolved->parent)->toBeInstanceOf(MySelfDependencyService::class);
+ expect($resolved->parent)->toBe($service);
});
if (PHP_MAJOR_VERSION >= 8) {
@@ -79,8 +79,8 @@
$resolved = $resolver->construct(MyUnionTypeDependencyService::class);
- assert($resolved instanceof MyUnionTypeDependencyService);
- assert($resolved->input === $container);
+ expect($resolved)->toBeInstanceOf(MyUnionTypeDependencyService::class);
+ expect($resolved->input)->toBe($container);
});
}
@@ -90,9 +90,9 @@
$resolved = $resolver->construct(MyConcreteContainerService::class);
- assert($resolved instanceof MyConcreteContainerService);
- assert($resolved->container instanceof ArrayContainer);
- assert($resolved->container !== $container);
+ expect($resolved)->toBeInstanceOf(MyConcreteContainerService::class);
+ expect($resolved->container)->toBeInstanceOf(ArrayContainer::class);
+ expect($resolved->container)->not->toBe($container);
});
it('should instantiate a class falling back to default values, if possible', function () {
@@ -100,8 +100,8 @@
$resolved = $resolver->construct(MyOptionalArgumentService::class);
- assert($resolved instanceof MyOptionalArgumentService);
- assert($resolved->name === 'MyOptionalArgumentService');
+ expect($resolved)->toBeInstanceOf(MyOptionalArgumentService::class);
+ expect($resolved->name)->toBe('MyOptionalArgumentService');
});
it('should instantiate a class falling back to null when there is no other choice', function () {
@@ -109,8 +109,8 @@
$resolved = $resolver->construct(MyNullableArgumentService::class);
- assert($resolved instanceof MyNullableArgumentService);
- assert($resolved->container === null);
+ expect($resolved)->toBeInstanceOf(MyNullableArgumentService::class);
+ expect($resolved->container)->toBeNull();
});
it('should throw exception if class being resolved is abstract', function () {
@@ -122,9 +122,9 @@
// passthru
}
- assert(isset($exception));
- assert($exception instanceof ClassCannotBeInstantiated);
- assert($exception->getClassName() === MyAbstractClass::class);
+ expect(isset($exception))->toBeTrue();
+ expect($exception)->toBeInstanceOf(ClassCannotBeInstantiated::class);
+ expect($exception->getClassName())->toBe(MyAbstractClass::class);
});
it('should throw exception if dependency class cannot be autowired', function () {
@@ -136,11 +136,11 @@
// passthru
}
- assert(isset($exception));
- assert($exception instanceof CannotAutowireDependencyArgument);
- assert($exception->getDependencyName() === MyAbstractContainerService::class);
- assert($exception->getArgumentName() === 'container');
- assert($exception->getMessage() === 'Could not autowire argument `container` for `Technically\DependencyResolver\Specs\Fixtures\MyAbstractContainerService`.');
+ expect(isset($exception))->toBeTrue();
+ expect($exception)->toBeInstanceOf(CannotAutowireDependencyArgument::class);
+ expect($exception->getDependencyName())->toBe(MyAbstractContainerService::class);
+ expect($exception->getArgumentName())->toBe('container');
+ expect($exception->getMessage())->toBe('Could not autowire argument `container` for `Technically\DependencyResolver\Tests\Fixtures\MyAbstractContainerService`.');
});
it('should throw exception if scalar dependency cannot be autowired', function () {
@@ -152,11 +152,11 @@
// passthru
}
- assert(isset($exception));
- assert($exception instanceof CannotAutowireDependencyArgument);
- assert($exception->getDependencyName() === MyUnresolvableScalarArgumentService::class);
- assert($exception->getArgumentName() === 'name');
- assert($exception->getMessage() === 'Could not autowire argument `name` for `Technically\DependencyResolver\Specs\Fixtures\MyUnresolvableScalarArgumentService`.');
+ expect(isset($exception))->toBeTrue();
+ expect($exception)->toBeInstanceOf(CannotAutowireDependencyArgument::class);
+ expect($exception->getDependencyName())->toBe(MyUnresolvableScalarArgumentService::class);
+ expect($exception->getArgumentName())->toBe('name');
+ expect($exception->getMessage())->toBe('Could not autowire argument `name` for `Technically\DependencyResolver\Tests\Fixtures\MyUnresolvableScalarArgumentService`.');
});
it('should throw exception if untyped dependency cannot be autowired', function () {
@@ -168,10 +168,10 @@
// passthru
}
- assert(isset($exception));
- assert($exception instanceof CannotAutowireDependencyArgument);
- assert($exception->getDependencyName() === MyUntypedArgumentService::class);
- assert($exception->getArgumentName() === 'input');
- assert($exception->getMessage() === 'Could not autowire argument `input` for `Technically\DependencyResolver\Specs\Fixtures\MyUntypedArgumentService`.');
+ expect(isset($exception))->toBeTrue();
+ expect($exception)->toBeInstanceOf(CannotAutowireDependencyArgument::class);
+ expect($exception->getDependencyName())->toBe(MyUntypedArgumentService::class);
+ expect($exception->getArgumentName())->toBe('input');
+ expect($exception->getMessage())->toBe('Could not autowire argument `input` for `Technically\DependencyResolver\Tests\Fixtures\MyUntypedArgumentService`.');
});
});
diff --git a/specs/DependencyResolver::resolve.spec.php b/tests/DependencyResolver::resolve.spec.php
similarity index 70%
rename from specs/DependencyResolver::resolve.spec.php
rename to tests/DependencyResolver::resolve.spec.php
index dfa12d9..481d57b 100644
--- a/specs/DependencyResolver::resolve.spec.php
+++ b/tests/DependencyResolver::resolve.spec.php
@@ -12,8 +12,8 @@
$resolved = $resolver->resolve(DependencyResolver::class);
- assert($resolved instanceof DependencyResolver);
- assert($resolved === $resolver);
+ expect($resolved)->toBeInstanceOf(DependencyResolver::class);
+ expect($resolved)->toBe($resolver);
});
it('should construct a new instance if container does not have it already', function () {
@@ -22,8 +22,8 @@
$resolved = $resolver->resolve(DependencyResolver::class);
- assert($resolved instanceof DependencyResolver);
- assert($resolved !== $resolver);
+ expect($resolved)->toBeInstanceOf(DependencyResolver::class);
+ expect($resolved)->not->toBe($resolver);
});
it('should throw InvalidArgumentException if the given class does not exist', function () {
@@ -35,8 +35,8 @@
// passthru
}
- assert(isset($exception));
- assert($exception instanceof InvalidArgumentException);
- assert($exception->getMessage() === '`Foo` is not a valid class name.');
+ expect(isset($exception))->toBeTrue();
+ expect($exception)->toBeInstanceOf(InvalidArgumentException::class);
+ expect($exception->getMessage())->toBe('`Foo` is not a valid class name.');
});
});
diff --git a/tests/Fixtures/MyAbstractClass.php b/tests/Fixtures/MyAbstractClass.php
new file mode 100644
index 0000000..034b951
--- /dev/null
+++ b/tests/Fixtures/MyAbstractClass.php
@@ -0,0 +1,8 @@
+parent = $parent;
+ }
+}
diff --git a/specs/Fixtures/MyStaticMethodService.php b/tests/Fixtures/MyStaticMethodService.php
similarity index 69%
rename from specs/Fixtures/MyStaticMethodService.php
rename to tests/Fixtures/MyStaticMethodService.php
index 739caa3..c5f4b25 100644
--- a/specs/Fixtures/MyStaticMethodService.php
+++ b/tests/Fixtures/MyStaticMethodService.php
@@ -1,12 +1,12 @@