Skip to content

Commit

Permalink
Validator Class finished
Browse files Browse the repository at this point in the history
Some methos refactored, test extended
  • Loading branch information
mkorkmaz committed Jan 26, 2017
1 parent 1182bc6 commit 6f12a1f
Show file tree
Hide file tree
Showing 2 changed files with 229 additions and 65 deletions.
139 changes: 88 additions & 51 deletions src/Validator.php
Expand Up @@ -48,23 +48,6 @@ class Validator
'Uuid' => 'string'
];

/**
* @param string $itemKey
* @param array $properties
* @return bool
* @throws InvalidArgumentException
*/
private function checkType(string $itemKey, array $properties)
{
if (!array_key_exists('type', $properties)) {
throw new InvalidArgumentException(sprintf('%s must have "type" property.', $itemKey));
}
if (!array_key_exists(upperCamelCase($properties['type']), self::$constraints)) {
throw new InvalidArgumentException(sprintf('%s is not valid DataType.', $properties['type']));
}
return true;
}

/**
* @param string $itemKey
* @param mixed $item
Expand All @@ -85,52 +68,106 @@ public function assertDocItem(string $itemKey, $item, array $properties)
}
}

/**
* @param string $itemKey
* @param array $properties
* @return bool
* @throws InvalidArgumentException
*/
private function checkType(string $itemKey, array $properties)
{
if (!array_key_exists('type', $properties)) {
throw new InvalidArgumentException(sprintf('%s must have "type" property.', $itemKey));
}
if (!array_key_exists(upperCamelCase($properties['type']), self::$constraints)) {
throw new InvalidArgumentException(sprintf('%s is not valid DataType.', $properties['type']));
}
return true;
}

/**
* Validate given documents
*
* @param array $schema
* @param array $myDoc
* @param string $myKey
* @param array $myKey
* @return array
* @throws InvalidArgumentException
*/
public function assertDoc(array $schema, array $myDoc, string $myKey = null)
public function assertDoc(array $schema, array $myDoc, array $myKey = null)
{
$myKeys = array_keys($myDoc);
foreach ($myKeys as $key) {
$myDoc_key_type = getType($myDoc[$key]);
$vKey = $key;
if ($myKey !== null) {
$vKey = $myKey.'.'.$key;
}
// Does doc has an array key that does not exist in model definition.
if (!isset($schema[$key])) {
$message = sprintf('Error for key "%s" that does not exist in the model', $vKey);
throw new InvalidArgumentException($message);
} // Is the value of the array[key] again another array?
elseif ($myDoc_key_type === 'array') {
// Validate this array too.
$myDoc[$key] = $this->assertDoc($schema[$key], $myDoc[$key], $vKey);
if (getType($myDoc[$key]) !== 'array') {
return $myDoc[$key];
}
} // Is the value of the array[key] have same variable type
//that stated in the definition of the model array.
elseif ($myDoc_key_type !== self::$validTypes[upperCamelCase($schema[$key]['type'])]) {
$message = sprintf(
'Error for key "%s", %s given but it must be %s',
$vKey,
$myDoc_key_type,
self::$validTypes[upperCamelCase($schema[$key]['type'])]
);
throw new InvalidArgumentException($message);
} else {
$assertedItem = $this->assertDocItem($vKey, $myDoc[$key], $schema[$key]);
if($assertedItem !== true) {
throw new InvalidArgumentException($assertedItem);
}
}
$myDoc[$key] = $this->assertItem($schema, $myDoc, $key, $myKey);
}
return $myDoc;
}

/**
* @param array $schema
* @param array $myDoc
* @param string $key
* @param array $myKey
* @return array|bool|string
* @throws InvalidArgumentException;
*/
private function assertItem(array $schema, array $myDoc, string $key, array $myKey = null)
{
$vKey = is_array($myKey) ? $myKey + [$key] : [$key];
$tmp = $this->isMulti($schema, $myDoc[$key], $key, $vKey);
if ($tmp !== false && is_array($tmp)) {
return $tmp;
}
$this->doesSchemaHasKey($schema, $key, $vKey);

$myDocKeyType = getType($myDoc[$key]);
$this->checkValueType($myDocKeyType, $schema[$key], $vKey);

$assertedItem = $this->assertDocItem($key, $myDoc[$key], $schema[$key]);
if ($assertedItem !== true) {
throw new InvalidArgumentException($assertedItem);
}
return $myDoc[$key];
}

