Repository: spiral/framework (php)

Issue:
Possible bug during Container resolving arguments
Hi,

Looking at the source code i think i found a bug. 
In the container during the argument resolving, there is an "assertType()" function used on the scalar (https://github.com/spiral/framework/blob/master/src/Core/src/Container.php#L451) when the value is null there is a check on the reflection parameter isOptional and getDefaultvalue === null, but this will not work if the typehint is "?string" the exception will be thrown to indicate null is not a correct value for this parameter.
I think you should use $parameter->allowsNull() to simplify the code and avoid this bug.

Hope this is clear and could help the projet.


Pull request description:
Fix container: wrong nullable parameter type assertion
| Q             | A
| ------------- | ---
| Bugfix?       | ✔️
| Breaks BC?    | ❌
| New feature?  | ❌
| Issues        |  fix #448


Patch:
diff --git a/src/Core/src/Container.php b/src/Core/src/Container.php
index 29ec47793..39a753a30 100644
--- a/src/Core/src/Container.php
+++ b/src/Core/src/Container.php
@@ -474,10 +474,7 @@ final class Container implements
     private function assertType(\ReflectionParameter $parameter, ContextFunction $context, $value): void
     {
         if ($value === null) {
-            if (
-                !$parameter->isOptional() &&
-                !($parameter->isDefaultValueAvailable() && $parameter->getDefaultValue() === null)
-            ) {
+            if (!$parameter->allowsNull()) {
                 throw new ArgumentException($parameter, $context);
             }
 


Test patch:
diff --git a/src/Core/tests/AutowireTest.php b/src/Core/tests/AutowireTest.php
index 8e410bc07..351caa6fc 100644
--- a/src/Core/tests/AutowireTest.php
+++ b/src/Core/tests/AutowireTest.php
@@ -229,6 +229,20 @@ class AutowireTest extends TestCase
         $this->assertInstanceOf(TypedClass::class, $object);
     }
 
+    public function testCallMethodWithNullValueOnNullableScalar(): void
+    {
+        $container = new Container();
+
+        $result = $container->invoke(
+            [SampleClass::class, 'nullableScalar'],
+            [
+                'nullable' => null,
+            ]
+        );
+
+        $this->assertNull($result);
+    }
+
     public function testAutowireTypecastingAndValidatingWrongInt(): void
     {
         $expected = "Unable to resolve 'int' argument in 'Spiral\Tests\Core\Fixtures\TypedClass::__construct'";
diff --git a/src/Core/tests/Fixtures/SampleClass.php b/src/Core/tests/Fixtures/SampleClass.php
index 1df870bed..dc23fd168 100644
--- a/src/Core/tests/Fixtures/SampleClass.php
+++ b/src/Core/tests/Fixtures/SampleClass.php
@@ -13,4 +13,8 @@ namespace Spiral\Tests\Core\Fixtures;
 
 class SampleClass
 {
+    public function nullableScalar(?string $nullable): ?string
+    {
+        return $nullable;
+    }
 }
diff --git a/src/Storage/tests/FileTestCase.php b/src/Storage/tests/FileTestCase.php
index 66a2a3c72..0a6032862 100644
--- a/src/Storage/tests/FileTestCase.php
+++ b/src/Storage/tests/FileTestCase.php
@@ -216,7 +216,7 @@ class FileTestCase extends TestCase
      */
     public function testLastModified(): void
     {
-        $now = \time();
+        $now = (int) \floor(\microtime(true));
 
         $file = $this->local->file('file.txt')
             ->create()