Skip to content

Commit

Permalink
MSI 100% (#62)
Browse files Browse the repository at this point in the history
  • Loading branch information
vjik committed Oct 26, 2023
1 parent 4f3a0d7 commit 1b2c230
Show file tree
Hide file tree
Showing 20 changed files with 261 additions and 44 deletions.
1 change: 1 addition & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ jobs:
phpunit:
uses: yiisoft/actions/.github/workflows/phpunit.yml@master
with:
ini-values: pcov.directory=$GITHUB_WORKSPACE, pcov.exclude=#^(?!($GITHUB_WORKSPACE/config/|$GITHUB_WORKSPACE/src/)).*#
os: >-
['ubuntu-latest', 'windows-latest']
php: >-
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/mutation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ jobs:
mutation:
uses: yiisoft/actions/.github/workflows/roave-infection.yml@master
with:
min-covered-msi: 100
os: >-
['ubuntu-latest']
php: >-
Expand Down
5 changes: 4 additions & 1 deletion infection.json.dist
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
}
},
"mutators": {
"@default": true
"@default": true,
"global-ignoreSourceCodeByRegex": [
"if \\(PHP_VERSION_ID.*"
]
}
}
2 changes: 1 addition & 1 deletion src/Exception/AbstractClassException.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public function __construct(ReflectionClass $reflectionClass)
{
parent::__construct(
sprintf(
'%s is not instantiable because it is abstract.',
'"%s" is not instantiable because it is abstract.',
$reflectionClass->getName(),
),
);
Expand Down
2 changes: 1 addition & 1 deletion src/Exception/NonExistClassException.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public function __construct(string $class)
{
parent::__construct(
sprintf(
'Class %s not exist.',
'Class "%s" not exist.',
$class
),
);
Expand Down
2 changes: 2 additions & 0 deletions src/Hydrator.php
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,11 @@ private function hydrateInternal(
new TypeCastContext($this, $property),
);
if ($result->isResolved()) {
// @codeCoverageIgnoreStart
if (PHP_VERSION_ID < 80100) {
$property->setAccessible(true);
}
// @codeCoverageIgnoreEnd
$property->setValue($object, $result->getValue());
}
}
Expand Down
1 change: 1 addition & 0 deletions src/Temp/RouteArgument.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

/**
* @codeCoverageIgnore
* @infection-ignore-all
*/
#[Attribute(Attribute::TARGET_PROPERTY | Attribute::TARGET_PARAMETER | Attribute::IS_REPEATABLE)]
final class RouteArgument implements ParameterAttributeInterface
Expand Down
1 change: 1 addition & 0 deletions src/Temp/RouteArgumentResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

/**
* @codeCoverageIgnore
* @infection-ignore-all
*/
final class RouteArgumentResolver implements ParameterAttributeResolverInterface
{
Expand Down
29 changes: 24 additions & 5 deletions tests/Attribute/Parameter/DiTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Yiisoft\Hydrator\Tests\Support\Attribute\Counter;
use Yiisoft\Hydrator\Tests\Support\Attribute\CounterResolver;
use Yiisoft\Hydrator\Tests\Support\Classes\CounterClass;
use Yiisoft\Hydrator\Tests\Support\Classes\DiNonExists;
use Yiisoft\Hydrator\Tests\Support\Classes\DiSingle;
use Yiisoft\Hydrator\Tests\Support\Classes\DiSingleConstructor;
use Yiisoft\Hydrator\Tests\Support\Classes\DiSingleNulledWithDefault;
Expand Down Expand Up @@ -48,6 +49,9 @@ public function testSingleWithoutTypeNotResolved(): void
$hydrator = $this->createHydrator();

$this->expectException(DiNotFoundException::class);
$this->expectExceptionMessage(
'Class property "' . DiSingleWithoutType::class . '::$engine" without type not resolved.'
);
$hydrator->create(DiSingleWithoutType::class);
}

Expand Down Expand Up @@ -77,11 +81,26 @@ public function testSingleNotResolved(): void

$this->assertInstanceOf(DiNotFoundException::class, $exception);
$this->assertSame(
'Class property "'
. DiSingle::class
. '::$engine" with type "'
. EngineInterface::class
. '" not resolved.',
'Class property "' . DiSingle::class . '::$engine" with type "' . EngineInterface::class . '" not resolved.',
$exception->getMessage()
);
$this->assertInstanceOf(NotFoundExceptionInterface::class, $exception->getPrevious());
}

