Skip to content

Commit

Permalink
Updates from CR, and new tests for new functionality. Adding casting,…
Browse files Browse the repository at this point in the history
… default value check, fixing a potential bug. WIP.
  • Loading branch information
stratease committed May 3, 2024
1 parent 3c5ffab commit 3b1071b
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 10 deletions.
31 changes: 22 additions & 9 deletions src/Models/Model.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,19 @@ protected function getPropertyDefault( string $key ) {
: null;
}

/**
* Check if there is a default value for a property.
*
* @since TBD
*
* @param string $key Property name.
*
* @return bool
*/
public function hasDefault( string $key ): bool {
return is_array( $this->properties[ $key ] ) && array_key_exists( 1, $this->properties[ $key ] );
}

/**
* Returns the defaults for all the properties. If a default is omitted it defaults to null.
*
Expand All @@ -150,7 +163,10 @@ protected function getPropertyDefaults() : array {
$defaults = [];
foreach ( array_keys( $this->properties ) as $property ) {
// @todo This could be an edge case bug, we shouldn't assume `null` is always a valid default value.
$defaults[ $property ] = $this->getPropertyDefault( $property );
// @todo Sometimes `null` is a valid default, but sometimes we want to allow for the MySQL default to take precedence (which requires no value set).
if ( $this->hasDefault( $property ) ) {
$defaults[ $property ] = $this->getPropertyDefault( $property );
}
}

return $defaults;
Expand Down Expand Up @@ -336,7 +352,7 @@ public static function propertyKeys() : array {
* @param string $key The property name.
* @param mixed $value The value to be cast.
*
* @return array|bool|int|string The $value after being cast to it's type.
* @return mixed The $value after being cast to it's type.
*/
protected function castAttribute( string $key, $value ) {
// Handle nullable fields as expected.
Expand All @@ -347,19 +363,16 @@ protected function castAttribute( string $key, $value ) {
$type = $this->getPropertyType( $key );

switch ( $type ) {
case 'int':
return (int) $value;
case 'string':
return (string) $value;
case 'bool':
return (bool) $value;
case 'array':
return (array) $value;
// We want to convert "false" string to false.
return filter_var( $value, FILTER_VALIDATE_BOOLEAN );
case 'date':
return is_string( $value ) ? $value : $value->format( 'Y-m-d' );
case 'datetime':
return is_string( $value ) ? $value : $value->format( 'Y-m-d H:i:s' );
default:
settype( $value, $type );

return $value;
}
}
Expand Down
3 changes: 3 additions & 0 deletions tests/_support/Helper/MockModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,8 @@ class MockModel extends Model {
'firstName' => [ 'string', 'Michael' ],
'lastName' => 'string',
'emails' => [ 'array', [] ],
'isActive' => 'bool',
'createdDatetime' => 'datetime',
'createdDate' => 'date',
];
}
48 changes: 47 additions & 1 deletion tests/wpunit/ModelTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace StellarWP\Models;

use DateTime;
use StellarWP\Models\Tests\ModelsTestCase;
use StellarWP\Models\Tests\MockModel;
use StellarWP\Models\Tests\MockModelWithRelationship;
Expand Down Expand Up @@ -205,9 +206,33 @@ public function testIssetShouldReturnFalse() {
* @return void
*/
public function testModelShouldThrowExceptionForAssigningInvalidPropertyType( $key, $value ) {
$this->markTestSkipped('This test is not yet implemented.');
$this->expectException( Config::getInvalidArgumentException() );
// @todo Are we keeping? If we want to adjust, test that invalid properties types are cast appropriately.
$model = new MockModel( [ $key => $value ] );
}

/**
* @since TBD
*
* @dataProvider castPropertyProvider
*/
public function testModelShouldCastPropertyTypes( $key, $value, $expected){
$model = new MockModel( [ $key => $value ] );

new MockModel( [ $key => $value ] );
$this->assertEquals( $expected, $model->$key );
}

/**
* @since TBD
*
* @return void
*/
public function testHasDefaultValue() {
$model = new MockModel();
$this->assertTrue( $model->hasDefault( 'firstName' ) );
$this->assertTrue( $model->hasDefault( 'emails' ) );
$this->assertFalse( $model->hasDefault( 'lastName' ) );
}

/**
Expand Down Expand Up @@ -289,4 +314,25 @@ public function invalidTypeProvider() {
[ 'emails', 'Not an array' ],
];
}

/**
* @since TBD
*
* @return array
*/
public function castPropertyProvider() {
return [
[ 'id', '1', 1 ],
[ 'lastName', 1, '1' ],
[ 'isActive', 'false', false ],
[ 'isActive', 1, true ],
[ 'isActive', 0, false ],
[ 'isActive', false, false ],
[ 'emails', [], [] ],
[ 'createdDate', new DateTime( 'June 1st 2020' ), '2020-06-01' ],
[ 'createdDatetime', new DateTime( 'June 1st 2020 12:30am' ), '2020-06-01 00:30:00' ],
[ 'createdDate', '2020-06-01', '2020-06-01' ],
[ 'createdDatetime', '2020-06-01 00:30:00', '2020-06-01 00:30:00' ],
];
}
}

0 comments on commit 3b1071b

Please sign in to comment.