Browse Source

Merge pull request #12543 from sdustinh/integer-type-is-numeric

Check for `is_numeric()` instead of `is_scalar()` on IntegerType
Mark Story 7 years ago
parent
commit
118c03d712

+ 9 - 1
src/Database/Type/IntegerType.php

@@ -64,7 +64,7 @@ class IntegerType extends Type implements TypeInterface, BatchCastingInterface
             return null;
         }
 
-        if (!is_scalar($value)) {
+        if (!is_numeric($value)) {
             throw new InvalidArgumentException(sprintf(
                 'Cannot convert value of type `%s` to integer',
                 getTypeName($value)
@@ -101,6 +101,14 @@ class IntegerType extends Type implements TypeInterface, BatchCastingInterface
             if (!isset($values[$field])) {
                 continue;
             }
+
+            if (!is_numeric($values[$field])) {
+                throw new InvalidArgumentException(sprintf(
+                    'Cannot convert value of type `%s` to integer',
+                    getTypeName($values[$field])
+                ));
+            }
+
             $values[$field] = (int)$values[$field];
         }
 

+ 4 - 4
tests/TestCase/Database/ConnectionTest.php

@@ -468,7 +468,7 @@ class ConnectionTest extends TestCase
         $title = 'changed the title!';
         $body = new \DateTime('2012-01-01');
         $values = compact('title', 'body');
-        $this->connection->update('things', $values, ['id' => '1-string-parsed-as-int'], ['body' => 'date', 'id' => 'integer']);
+        $this->connection->update('things', $values, ['id' => '1'], ['body' => 'date', 'id' => 'integer']);
         $result = $this->connection->execute('SELECT * FROM things WHERE title = :title AND body = :body', $values, ['body' => 'date']);
         $this->assertCount(1, $result);
         $row = $result->fetch('assoc');
@@ -495,17 +495,17 @@ class ConnectionTest extends TestCase
      */
     public function testDeleteWithConditions()
     {
-        $this->connection->delete('things', ['id' => '1-rest-is-omitted'], ['id' => 'integer']);
+        $this->connection->delete('things', ['id' => '1'], ['id' => 'integer']);
         $result = $this->connection->execute('SELECT * FROM things');
         $this->assertCount(1, $result);
         $result->closeCursor();
 
-        $this->connection->delete('things', ['id' => '1-rest-is-omitted'], ['id' => 'integer']);
+        $this->connection->delete('things', ['id' => '1'], ['id' => 'integer']);
         $result = $this->connection->execute('SELECT * FROM things');
         $this->assertCount(1, $result);
         $result->closeCursor();
 
-        $this->connection->delete('things', ['id' => '2-rest-is-omitted'], ['id' => 'integer']);
+        $this->connection->delete('things', ['id' => '2'], ['id' => 'integer']);
         $result = $this->connection->execute('SELECT * FROM things');
         $this->assertCount(0, $result);
         $result->closeCursor();

+ 2 - 2
tests/TestCase/Database/QueryTest.php

@@ -723,7 +723,7 @@ class QueryTest extends TestCase
             ->from('comments')
             ->where(
                 [
-                    'id' => '3something-crazy',
+                    'id' => '3',
                     'created <' => new \DateTime('2013-01-01 12:00')
                 ],
                 ['created' => 'datetime', 'id' => 'integer']
@@ -739,7 +739,7 @@ class QueryTest extends TestCase
             ->from('comments')
             ->where(
                 [
-                    'id' => '1something-crazy',
+                    'id' => '1',
                     'created <' => new \DateTime('2013-01-01 12:00')
                 ],
                 ['created' => 'datetime', 'id' => 'integer']

+ 48 - 5
tests/TestCase/Database/Type/IntegerTypeTest.php

@@ -95,6 +95,36 @@ class IntegerTypeTest extends TestCase
     }
 
     /**
+     * Test to make sure the method throws an exception for invalid integer values.
+     *
+     * @return void
+     */
+    public function testInvalidManyToPHP()
+    {
+        $this->expectException(\InvalidArgumentException::class);
+        $values = [
+            'a' => null,
+            'b' => '2.3',
+            'c' => '15',
+            'd' => '0.0',
+            'e' => 10,
+            'f' => '6a88accf-a34e-4dd9-ade0-8d255ccaecbe'
+        ];
+        $expected = [
+            'a' => null,
+            'b' => 2,
+            'c' => 15,
+            'd' => 0,
+            'e' => 10,
+            'f' => '6a88accf-a34e-4dd9-ade0-8d255ccaecbe'
+        ];
+        $this->assertEquals(
+            $expected,
+            $this->type->manyToPHP($values, array_keys($values), $this->driver)
+        );
+    }
+
+    /**
      * Test converting to database format
      *
      * @return void
@@ -103,9 +133,6 @@ class IntegerTypeTest extends TestCase
     {
         $this->assertNull($this->type->toDatabase(null, $this->driver));
 
-        $result = $this->type->toDatabase('some data', $this->driver);
-        $this->assertSame(0, $result);
-
         $result = $this->type->toDatabase(2, $this->driver);
         $this->assertSame(2, $result);
 
@@ -114,14 +141,30 @@ class IntegerTypeTest extends TestCase
     }
 
     /**
+     * Invalid Integer Data Provider
+     *
+     * @return void
+     */
+    public function invalidIntegerProvider()
+    {
+        return [
+            'array' => [['3', '4']],
+            'non-numeric-string' => ['some-data'],
+            'uuid' => ['6a88accf-a34e-4dd9-ade0-8d255ccaecbe'],
+        ];
+    }
+
+    /**
      * Tests that passing an invalid value will throw an exception
      *
+     * @dataProvider invalidIntegerProvider
+     * @param  mixed $value Invalid value to test against the database type.
      * @return void
      */
-    public function testToDatabaseInvalid()
+    public function testToDatabaseInvalid($value)
     {
         $this->expectException(\InvalidArgumentException::class);
-        $this->type->toDatabase(['3', '4'], $this->driver);
+        $this->type->toDatabase($value, $this->driver);
     }
 
     /**