private function isMulti(array $schema, $myDoc, $key, array $vKey)
{
if (array_key_exists($key, $schema) && is_array($schema[$key]) && array_key_exists('_many', $schema[$key])) {
$newDoc = [];
foreach ($myDoc as $mKey => $item) {
$tmpvKey = $vKey + [$mKey];
$newDoc[] = $this->assertDoc($schema[$key]['_many'], $item, $tmpvKey);
}
return $newDoc;
}
return false;
}

private function doesSchemaHasKey(array $schema, $key, $vKey)
{
// Does doc has an array key that does not exist in model definition.
if (!isset($schema[$key])) {
$message = sprintf('Error for key "%s" that does not exist in the model', implode('.', $vKey));
throw new InvalidArgumentException($message);
}
}

// Is the value of the array[key] have same variable type
//that stated in the definition of the model array.
private function checkValueType($myDocKeyType, $schemaKey, $vKey)
{
if (
is_array($schemaKey)
&& array_key_exists('type', $schemaKey)
&& $myDocKeyType !== self::$validTypes[upperCamelCase($schemaKey['type'])]
) {
$message = sprintf(
'Error for key "%s": %s value given but it must have been %s',
implode('.', $vKey),
$myDocKeyType,
self::$validTypes[upperCamelCase($schemaKey['type'])]
);
throw new InvalidArgumentException($message);
}
}
}
155 changes: 141 additions & 14 deletions tests/ValidatorClassTest.php
Expand Up @@ -10,7 +10,7 @@

