Skip to content

Commit

Permalink
RFCValidation strategy, multiple validation (#96)
Browse files Browse the repository at this point in the history
closes #62
  • Loading branch information
egulias committed Apr 30, 2016
1 parent 0f768c9 commit ed861e1
Show file tree
Hide file tree
Showing 7 changed files with 209 additions and 31 deletions.
@@ -0,0 +1,13 @@
<?php

namespace Egulias\EmailValidator\Validation\Exception;

use Exception;

class EmptyValidationList extends \InvalidArgumentException
{
public function __construct($code = 0, Exception $previous = null)
{
parent::__construct("Empty validation list is not allowed", $code, $previous);
}
}
26 changes: 26 additions & 0 deletions src/Egulias/EmailValidator/Validation/MultipleErrors.php
@@ -0,0 +1,26 @@
<?php

namespace Egulias\EmailValidator\Validation;

use Egulias\EmailValidator\Exception\InvalidEmail;

class MultipleErrors extends InvalidEmail
{
const CODE = 999;
const REASON = "Accumulated errors for multiple validations";
/**
* @var array
*/
private $errors = [];

public function __construct(array $errors)
{
$this->errors = $errors;
parent::__construct();
}

public function getErrors()
{
return $this->errors;
}
}
@@ -0,0 +1,46 @@
<?php

namespace Egulias\EmailValidator\Validation;

use Egulias\EmailValidator\EmailLexer;
use Egulias\EmailValidator\Validation\Exception\EmptyValidationList;

class MultipleValidationWithAnd implements EmailValidation
{
private $validations = [];
private $warnings = [];
private $error;

public function __construct(array $validations)
{
if (count($validations) == 0) {
throw new EmptyValidationList();
}

$this->validations = $validations;
}

public function isValid($email, EmailLexer $emailLexer)
{
$result = true;
$errors = [];
foreach ($this->validations as $validation) {
$result = $result && $validation->isValid($email, $emailLexer);
$this->warnings = array_merge($this->warnings, $validation->getWarnings());
$errors[] = $validation->getError();
}
$this->error = new MultipleErrors($errors);

return $result;
}

public function getError()
{
return $this->error;
}

public function getWarnings()
{
return $this->warnings;
}
}
2 changes: 1 addition & 1 deletion src/Egulias/EmailValidator/Validation/RFCValidation.php
Expand Up @@ -9,7 +9,7 @@
class RFCValidation implements EmailValidation
{
private $parser;
private $warnings;
private $warnings = [];
private $error;

public function isValid($email, EmailLexer $emailLexer)
Expand Down
15 changes: 14 additions & 1 deletion tests/egulias/Tests/EmailValidator/EmailValidatorTest.php
Expand Up @@ -3,6 +3,7 @@
namespace Egulias\Tests\EmailValidator;

use Egulias\EmailValidator\EmailValidator;
use Egulias\EmailValidator\Validation\MultipleValidationWithAnd;

class EmailValidatorTest extends \PHPUnit_Framework_TestCase
{
Expand All @@ -12,8 +13,20 @@ public function testValidationIsUsed()
$validation = $this->getMock("Egulias\\EmailValidator\\Validation\\EmailValidation");
$validation->expects($this->once())->method("isValid")->willReturn(true);
$validation->expects($this->once())->method("getWarnings")->willReturn([]);
$validation->expects($this->once())->method("getError")->willReturn(new \InvalidArgumentException());
$validation->expects($this->once())->method("getError")->willReturn(null);

$this->assertTrue($validator->isValid("example@example.com", $validation));
}

public function testMultipleValidation()
{
$validator = new EmailValidator();
$validation = $this->getMock("Egulias\\EmailValidator\\Validation\\EmailValidation");
$validation->expects($this->once())->method("isValid")->willReturn(true);
$validation->expects($this->once())->method("getWarnings")->willReturn([]);
$validation->expects($this->once())->method("getError")->willReturn(null);
$multiple = new MultipleValidationWithAnd([$validation]);

$this->assertTrue($validator->isValid("example@example.com", $multiple));
}
}
@@ -0,0 +1,82 @@
<?php

namespace Egulias\Tests\EmailValidator\Validation;

use Egulias\EmailValidator\Exception\CommaInDomain;
use Egulias\EmailValidator\Exception\NoDomainPart;
use Egulias\EmailValidator\Validation\MultipleErrors;
use Egulias\EmailValidator\Validation\MultipleValidationWithAnd;
use Egulias\EmailValidator\Warning\AddressLiteral;
use Egulias\EmailValidator\Warning\DomainLiteral;

class MultipleValidationWitAndTest extends \PHPUnit_Framework_TestCase
{
public function testUsesAndLogicalOperation()
{
$lexer = $this->getMock("Egulias\\EmailValidator\\EmailLexer");
$validationTrue = $this->getMock("Egulias\\EmailValidator\\Validation\\EmailValidation");
$validationTrue->expects($this->any())->method("isValid")->willReturn(true);
$validationTrue->expects($this->any())->method("getWarnings")->willReturn([]);
$validationFalse = $this->getMock("Egulias\\EmailValidator\\Validation\\EmailValidation");
$validationFalse->expects($this->any())->method("isValid")->willReturn(false);
$validationFalse->expects($this->any())->method("getWarnings")->willReturn([]);
$multipleValidation = new MultipleValidationWithAnd([$validationTrue, $validationFalse]);
$this->assertFalse($multipleValidation->isValid("exmpale@example.com", $lexer));
}

/**
* @expectedException Egulias\EmailValidator\Validation\Exception\EmptyValidationList
*/
public function testEmptyListIsNotAllowed()
{
new MultipleValidationWithAnd([]);
}

public function testAccumulatesWarnings()
{
$warnings1 = [
AddressLiteral::CODE => new AddressLiteral()
];
$warnings2 = [
DomainLiteral::CODE => new DomainLiteral()
];
$expectedResult = array_merge($warnings1, $warnings2);

$lexer = $this->getMock("Egulias\\EmailValidator\\EmailLexer");
$validation1 = $this->getMock("Egulias\\EmailValidator\\Validation\\EmailValidation");
$validation1->expects($this->any())->method("isValid")->willReturn(true);
$validation1->expects($this->once())->method("getWarnings")->willReturn($warnings1);

$validation2 = $this->getMock("Egulias\\EmailValidator\\Validation\\EmailValidation");
$validation2->expects($this->any())->method("isValid")->willReturn(false);
$validation2->expects($this->once())->method("getWarnings")->willReturn($warnings2);

$multipleValidation = new MultipleValidationWithAnd([$validation1, $validation2]);
$multipleValidation->isValid("example@example.com", $lexer);
$this->assertEquals($expectedResult, $multipleValidation->getWarnings());
}

public function testGathersAllTheErrors()
{
$error1 = new CommaInDomain();
$error2 = new NoDomainPart();

$expectedResult = new MultipleErrors([$error1, $error2]);

$lexer = $this->getMock("Egulias\\EmailValidator\\EmailLexer");

$validation1 = $this->getMock("Egulias\\EmailValidator\\Validation\\EmailValidation");
$validation1->expects($this->any())->method("isValid")->willReturn(true);
$validation1->expects($this->once())->method("getWarnings")->willReturn([]);
$validation1->expects($this->once())->method("getError")->willReturn($error1);

$validation2 = $this->getMock("Egulias\\EmailValidator\\Validation\\EmailValidation");
$validation2->expects($this->any())->method("isValid")->willReturn(false);
$validation2->expects($this->once())->method("getWarnings")->willReturn([]);
$validation2->expects($this->once())->method("getError")->willReturn($error2);

$multipleValidation = new MultipleValidationWithAnd([$validation1, $validation2]);
$multipleValidation->isValid("example@example.com", $lexer);
$this->assertEquals($expectedResult, $multipleValidation->getError());
}
}
@@ -1,6 +1,6 @@
<?php

namespace Egulias\EmailValidator\Tests;
namespace Egulias\Tests\EmailValidator\Validation;

use Egulias\EmailValidator\EmailLexer;
use Egulias\EmailValidator\Validation\RFCValidation;
Expand Down Expand Up @@ -33,8 +33,6 @@
use Egulias\EmailValidator\Warning\IPV6MaxGroups;
use Egulias\EmailValidator\Warning\LabelTooLong;
use Egulias\EmailValidator\Warning\LocalTooLong;
use Egulias\EmailValidator\Warning\NoDNSMXRecord;
use Egulias\EmailValidator\Warning\NoDNSRecord;
use Egulias\EmailValidator\Warning\ObsoleteDTEXT;
use Egulias\EmailValidator\Warning\QuotedString;

Expand Down Expand Up @@ -72,32 +70,32 @@ public function testValidEmails($email)
public function getValidEmails()
{
return array(
array('â@iana.org'),
array('fabien@symfony.com'),
array('example@example.co.uk'),
array('fabien_potencier@example.fr'),
array('example@localhost'),
array('fab\'ien@symfony.com'),
array('fab\ ien@symfony.com'),
array('example((example))@fakedfake.co.uk'),
array('example@faked(fake).co.uk'),
array('fabien+@symfony.com'),
array('инфо@письмо.рф'),
array('"username"@example.com'),
array('"user,name"@example.com'),
array('"user name"@example.com'),
array('"user@name"@example.com'),
array('"\a"@iana.org'),
array('"test\ test"@iana.org'),
array('""@iana.org'),
array('"\""@iana.org'),
array('müller@möller.de'),
array('test@email*'),
array('test@email!'),
array('test@email&'),
array('test@email^'),
array('test@email%'),
array('test@email$'),
['â@iana.org'],
['fabien@symfony.com'],
['example@example.co.uk'],
['fabien_potencier@example.fr'],
['example@localhost'],
['fab\'ien@symfony.com'],
['fab\ ien@symfony.com'],
['example((example))@fakedfake.co.uk'],
['example@faked(fake).co.uk'],
['fabien+@symfony.com'],
['инфо@письмо.рф'],
['"username"@example.com'],
['"user,name"@example.com'],
['"user name"@example.com'],
['"user@name"@example.com'],
['"\a"@iana.org'],
['"test\ test"@iana.org'],
['""@iana.org'],
['"\""@iana.org'],
['müller@möller.de'],
['test@email*'],
['test@email!'],
['test@email&'],
['test@email^'],
['test@email%'],
['test@email$'],
);
}

Expand Down

0 comments on commit ed861e1

Please sign in to comment.