diff --git a/src/BuildableValidateParam.php b/src/BuildableValidateParam.php new file mode 100644 index 0000000..ce0622e --- /dev/null +++ b/src/BuildableValidateParam.php @@ -0,0 +1,35 @@ + $arguments + * @param array $properties + * @throws InvalidArgumentException + * @return void + */ + public function validateArguments(array $arguments, array $properties): void + { + $propertiesName = []; + \array_walk( + array: $properties, + callback: function (\ReflectionProperty $property) use (&$propertiesName) { + $propertiesName[$property->getName()] = $property->getName(); + }, + ); + $invalidArgs = \array_diff_key($arguments, $propertiesName); + if (0 !== \count($invalidArgs)) { + throw new InvalidArgumentException( + message: \sprintf( + 'Arguments %s dont match with call function', + \implode(separator: ',', array: $invalidArgs), + ), + ); + } + } +} diff --git a/src/BuildableWithArgUnpacking.php b/src/BuildableWithArgUnpacking.php index 990dfb9..2954149 100644 --- a/src/BuildableWithArgUnpacking.php +++ b/src/BuildableWithArgUnpacking.php @@ -4,10 +4,14 @@ namespace Buildotter\Core; +use ReflectionException; + trait BuildableWithArgUnpacking { + use BuildableValidateParam; /** * @param mixed ...$values + * @throws ReflectionException */ public function with(...$values): static { @@ -15,6 +19,11 @@ public function with(...$values): static $clone = $r->newInstanceWithoutConstructor(); + $this->validateArguments( + arguments: $values, + properties: $r->getProperties(), + ); + foreach ($r->getProperties() as $property) { $field = $property->name; $clone->$field = match (\array_key_exists($field, $values)) { diff --git a/src/BuildableWithArray.php b/src/BuildableWithArray.php index 3211ebc..a77cbda 100644 --- a/src/BuildableWithArray.php +++ b/src/BuildableWithArray.php @@ -6,6 +6,7 @@ trait BuildableWithArray { + use BuildableValidateParam; /** * @param array $values */ @@ -15,6 +16,11 @@ public function with(array $values): static $clone = $r->newInstanceWithoutConstructor(); + $this->validateArguments( + arguments: $values, + properties: $r->getProperties(), + ); + foreach ($r->getProperties() as $property) { $field = $property->name; $clone->$field = match (\array_key_exists($field, $values)) { diff --git a/tests/BuildatableTest.php b/tests/BuildatableTest.php index 0733d0f..10e5f35 100644 --- a/tests/BuildatableTest.php +++ b/tests/BuildatableTest.php @@ -7,7 +7,9 @@ use Buildotter\Core\BuildableWithArgUnpacking; use Buildotter\Core\BuildableWithArray; use Buildotter\Core\Buildatable; +use InvalidArgumentException; use PHPUnit\Framework\TestCase; +use ReflectionException; use function PHPUnit\Framework\assertEquals; final class BuildatableTest extends TestCase @@ -39,6 +41,35 @@ public function test_it_is_buildatable_with_arg_unpacking(): void $fooBuiltWithArgsUnpacking, ); } + + /** + * @throws ReflectionException + */ + public function test_it_is_not_buildatable_with_bad_arg_unpacking(): void + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Arguments test dont match with call function'); + FooBuilderWithArgUnpacking::new() + ->with(badargument: 'test', number: random()->randomNumber()) + ->build(); + FooBuilderWithArray::new() + ->with(['badargument' => 'test']) + ->build(); + } + + public function test_it_is_not_buildatable_with_bad_arg_array(): void + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Arguments test dont match with call function'); + FooBuilderWithArray::new() + ->with( + values: [ + 'badargument' => 'test', + 'number' => random()->randomNumber(), + ], + ) + ->build(); + } } final class Foo