Skip to content

Commit

Permalink
Merge pull request #353 from atk4/feature/line-end-normalize
Browse files Browse the repository at this point in the history
Feature/line end normalize
  • Loading branch information
romaninsh committed Oct 26, 2018
2 parents 5a1f779 + 350ac48 commit 42395e1
Show file tree
Hide file tree
Showing 2 changed files with 244 additions and 10 deletions.
29 changes: 21 additions & 8 deletions src/Field.php
Expand Up @@ -258,17 +258,27 @@ public function normalize($value)
return;
}

// validate scalar values
if (in_array($f->type, ['string', 'text', 'integer', 'money', 'float']) && !is_scalar($value)) {
throw new ValidationException([$this->name => 'Must use scalar value']);
}

// normalize
switch ($f->type) {
case null: // loose comparison, but is OK here
if ($this->required && empty($value)) {
throw new ValidationException([$this->name => 'Must not be empty']);
}
break;
case 'string':
case 'text':
if (!is_scalar($value)) {
throw new ValidationException([$this->name => 'Must be a string']);
// remove all line-ends and trim
$value = trim(str_replace(["\r", "\n"], '', $value));
if ($this->required && empty($value)) {
throw new ValidationException([$this->name => 'Must not be empty']);
}
break;
case 'text':
// normalize line-ends to LF and trim
$value = trim(str_replace(["\r\n", "\r"], "\n", $value));
if ($this->required && empty($value)) {
throw new ValidationException([$this->name => 'Must not be empty']);
Expand All @@ -288,7 +298,7 @@ public function normalize($value)
}
break;
case 'float':
$value = str_replace(',', '', $value);
$value = preg_replace('/[^0-9.-]/', '', $value);
if (!is_numeric($value)) {
throw new ValidationException([$this->name => 'Must be numeric']);
}
Expand All @@ -312,9 +322,9 @@ public function normalize($value)
break;
}
if (isset($f->enum) && is_array($f->enum)) {
if (isset($f->enum[0]) && $value === $f->enum[0]) {
if (isset($f->enum[0]) && strtolower($value) === strtolower($f->enum[0])) {
$value = false;
} elseif (isset($f->enum[1]) && $value === $f->enum[1]) {
} elseif (isset($f->enum[1]) && strtolower($value) === strtolower($f->enum[1])) {
$value = true;
}
} elseif (is_numeric($value)) {
Expand All @@ -330,7 +340,6 @@ public function normalize($value)
case 'date':
case 'datetime':
case 'time':

// we allow http://php.net/manual/en/datetime.formats.relative.php
$class = isset($f->dateTimeClass) ? $f->dateTimeClass : 'DateTime';

Expand All @@ -339,7 +348,11 @@ public function normalize($value)
} elseif (is_string($value)) {
$value = new $class($value);
} elseif (!$value instanceof $class) {
throw new Exception(['must be a '.$f->type, 'class' => $class, 'value class' => get_class($value)]);
if (is_object($value)) {
throw new ValidationException(['must be a '.$f->type, 'class' => $class, 'value class' => get_class($value)]);
}

throw new ValidationException(['must be a '.$f->type, 'class' => $class, 'value type' => gettype($value)]);
}
break;
case 'array':
Expand Down
225 changes: 223 additions & 2 deletions tests/FieldTest.php
Expand Up @@ -120,7 +120,7 @@ public function testRequired2()
/**
* @expectedException Exception
*/
public function testMandatory4()
public function testMandatory3()
{
$db = new Persistence_SQL($this->db->connection);
$a = [
Expand All @@ -136,7 +136,7 @@ public function testMandatory4()
$m->save(['name' => null]);
}

public function testMandatory3()
public function testMandatory4()
{
if ($this->driver == 'pgsql') {
$this->markTestIncomplete('This test is not supported on PostgreSQL');
Expand Down Expand Up @@ -527,4 +527,225 @@ public function testEncryptedField()
$m->unload()->load(1);
$this->assertEquals('i am a woman', $m['secret']);
}

public function testNormalize()
{
$m = new Model(['strict_types' => true]);

// Field types: 'string', 'text', 'integer', 'money', 'float', 'boolean',
// 'date', 'datetime', 'time', 'array', 'object'
$m->addField('string', ['type' => 'string']);
$m->addField('text', ['type' => 'text']);
$m->addField('integer', ['type' => 'integer']);
$m->addField('money', ['type' => 'money']);
$m->addField('float', ['type' => 'float']);
$m->addField('boolean', ['type' => 'boolean']);
$m->addField('boolean_enum', ['type' => 'boolean', 'enum'=>['N', 'Y']]);
$m->addField('date', ['type' => 'date']);
$m->addField('datetime', ['type' => 'datetime']);
$m->addField('time', ['type' => 'time']);
$m->addField('array', ['type' => 'array']);
$m->addField('object', ['type' => 'object']);

// string
$m['string'] = "Two\r\nLines ";
$this->assertSame('TwoLines', $m['string']);

$m['string'] = "Two\rLines ";
$this->assertSame('TwoLines', $m['string']);

$m['string'] = "Two\nLines ";
$this->assertSame('TwoLines', $m['string']);

// text
$m['text'] = "Two\r\nLines ";
$this->assertSame("Two\nLines", $m['text']);

$m['text'] = "Two\rLines ";
$this->assertSame("Two\nLines", $m['text']);

$m['text'] = "Two\nLines ";
$this->assertSame("Two\nLines", $m['text']);

// integer, money, float
$m['integer'] = '12,345.67676767'; // no digits after dot
$this->assertSame(12345, $m['integer']);

$m['money'] = '12,345.67676767'; // 4 digits after dot
$this->assertSame(12345.6768, $m['money']);

$m['float'] = '12,345.67676767'; // don't round
$this->assertSame(12345.67676767, $m['float']);

// boolean
$m['boolean'] = 0;
$this->assertSame(false, $m['boolean']);
$m['boolean'] = 1;
$this->assertSame(true, $m['boolean']);

$m['boolean_enum'] = 'N';
$this->assertSame(false, $m['boolean_enum']);
$m['boolean_enum'] = 'Y';
$this->assertSame(true, $m['boolean_enum']);

// date, datetime, time
$m['date'] = 123;
$this->assertInstanceof('DateTime', $m['date']);
$m['date'] = '123';
$this->assertInstanceof('DateTime', $m['date']);
$m['date'] = '2018-05-31';
$this->assertInstanceof('DateTime', $m['date']);
$m['datetime'] = 123;
$this->assertInstanceof('DateTime', $m['datetime']);
$m['datetime'] = '123';
$this->assertInstanceof('DateTime', $m['datetime']);
$m['datetime'] = '2018-05-31 12:13:14';
$this->assertInstanceof('DateTime', $m['datetime']);
$m['time'] = 123;
$this->assertInstanceof('DateTime', $m['time']);
$m['time'] = '123';
$this->assertInstanceof('DateTime', $m['time']);
$m['time'] = '12:13:14';
$this->assertInstanceof('DateTime', $m['time']);
}

/**
* @expectedException \atk4\data\ValidationException
*/
public function testNormalizeException1()
{
$m = new Model(['strict_types' => true]);
$m->addField('foo', ['type' => 'string']);
$m['foo'] = [];
}

/**
* @expectedException \atk4\data\ValidationException
*/
public function testNormalizeException2()
{
$m = new Model(['strict_types' => true]);
$m->addField('foo', ['type' => 'text']);
$m['foo'] = [];
}

/**
* @expectedException \atk4\data\ValidationException
*/
public function testNormalizeException3()
{
$m = new Model(['strict_types' => true]);
$m->addField('foo', ['type' => 'integer']);
$m['foo'] = [];
}

/**
* @expectedException \atk4\data\ValidationException
*/
public function testNormalizeException4()
{
$m = new Model(['strict_types' => true]);
$m->addField('foo', ['type' => 'money']);
$m['foo'] = [];
}

/**
* @expectedException \atk4\data\ValidationException
*/
public function testNormalizeException5()
{
$m = new Model(['strict_types' => true]);
$m->addField('foo', ['type' => 'float']);
$m['foo'] = [];
}

/**
* @expectedException \atk4\data\ValidationException
*/
public function testNormalizeException6()
{
$m = new Model(['strict_types' => true]);
$m->addField('foo', ['type' => 'date']);
$m['foo'] = [];
}

/**
* @expectedException \atk4\data\ValidationException
*/
public function testNormalizeException7()
{
$m = new Model(['strict_types' => true]);
$m->addField('foo', ['type' => 'datetime']);
$m['foo'] = [];
}

/**
* @expectedException \atk4\data\ValidationException
*/
public function testNormalizeException8()
{
$m = new Model(['strict_types' => true]);
$m->addField('foo', ['type' => 'time']);
$m['foo'] = [];
}

/**
* @expectedException \atk4\data\ValidationException
*/
public function testNormalizeException9()
{
$m = new Model(['strict_types' => true]);
$m->addField('foo', ['type' => 'integer']);
$m['foo'] = '123---456';
}

/**
* @expectedException \atk4\data\ValidationException
*/
public function testNormalizeException10()
{
$m = new Model(['strict_types' => true]);
$m->addField('foo', ['type' => 'money']);
$m['foo'] = '123---456';
}

/**
* @expectedException \atk4\data\ValidationException
*/
public function testNormalizeException11()
{
$m = new Model(['strict_types' => true]);
$m->addField('foo', ['type' => 'float']);
$m['foo'] = '123---456';
}

/**
* @expectedException \atk4\data\ValidationException
*/
public function testNormalizeException12()
{
$m = new Model(['strict_types' => true]);
$m->addField('foo', ['type' => 'array']);
$m['foo'] = 'ABC';
}

/**
* @expectedException \atk4\data\ValidationException
*/
public function testNormalizeException13()
{
$m = new Model(['strict_types' => true]);
$m->addField('foo', ['type' => 'object']);
$m['foo'] = 'ABC';
}

/**
* @expectedException \atk4\data\ValidationException
*/
public function testNormalizeException14()
{
$m = new Model(['strict_types' => true]);
$m->addField('foo', ['type' => 'boolean']);
$m['foo'] = 'ABC';
}
}

0 comments on commit 42395e1

Please sign in to comment.