public function testWithNonExistsId(): void
{
$hydrator = $this->createHydrator();

$exception = null;
try {
$hydrator->create(DiNonExists::class);
} catch (Throwable $e) {
$exception = $e;
}

$this->assertInstanceOf(DiNotFoundException::class, $exception);
$this->assertSame(
'Class property "' . DiNonExists::class . '::$engine" without type not resolved.',
$exception->getMessage()
);
$this->assertInstanceOf(NotFoundExceptionInterface::class, $exception->getPrevious());
Expand Down
24 changes: 23 additions & 1 deletion tests/Attribute/Parameter/ToStringTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,18 @@
namespace Yiisoft\Hydrator\Tests\Attribute\Parameter;

use PHPUnit\Framework\TestCase;
use Yiisoft\Hydrator\ArrayData;
use Yiisoft\Hydrator\Attribute\Parameter\ToString;
use Yiisoft\Hydrator\AttributeHandling\ParameterAttributeResolveContext;
use Yiisoft\Hydrator\Hydrator;
use Yiisoft\Hydrator\AttributeHandling\ResolverFactory\ContainerAttributeResolverFactory;
use Yiisoft\Hydrator\Result;
use Yiisoft\Hydrator\Tests\Support\Attribute\Counter;
use Yiisoft\Hydrator\Tests\Support\Attribute\CounterResolver;
use Yiisoft\Hydrator\Tests\Support\Classes\CounterClass;
use Yiisoft\Hydrator\Tests\Support\StringableObject;
use Yiisoft\Hydrator\AttributeHandling\Exception\UnexpectedAttributeException;
use Yiisoft\Hydrator\Tests\Support\TestHelper;
use Yiisoft\Test\Support\Container\SimpleContainer;

final class ToStringTest extends TestCase
Expand All @@ -33,7 +37,25 @@ public function dataBase(): array
/**
* @dataProvider dataBase
*/
public function testBase(string $expected, mixed $value): void
public function testBase(mixed $expected, mixed $value): void
{
$attribute = new ToString();
$context = new ParameterAttributeResolveContext(
TestHelper::getFirstParameter(static fn(string $a) => null),
Result::success($value),
new ArrayData(),
);

$result = $attribute->getParameterValue($attribute, $context);

$this->assertSame(true, $result->isResolved());
$this->assertSame($expected, $result->getValue());
}

/**
* @dataProvider dataBase
*/
public function testBaseWithHydrator(string $expected, mixed $value): void
{
$hydrator = new Hydrator();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Yiisoft\Hydrator\Tests\Support\Attribute\CustomValue;
use Yiisoft\Hydrator\Tests\Support\Attribute\ParameterizedResolver;
use Yiisoft\Hydrator\Tests\Support\Attribute\PrivateConstructorResolver;
use Yiisoft\Hydrator\Tests\Support\Attribute\ResolverWithConstructorWithoutParameters;

final class ReflectionAttributeResolverFactoryTest extends TestCase
{
Expand Down Expand Up @@ -80,4 +81,14 @@ public function testConstructorWithParameters(): void
);
$factory->create($attribute);
}

public function testConstructorWithoutParameters(): void
{
$attribute = new CustomResolverAttr(ResolverWithConstructorWithoutParameters::class);
$factory = new ReflectionAttributeResolverFactory();

$resolver = $factory->create($attribute);

$this->assertInstanceOf(ResolverWithConstructorWithoutParameters::class, $resolver);
}
}
2 changes: 2 additions & 0 deletions tests/HydratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,7 @@ public function testCreateInstanceOfAbstractClass(): void
$hydrator = new Hydrator();

$this->expectException(AbstractClassException::class);
$this->expectExceptionMessage('"' . AbstractClass::class . '" is not instantiable because it is abstract.');
$hydrator->create(AbstractClass::class);
}