class MyValidatorClass extends TestCase
{
public $validSchema = [
public $validSchema1 = [
'id' => [
'type' => 'integer'
],
Expand All @@ -22,13 +22,66 @@ class MyValidatorClass extends TestCase
'values' => ['0', '1']
]
];
public $validSchema2 = [
'id' => [
'type' => 'integer'
],
'email' => [
'type' => 'email'
],
'is_active' => [
'type' => 'enum',
'values' => ['0', '1']
],
'children' => [
'_many' => [
'name' => ['type' => 'text'],
'education' => [
'_many' => [
'school' => ['type' => 'text'],
'city' => ['type' => 'text'],
'year' => ['type' => 'integer']
]
]
]
]
];

public $validData = [
public $validData1 = [
'id' => 1,
'email' => 'mehmet@github.com',
'email' => 'selami@github.com',
'is_active' => '1'
];

public $validData2 = [
'id' => 1,
'email' => 'selami@github.com',
'is_active' => '1',
'children' => [
[
'name' => 'Jon',
'education' => [
[
'school' => 'Yıldırım Beyazıt',
'city' => 'Bursa',
'year' => 1996
]
]
],
[
'name' => 'Jane',
'education' => [
[
'school' => 'Ankara University',
'city' => 'Ankara',
'year' => 2003

]
]
]
]
];


/**
* @test
Expand Down Expand Up @@ -77,7 +130,7 @@ public function shouldTReturnTrueForCheckType()
public function shouldAssertTrueForAssertDocItem()
{
$constraint = new Validator();
$assert = $constraint->assertDocItem('key', 'mehmet@github.com', ['type' => 'email']);
$assert = $constraint->assertDocItem('key', 'selami@github.com', ['type' => 'email']);
$this->assertTrue($assert);
}

Expand All @@ -87,7 +140,7 @@ public function shouldAssertTrueForAssertDocItem()
public function shouldReturnErrorForAssertDocItem()
{
$constraint = new Validator();
$assert = $constraint->assertDocItem('key', 'mehme@t@github.com', ['type' => 'email']);
$assert = $constraint->assertDocItem('key', 'selami@t@github.com', ['type' => 'email']);
$this->assertContains('INVALID_MAIL_ADDRESS_FORMAT', $assert);
}

Expand All @@ -97,15 +150,47 @@ public function shouldReturnErrorForAssertDocItem()
public function shouldAssertTrueForAssertDoc()
{
$constraint = new Validator();
$assert = $constraint->assertDoc($this->validSchema, $this->validData);
$this->assertArrayHasKey('id',$assert);
$this->assertArrayHasKey('email',$assert);
$this->assertArrayHasKey('is_active',$assert);
$assert = $constraint->assertDoc($this->validSchema1, $this->validData1);
$this->assertArrayHasKey('id', $assert);
$this->assertArrayHasKey('email', $assert);
$this->assertArrayHasKey('is_active', $assert);
$this->assertSame(1, $assert['id']);
$this->assertSame('mehmet@github.com', $assert['email']);
$this->assertSame('selami@github.com', $assert['email']);
$this->assertSame('1', $assert['is_active']);
}

/**
* @test
*/
public function shouldAssertTrueForNestedAssertDoc()
{
$constraint = new Validator();
$assert = $constraint->assertDoc($this->validSchema2, $this->validData2);

$this->assertArrayHasKey('id', $assert);
$this->assertArrayHasKey('email', $assert);
$this->assertArrayHasKey('is_active', $assert);
$this->assertSame(1, $assert['id']);
$this->assertSame('selami@github.com', $assert['email']);
$this->assertSame('1', $assert['is_active']);
$this->assertArrayHasKey(0, $assert['children']);
$this->assertArrayHasKey('name', $assert['children'][0]);
$this->assertSame('Jon', $assert['children'][0]['name']);

$this->assertArrayHasKey(1, $assert['children']);
$this->assertArrayHasKey('name', $assert['children'][1]);
$this->assertSame('Jane', $assert['children'][1]['name']);

$this->assertArrayHasKey('education', $assert['children'][0]);
$this->assertArrayHasKey('school', $assert['children'][0]['education'][0]);
$this->assertArrayHasKey('city', $assert['children'][0]['education'][0]);
$this->assertArrayHasKey('year', $assert['children'][0]['education'][0]);
$this->assertSame('Yıldırım Beyazıt', $assert['children'][0]['education'][0]['school']);
$this->assertSame('Bursa', $assert['children'][0]['education'][0]['city']);
$this->assertSame(1996, $assert['children'][0]['education'][0]['year']);
}


/**
* @test
* @dataProvider invalidDataProvider
Expand All @@ -115,15 +200,57 @@ public function shouldAssertTrueForAssertDoc()
public function shouldThrowExceptionForAssertDoc($invalidData)
{
$constraint = new Validator();
$constraint->assertDoc($this->validSchema, $invalidData);
$constraint->assertDoc($this->validSchema1, $invalidData);
}

public function invalidDataProvider()
{
return [
return [
[
['id' => 2, 'non_existing_field' => 'some_text']
['id' => 2, 'non_existing_field' => 'some_text'],
['id' => 2, 'email' => 'selami@github.com', 'is_active' => 1]
]
];
];
}

/**
* @test
* @dataProvider invalidSchemaProvider
* @param array $invalidSchema
* @expectedException InvalidArgumentException
*/
public function shouldThrowExceptionForAssertDocForInvalidSchema($invalidSchema)
{
$constraint = new Validator();
$constraint->assertDoc($invalidSchema, $this->validData1);
}

public function invalidSchemaProvider()
{
return [
[
'id' => [
'type' => 'integer'
],
'email' => [
'type' => 'email'
],
'is_active' => [
'type' => 'non_existed_data_type',
'values' => ['0', '1']
]
],
[
'id' => [
'type' => 'integer'
],
'email' => [
'type' => 'email'
],
'is_active' => [
'values' => ['0', '1']
]
]
];
}
}

0 comments on commit 6f12a1f

Please sign in to comment.