Skip to content

Commit

Permalink
ValueObjectBuilder added to create Value Object properly.
Browse files Browse the repository at this point in the history
  • Loading branch information
mkorkmaz committed Nov 28, 2018
1 parent ed23be2 commit d3c2b2d
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 0 deletions.
60 changes: 60 additions & 0 deletions src/ValueObjectBuilder.php
@@ -0,0 +1,60 @@
<?php
declare(strict_types=1);

namespace Selami\Entity;

use stdClass;
use Selami\Entity\Interfaces\ValueObjectInterface;
use Selami\Entity\Exception\CouldNotFindJSONSchemaFileException;
use Selami\Entity\Exception\InvalidMethodNameException;
use function in_array;

class ValueObjectBuilder
{
private $jsonSchema;
private $properties;
private $data;

private function __construct(string $jsonSchema)
{
$this->data = new stdClass();
$this->jsonSchema = $jsonSchema;
$this->properties = (new Model($jsonSchema))->getProperties();
}

public static function createFromJsonFile(string $jsonFilePath) : ValueObjectBuilder
{
if (!file_exists($jsonFilePath)) {
throw new CouldNotFindJSONSchemaFileException(
sprintf('Json Schema file(%s) does not exist!', $jsonFilePath)
);
}
return self::createFromJsonString(file_get_contents($jsonFilePath));
}
public static function createFromJsonString(string $jsonString) : ValueObjectBuilder
{
return new self($jsonString);
}

public function __call(string $name, array $values)
{
if (strpos($name, 'with') !== 0) {
throw new InvalidMethodNameException(
sprintf('Invalid method name (%s) to set a value to a property', $name)
);
}
$propertyName = lcfirst(str_replace('with', '', $name));
if (!in_array($propertyName, $this->properties, true)) {
throw new InvalidMethodNameException(
sprintf('Invalid property name (%s) for the defined schema!', $propertyName)
);
}
$this->data->{$propertyName} = $values[0];
return $this;
}

public function build() : ValueObjectInterface
{
return ValueObject::createFromJson($this->jsonSchema, $this->data);
}
}
34 changes: 34 additions & 0 deletions tests/resources/test-schema-credit-card-value-object.json
@@ -0,0 +1,34 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://api.example.com/profile.json#",
"type": "object",
"properties": {
"cardHolderName": {
"type": "string",
"minLength": 5,
"maxLength": 64
},
"expireDateMonth": {
"type": "integer",
"minimum": 1,
"maximum": 12
},
"expireDateYear": {
"type": "integer",
"minimum": 18,
"maximum": 30
},
"cvvNumber": {
"type": "string",
"pattern": "^[0-9]{3}$"
},
"cardNumber": {
"type": "string",
"minLength": 15,
"maxLength": 16,
"pattern": "^[0-9]{16}$"
}
},
"required": ["cardHolderName", "cardNumber", "expireDateMonth", "expireDateYear", "cvvNumber"],
"additionalProperties": false
}
80 changes: 80 additions & 0 deletions tests/unit/ValueObjectBuilderTest.php
@@ -0,0 +1,80 @@
<?php

use Selami\Entity\ValueObject;
use Selami\Entity\ValueObjectBuilder;
use Selami\Entity\Model;

class ValueObjectBuilderTest extends \Codeception\Test\Unit
{
/**
* @var \UnitTester
*/
protected $tester;

protected function _before()
{
}

protected function _after()
{
}

/**
* @test
*/
public function shouldReturnValueObjectSuccessfully() : void
{
$valueObject = ValueObjectBuilder::createFromJsonFile(
__DIR__.'/../resources/test-schema-credit-card-value-object.json'
)
->withCardNumber('5555555555555555')
->withCardHolderName('Kedibey')
->withExpireDateMonth(8)
->withExpireDateYear(24)
->withCvvNumber('937')
->build();

$this->assertEquals('Kedibey', $valueObject->cardHolderName);
}

/**
* @test
* @expectedException \Selami\Entity\Exception\InvalidMethodNameException
*/
public function shouldFailForInvalidMethodName() : void
{
ValueObjectBuilder::createFromJsonFile(
__DIR__.'/../resources/test-schema-credit-card-value-object.json'
)
->cardNumber('5555555555555555')
->withCardHolderName('Kedibey')
->withExpireDateMonth(8)
->withExpireDateYear(24)
->withCvvNumber('937')
->build();
}
/**
* @test
* @expectedException \Selami\Entity\Exception\InvalidMethodNameException
*/
public function shouldFailForInvalidPropertyName() : void
{
ValueObjectBuilder::createFromJsonFile(
__DIR__.'/../resources/test-schema-credit-card-value-object.json'
)
->withCardNumber('5555555555555555')
->withCardHoldersName('Kedibey')
->withExpireDateMonth(8)
->withExpireDateYear(24)
->withCvvNumber('937')
->build();
}
/**
* @test
* @expectedException \Selami\Entity\Exception\InvalidArgumentException
*/
public function shouldFailForAModelFileDoesNotExist() : void
{
ValueObjectBuilder::createFromJsonFile(__DIR__.'/../resources/test-schema-no-file.json');
}
}

0 comments on commit d3c2b2d

Please sign in to comment.