Skip to content

Commit

Permalink
Merge pull request #9 from m1x0n/feature/abstract-type
Browse files Browse the repository at this point in the history
Added AbstractTypeObject with possibility of its serizalization/deserizalization
  • Loading branch information
Barry O Sullivan authored Nov 9, 2017
2 parents 94919f2 + 3c019f0 commit 1b410c7
Show file tree
Hide file tree
Showing 7 changed files with 230 additions and 1 deletion.
3 changes: 3 additions & 0 deletions src/Deserializer/Deserializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ private function deserializer_repo_fetch($class)
if ($this->is_instance_of($class, Type\AbstractTypeEntity::class)) {
return $this->type_entity;
}
if ($this->is_instance_of($class, Type\AbstractTypeObject::class)) {
return $this->type_entity;
}
if ($this->is_instance_of($class, Type\AbstractSingleValue::class)) {
return $this->single_value;
}
Expand Down
3 changes: 2 additions & 1 deletion src/Deserializer/Deserializer/TypeEntity.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,11 @@ public function deserialize($class, $serialized)
private function make_parameter($parameter, $serialized, $variable_property, $variable_property_class)
{
$name = $parameter->getName();
$parameter_class = $parameter->getClass()->getName();

if ($name == $variable_property) {
$parameter_class = $variable_property_class;
} else {
$parameter_class = $parameter->getClass()->getName();
}

if (!property_exists($serialized, $name)) {
Expand Down
3 changes: 3 additions & 0 deletions src/Serializer/Serializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ private function serializer_repo_fetch($class, $object)
if ($this->is_instance_of($class, Type\AbstractTypeEntity::class)) {
return $this->composite;
}
if ($this->is_instance_of($class, Type\AbstractTypeObject::class)) {
return $this->composite;
}
if ($this->is_instance_of($class, Type\AbstractSingleValue::class)) {
return $this->single_value;
}
Expand Down
32 changes: 32 additions & 0 deletions src/ValueObject/SampleCompositeWithVariableType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace EventSourced\ValueObject\ValueObject;

use EventSourced\ValueObject\ValueObject\Type\AbstractTypeObject;
use Money\Money;

class SampleCompositeWithVariableType extends AbstractTypeObject
{
protected $type;
protected $value;

public function __construct(SampleType $type, $value)
{
$this->type = $type;
$this->value = $value;
}

protected static function accepts()
{
return [
'default' => Uuid::class,
'coordinates' => GPSCoordinates::class,
'money' => Money::class
];
}

public static function variable_property_key()
{
return 'value';
}
}
17 changes: 17 additions & 0 deletions src/ValueObject/SampleType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace EventSourced\ValueObject\ValueObject;

use EventSourced\ValueObject\ValueObject\Type\AbstractSingleValue;

class SampleType extends AbstractSingleValue
{
protected function validator()
{
return parent::validator()->in([
'default',
'coordinates',
'money'
]);
}
}
34 changes: 34 additions & 0 deletions src/ValueObject/Type/AbstractTypeObject.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace EventSourced\ValueObject\ValueObject\Type;

use EventSourced\ValueObject\Contracts\ValueObject;

abstract class AbstractTypeObject extends AbstractComposite
{
static protected function accepts()
{
throw new \Exception("No values accepted for this type, please override this function and return an array mapping the type value to the type class path");
}

public static function get_class_for_type_key($type_key)
{
return static::accepts()[$type_key];
}

public static function variable_property_key()
{
throw new \Exception("No variable property defined for this type, please override this function and return the name of the property that contains the variable valueobject.");
}

protected function assert_valid_type(AbstractSingleValue $type, ValueObject $value)
{
$type_key = $type->value();
if (!isset(static::accepts()[$type_key])) {
throw new \Exception("Unknown type '$type_key', unable to process.");
}
if (static::accepts()[$type_key] != get_class($value)) {
throw new \Exception("Invalid type '$type_key', for object '".get_class($value)."'");
}
}
}
139 changes: 139 additions & 0 deletions test/Deserializer/AbstractTypeObjectDeserializerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
<?php

namespace Test\Deserializer;

use EventSourced\ValueObject\Extensions\ExtensionRepository;
use EventSourced\ValueObject\Reflector\Reflector;
use EventSourced\ValueObject\Deserializer;
use EventSourced\ValueObject\Serializer\Serializer;
use EventSourced\ValueObject\ValueObject\Coordinate;
use EventSourced\ValueObject\ValueObject\GPSCoordinates;
use EventSourced\ValueObject\ValueObject\SampleCompositeWithVariableType;
use EventSourced\ValueObject\ValueObject\SampleType;
use EventSourced\ValueObject\ValueObject\Uuid;
use Money\Money;

class AbstractTypeObjectDeserializerTest extends \PHPUnit_Framework_TestCase
{
/**
* @var Serializer
*/
protected $serializer;

/**
* @var Deserializer\Deserializer
*/
protected $deserializer;

protected function setUp()
{
parent::setUp();

$reflector = new Reflector();
$extensions = new ExtensionRepository();
$this->serializer = new Serializer($reflector, $extensions);
$this->deserializer = new Deserializer\Deserializer($reflector, $extensions);
}

public function test_should_deserialize_sample_composite_with_variable_type()
{
$sample = [
'type' => 'default',
'value' => '95f2f496-38d4-4914-9632-9b1d803866ee'
];

$sample = $this->deserializer->deserialize(
SampleCompositeWithVariableType::class,
$sample
);

$this->assertInstanceOf(SampleCompositeWithVariableType::class, $sample);

$sample2 = [
'type' => 'coordinates',
'value' => [
'latitude' => 23,
'longitude' => 78
]
];

$sample2 = $this->deserializer->deserialize(
SampleCompositeWithVariableType::class,
$sample2
);

$this->assertInstanceOf(SampleCompositeWithVariableType::class, $sample2);
}

public function test_should_serializer_sample_composite_with_variable_type()
{
$sample = new SampleCompositeWithVariableType(
new SampleType('coordinates'),
new GPSCoordinates(new Coordinate(23), new Coordinate(78))
);

$expected = [
'type' => 'coordinates',
'value' => [
'latitude' => 23,
'longitude' => 78
]
];

$serialized = $this->serializer->serialize($sample);

$this->assertEquals($expected, $serialized);

$sample2 = new SampleCompositeWithVariableType(
new SampleType('coordinates'),
new Uuid('a71fdd68-ea34-4f3e-a2ea-72da87ceb262')
);

$expected2 = [
'type' => 'coordinates',
'value' => 'a71fdd68-ea34-4f3e-a2ea-72da87ceb262'
];

$serialized2 = $this->serializer->serialize($sample2);

$this->assertEquals($expected2, $serialized2);
}

public function test_should_deserialize_composite_with_variable_money_type()
{
$sample = [
'type' => 'money',
'value' => [
'amount' => 1000,
'currency' => 'EUR'
]
];

$sample = $this->deserializer->deserialize(
SampleCompositeWithVariableType::class,
$sample
);

$this->assertInstanceOf(SampleCompositeWithVariableType::class, $sample);
}

public function test_should_serialize_composite_with_variable_money_type()
{
$sample = new SampleCompositeWithVariableType(
new SampleType('money'),
Money::EUR(1000)
);

$expected = [
'type' => 'money',
'value' => [
'amount' => 1000,
'currency' => 'EUR'
]
];

$serialized = $this->serializer->serialize($sample);

$this->assertEquals($expected, $serialized);
}
}

0 comments on commit 1b410c7

Please sign in to comment.