Expand All @@ -716,6 +717,7 @@ public function testCreateNonExistClass(): void
$hydrator = new Hydrator();

$this->expectException(NonExistClassException::class);
$this->expectExceptionMessage('Class "NonExistClass" not exist.');
$hydrator->create('NonExistClass');
}
}
26 changes: 26 additions & 0 deletions tests/ObjectFactory/ReflectionObjectFactoryTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace ObjectFactory;

use PHPUnit\Framework\TestCase;
use ReflectionClass;
use Yiisoft\Hydrator\Exception\WrongConstructorArgumentsCountException;
use Yiisoft\Hydrator\ObjectFactory\ReflectionObjectFactory;
use Yiisoft\Hydrator\Tests\Support\StringableObject;

final class ReflectionObjectFactoryTest extends TestCase
{
public function testWrongConstructorArgumentsCount(): void
{
$factory = new ReflectionObjectFactory();
$reflection = new ReflectionClass(StringableObject::class);

$this->expectException(WrongConstructorArgumentsCountException::class);
$this->expectExceptionMessage(
'Class "' . StringableObject::class . '" cannot be instantiated because it has 1 required parameters in constructor, but passed only 0.'
);
$factory->create($reflection, []);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Hydrator\Tests\Support\Attribute;

use LogicException;
use Yiisoft\Hydrator\Attribute\Parameter\ParameterAttributeInterface;
use Yiisoft\Hydrator\Attribute\Parameter\ParameterAttributeResolverInterface;
use Yiisoft\Hydrator\AttributeHandling\ParameterAttributeResolveContext;
use Yiisoft\Hydrator\Result;

final class ResolverWithConstructorWithoutParameters implements ParameterAttributeResolverInterface
{
public function __construct()
{
}

public function getParameterValue(
ParameterAttributeInterface $attribute,
ParameterAttributeResolveContext $context
): Result {
throw new LogicException('This method should not be called.');
}
}
13 changes: 13 additions & 0 deletions tests/Support/Classes/DiNonExists.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Hydrator\Tests\Support\Classes;

use Yiisoft\Hydrator\Attribute\Parameter\Di;

final class DiNonExists
{
#[Di('non-exists')]
public $engine;
}
10 changes: 10 additions & 0 deletions tests/Support/TestHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
use Closure;
use ReflectionFunction;
use ReflectionParameter;
use Yiisoft\Hydrator\Hydrator;
use Yiisoft\Hydrator\TypeCaster\TypeCastContext;

final class TestHelper
{
Expand All @@ -16,4 +18,12 @@ public static function getFirstParameter(Closure $closure): ReflectionParameter

return reset($parameters);
}

public static function createTypeCastContext(Closure $closure): TypeCastContext
{
return new TypeCastContext(
new Hydrator(),
self::getFirstParameter($closure),
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

declare(strict_types=1);

namespace TestEnvironments\Php81\TypeCaster;

use Closure;
use PHPUnit\Framework\TestCase;
use Yiisoft\Hydrator\Result;
use Yiisoft\Hydrator\Tests\Support\StringableObject;
use Yiisoft\Hydrator\Tests\Support\TestHelper;
use Yiisoft\Hydrator\TypeCaster\PhpNativeTypeCaster;

final class PhpNativeTypeCasterTest extends TestCase
{
public function dataBase(): array
{
return [
'int to object|int|string' => [
Result::success(42),
42,
static fn(StringableObject|int|string $a) => null,
],
'string to object|int|string' => [
Result::success('42'),
'42',
static fn(StringableObject|int|string $a) => null,
],
'string to object|int' => [
Result::success(42),
'42',
static fn(StringableObject|int $a) => null,
],
];
}

/**
* @dataProvider dataBase
*/
public function testBase(Result $expected, mixed $value, Closure $closure): void
{
$typeCaster = new PhpNativeTypeCaster();
$context = TestHelper::createTypeCastContext($closure);

$result = $typeCaster->cast($value, $context);

$this->assertSame($expected->isResolved(), $result->isResolved());
$this->assertSame($expected->getValue(), $result->getValue());
}
}

0 comments on commit 1b2c230

Please sign in to comment.