Compare commits

...

24 Commits

Author SHA1 Message Date
Graham Campbell 834593d590 Fixed tests (#223) 2019-12-30 09:14:25 +01:00
Graham Campbell a6255605af Important compser.json fix (#220) 2019-12-20 13:49:39 +01:00
felipeAraujo 950d0663dc making the docs more precise in order to some lint tools don't give error (#216) 2019-09-15 22:23:48 +02:00
Nicolas Grekas 92dd169c32 Advertise return annotations from doctrine/lexer (#209) 2019-08-13 19:33:27 +02:00
Nicolas Grekas a6c8d7101b Fix PHP 7.4 support (#203)
Adding support for deprecated PHP behaviours.
2019-07-19 22:52:08 +02:00
Eduardo Gulias Davis 128cc721d7 fix(201) - empty domain 2019-06-23 12:14:27 +02:00
Viktor Szépe c26463ff92 Fix class name and parameter types (#200)
* Fix class name and paramtere types

* HHVM is not a thing anymore
2019-05-17 00:02:54 +02:00
Victor Bocharsky a09af2de87 Minor: Use SVG format for some bad looking badges in README (#197) 2019-05-07 22:08:52 +02:00
Victor Bocharsky c802f106b3 Simplify installation command in README (#198)
Composer will automatically use BC constraint, like `^2.1.7`
2019-05-07 22:08:00 +02:00
Joël Harkes 709f21f927 Update MultipleValidationWithAnd.php (#179)
* Update MultipleValidationWithAnd.php

Fix all validations actually get executed when mode is ALLOW_ALL_ERRORS (1)

* this should validate not breake out.

* Actually fix the unit tests

* add real invalid email test
2018-12-04 23:38:24 +01:00
Eduardo Gulias Davis e68c26e065 Update supported RFCs (#186)
solves #186
2018-12-03 11:33:36 +01:00
Andrey Bolonin 8036f2bd05 Update .travis.yml (#182) 2018-11-03 22:52:10 +01:00
nikitos569 0043eab0c5 Update README.md (#180) 2018-10-19 00:14:56 +02:00
SAMUEL NELA 0578b32b30 Added autoload-dev (#178) 2018-09-25 22:47:26 +02:00
Tom Sommer 54859fabea INTL_IDNA_VARIANT_UTS46 is not supported on all systems (#173)
* INTL_IDNA_VARIANT_UTS46 is not supported on all systems

Fall back to INTL_IDNA_VARIANT_2003 if INTL_IDNA_VARIANT_UTS46 is not found.

* Fix syntax error

* Update DNSCheckValidation.php
2018-08-16 22:49:45 +02:00
Tom Sommer 135444003f Correctly check for intl extension in SpoofCheck (#174) 2018-08-13 14:43:59 +02:00
Tom Sommer 9dde0df1e3 DNSCheckValidation requires the Intl extension (#175)
* DNSCheckValidation requires the Intl extension as well

* Check for Intl extension in DNSCheckValidation
2018-08-13 14:43:24 +02:00
Lode Claassen 8790f59415 DNS check should convert unicode domains first (#166)
* fix checkdnsrr not handling unicode domains properly

* fix for php7.2
2018-04-10 12:11:19 +02:00
masterwto 114b663f20 Update SpoofCheckValidation.php (#163)
removing spaces
2018-01-16 18:13:22 +01:00
Gabriel Caruso a0e0fadfce Use dedicated PHPUnit assertion methods (#159) 2018-01-05 23:47:59 +01:00
Robbert 74c0f07434 Clarification fix (#162)
You implement an interface.
2018-01-05 23:40:27 +01:00
Rotzbua ad1a0e9773 Update README.md (#157)
changed links from http to https if supported
2017-11-23 01:15:37 +01:00
Rotzbua aeb6851388 Update Other.md (#158)
change links from http to https if supported
2017-11-23 01:15:20 +01:00
Remi Collet a23fcc1315 Improve test requirements and add versions to test matrix
* allow phpunit 5.7 and 6

* add PHP 7.1 and 7.2 to travis
2017-11-17 00:41:28 +01:00
20 changed files with 196 additions and 1909 deletions
+21 -21
View File
@@ -1,33 +1,33 @@
sudo: false
language: php language: php
php:
- 5.5
- 5.6
- 7.0
- hhvm
env:
global:
- deps=no
matrix: matrix:
fast_finish: true
include: include:
- php: 5.5 - php: 5.5.9
dist: trusty
env: deps=low env: deps=low
- php: 5.5
dist: trusty
- php: 5.6 - php: 5.6
env: deps=high dist: xenial
- php: 7.0
dist: xenial
- php: 7.1
dist: bionic
- php: 7.2
dist: bionic
- php: 7.3
dist: bionic
- php: 7.4
dist: bionic
install: install:
- if [ "$deps" = "no" ]; then composer install; fi - if [ "$deps" = "low" ]; then composer update --prefer-lowest; else composer install; fi
- if [ "$deps" = "low" ]; then composer update --prefer-lowest; fi
- if [ "$deps" = "high" ]; then composer update; fi before_script:
- mkdir -p build/logs
script: script:
- mkdir -p build/logs - vendor/bin/phpunit --coverage-clover build/logs/clover.xml
- vendor/bin/phpunit --coverage-clover build/logs/clover.xml
after_script: after_script:
- php vendor/bin/coveralls - php vendor/bin/coveralls
+24 -4
View File
@@ -77,10 +77,25 @@ class EmailLexer extends AbstractLexer
protected $previous; protected $previous;
private static $nullToken = [
'value' => '',
'type' => null,
'position' => 0,
];
public function __construct()
{
$this->previous = $this->token = self::$nullToken;
}
/**
* @return void
*/
public function reset() public function reset()
{ {
$this->hasInvalidTokens = false; $this->hasInvalidTokens = false;
parent::reset(); parent::reset();
$this->previous = $this->token = self::$nullToken;
} }
public function hasInvalidTokens() public function hasInvalidTokens()
@@ -89,7 +104,7 @@ class EmailLexer extends AbstractLexer
} }
/** /**
* @param $type * @param string $type
* @throws \UnexpectedValueException * @throws \UnexpectedValueException
* @return boolean * @return boolean
*/ */
@@ -122,8 +137,10 @@ class EmailLexer extends AbstractLexer
public function moveNext() public function moveNext()
{ {
$this->previous = $this->token; $this->previous = $this->token;
$hasNext = parent::moveNext();
$this->token = $this->token ?: self::$nullToken;
return parent::moveNext(); return $hasNext;
} }
/** /**
@@ -189,7 +206,7 @@ class EmailLexer extends AbstractLexer
} }
/** /**
* @param $value * @param string $value
* @return bool * @return bool
*/ */
protected function isNullType($value) protected function isNullType($value)
@@ -202,7 +219,7 @@ class EmailLexer extends AbstractLexer
} }
/** /**
* @param $value * @param string $value
* @return bool * @return bool
*/ */
protected function isUTF8Invalid($value) protected function isUTF8Invalid($value)
@@ -214,6 +231,9 @@ class EmailLexer extends AbstractLexer
return false; return false;
} }
/**
* @return string
*/
protected function getModifiers() protected function getModifiers()
{ {
return 'iu'; return 'iu';
+1 -1
View File
@@ -33,7 +33,7 @@ class EmailParser
} }
/** /**
* @param $str * @param string $str
* @return array * @return array
*/ */
public function parse($str) public function parse($str)
+1 -1
View File
@@ -28,7 +28,7 @@ class EmailValidator
} }
/** /**
* @param $email * @param string $email
* @param EmailValidation $emailValidation * @param EmailValidation $emailValidation
* @return bool * @return bool
*/ */
+1 -1
View File
@@ -2,7 +2,7 @@
namespace Egulias\EmailValidator\Exception; namespace Egulias\EmailValidator\Exception;
class ExpectedQPair extends InvalidEmail class ExpectingQPair extends InvalidEmail
{ {
const CODE = 136; const CODE = 136;
const REASON = "Expecting QPAIR"; const REASON = "Expecting QPAIR";
-2
View File
@@ -2,8 +2,6 @@
namespace Egulias\EmailValidator\Exception; namespace Egulias\EmailValidator\Exception;
use Egulias\EmailValidator\Exception\InvalidEmail;
class NoDNSRecord extends InvalidEmail class NoDNSRecord extends InvalidEmail
{ {
const CODE = 5; const CODE = 5;
+34 -16
View File
@@ -41,21 +41,7 @@ class DomainPart extends Parser
{ {
$this->lexer->moveNext(); $this->lexer->moveNext();
if ($this->lexer->token['type'] === EmailLexer::S_DOT) { $this->performDomainStartChecks();
throw new DotAtStart();
}
if ($this->lexer->token['type'] === EmailLexer::S_EMPTY) {
throw new NoDomainPart();
}
if ($this->lexer->token['type'] === EmailLexer::S_HYPHEN) {
throw new DomainHyphened();
}
if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) {
$this->warnings[DeprecatedComment::CODE] = new DeprecatedComment();
$this->parseDomainComments();
}
$domain = $this->doParseDomainPart(); $domain = $this->doParseDomainPart();
@@ -77,6 +63,38 @@ class DomainPart extends Parser
$this->domainPart = $domain; $this->domainPart = $domain;
} }
private function performDomainStartChecks()
{
$this->checkInvalidTokensAfterAT();
$this->checkEmptyDomain();
if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) {
$this->warnings[DeprecatedComment::CODE] = new DeprecatedComment();
$this->parseDomainComments();
}
}
private function checkEmptyDomain()
{
$thereIsNoDomain = $this->lexer->token['type'] === EmailLexer::S_EMPTY ||
($this->lexer->token['type'] === EmailLexer::S_SP &&
!$this->lexer->isNextToken(EmailLexer::GENERIC));
if ($thereIsNoDomain) {
throw new NoDomainPart();
}
}
private function checkInvalidTokensAfterAT()
{
if ($this->lexer->token['type'] === EmailLexer::S_DOT) {
throw new DotAtStart();
}
if ($this->lexer->token['type'] === EmailLexer::S_HYPHEN) {
throw new DomainHyphened();
}
}
public function getDomainPart() public function getDomainPart()
{ {
return $this->domainPart; return $this->domainPart;
@@ -166,7 +184,7 @@ class DomainPart extends Parser
$domain .= $this->lexer->token['value']; $domain .= $this->lexer->token['value'];
$this->lexer->moveNext(); $this->lexer->moveNext();
} while ($this->lexer->token); } while (null !== $this->lexer->token['type']);
return $domain; return $domain;
} }
+3 -3
View File
@@ -21,8 +21,8 @@ class LocalPart extends Parser
$closingQuote = false; $closingQuote = false;
$openedParenthesis = 0; $openedParenthesis = 0;
while ($this->lexer->token['type'] !== EmailLexer::S_AT && $this->lexer->token) { while ($this->lexer->token['type'] !== EmailLexer::S_AT && null !== $this->lexer->token['type']) {
if ($this->lexer->token['type'] === EmailLexer::S_DOT && !$this->lexer->getPrevious()) { if ($this->lexer->token['type'] === EmailLexer::S_DOT && null === $this->lexer->getPrevious()['type']) {
throw new DotAtStart(); throw new DotAtStart();
} }
@@ -86,7 +86,7 @@ class LocalPart extends Parser
$this->lexer->moveNext(); $this->lexer->moveNext();
while ($this->lexer->token['type'] !== EmailLexer::S_DQUOTE && $this->lexer->token) { while ($this->lexer->token['type'] !== EmailLexer::S_DQUOTE && null !== $this->lexer->token['type']) {
$parseAgain = false; $parseAgain = false;
if (isset($special[$this->lexer->token['type']]) && $setSpecialsWarning) { if (isset($special[$this->lexer->token['type']]) && $setSpecialsWarning) {
$this->warnings[CFWSWithFWS::CODE] = new CFWSWithFWS(); $this->warnings[CFWSWithFWS::CODE] = new CFWSWithFWS();
+2 -2
View File
@@ -8,7 +8,7 @@ use Egulias\EmailValidator\Exception\ConsecutiveDot;
use Egulias\EmailValidator\Exception\CRLFAtTheEnd; use Egulias\EmailValidator\Exception\CRLFAtTheEnd;
use Egulias\EmailValidator\Exception\CRLFX2; use Egulias\EmailValidator\Exception\CRLFX2;
use Egulias\EmailValidator\Exception\CRNoLF; use Egulias\EmailValidator\Exception\CRNoLF;
use Egulias\EmailValidator\Exception\ExpectedQPair; use Egulias\EmailValidator\Exception\ExpectingQPair;
use Egulias\EmailValidator\Exception\ExpectingATEXT; use Egulias\EmailValidator\Exception\ExpectingATEXT;
use Egulias\EmailValidator\Exception\ExpectingCTEXT; use Egulias\EmailValidator\Exception\ExpectingCTEXT;
use Egulias\EmailValidator\Exception\UnclosedComment; use Egulias\EmailValidator\Exception\UnclosedComment;
@@ -50,7 +50,7 @@ abstract class Parser
{ {
if (!($this->lexer->token['type'] === EmailLexer::INVALID if (!($this->lexer->token['type'] === EmailLexer::INVALID
|| $this->lexer->token['type'] === EmailLexer::C_DEL)) { || $this->lexer->token['type'] === EmailLexer::C_DEL)) {
throw new ExpectedQPair(); throw new ExpectingQPair();
} }
$this->warnings[QuotedPart::CODE] = $this->warnings[QuotedPart::CODE] =
@@ -18,6 +18,13 @@ class DNSCheckValidation implements EmailValidation
* @var InvalidEmail * @var InvalidEmail
*/ */
private $error; private $error;
public function __construct()
{
if (!extension_loaded('intl')) {
throw new \LogicException(sprintf('The %s class requires the Intl extension.', __CLASS__));
}
}
public function isValid($email, EmailLexer $emailLexer) public function isValid($email, EmailLexer $emailLexer)
{ {
@@ -44,7 +51,11 @@ class DNSCheckValidation implements EmailValidation
protected function checkDNS($host) protected function checkDNS($host)
{ {
$host = rtrim($host, '.') . '.'; $variant = INTL_IDNA_VARIANT_2003;
if ( defined('INTL_IDNA_VARIANT_UTS46') ) {
$variant = INTL_IDNA_VARIANT_UTS46;
}
$host = rtrim(idn_to_ascii($host, IDNA_DEFAULT, $variant), '.') . '.';
$Aresult = true; $Aresult = true;
$MXresult = checkdnsrr($host, 'MX'); $MXresult = checkdnsrr($host, 'MX');
@@ -62,7 +62,8 @@ class MultipleValidationWithAnd implements EmailValidation
$errors = []; $errors = [];
foreach ($this->validations as $validation) { foreach ($this->validations as $validation) {
$emailLexer->reset(); $emailLexer->reset();
$result = $result && $validation->isValid($email, $emailLexer); $validationResult = $validation->isValid($email, $emailLexer);
$result = $result && $validationResult;
$this->warnings = array_merge($this->warnings, $validation->getWarnings()); $this->warnings = array_merge($this->warnings, $validation->getWarnings());
$errors = $this->addNewError($validation->getError(), $errors); $errors = $this->addNewError($validation->getError(), $errors);
@@ -93,7 +94,9 @@ class MultipleValidationWithAnd implements EmailValidation
} }
/** /**
* {@inheritdoc} * Returns the validation errors.
*
* @return MultipleErrors|null
*/ */
public function getError() public function getError()
{ {
@@ -13,10 +13,10 @@ class SpoofCheckValidation implements EmailValidation
* @var InvalidEmail * @var InvalidEmail
*/ */
private $error; private $error;
public function __construct() public function __construct()
{ {
if (!class_exists(Spoofchecker::class)) { if (!extension_loaded('intl')) {
throw new \LogicException(sprintf('The %s class requires the Intl extension.', __CLASS__)); throw new \LogicException(sprintf('The %s class requires the Intl extension.', __CLASS__));
} }
} }
+11 -8
View File
@@ -1,19 +1,22 @@
# EmailValidator # EmailValidator
[![Build Status](https://travis-ci.org/egulias/EmailValidator.png?branch=master)](https://travis-ci.org/egulias/EmailValidator) [![Coverage Status](https://coveralls.io/repos/egulias/EmailValidator/badge.png?branch=master)](https://coveralls.io/r/egulias/EmailValidator?branch=master) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/egulias/EmailValidator/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/egulias/EmailValidator/?branch=master) [![SensioLabsInsight](https://insight.sensiolabs.com/projects/22ba6692-9c02-42e5-a65d-1c5696bfffc6/small.png)](https://insight.sensiolabs.com/projects/22ba6692-9c02-42e5-a65d-1c5696bfffc6) [![Build Status](https://travis-ci.org/egulias/EmailValidator.svg?branch=master)](https://travis-ci.org/egulias/EmailValidator) [![Coverage Status](https://coveralls.io/repos/egulias/EmailValidator/badge.svg?branch=master)](https://coveralls.io/r/egulias/EmailValidator?branch=master) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/egulias/EmailValidator/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/egulias/EmailValidator/?branch=master) [![SensioLabsInsight](https://insight.sensiolabs.com/projects/22ba6692-9c02-42e5-a65d-1c5696bfffc6/small.png)](https://insight.sensiolabs.com/projects/22ba6692-9c02-42e5-a65d-1c5696bfffc6)
============================= =============================
With the help of [PHPStorm](https://www.jetbrains.com/phpstorm/) ## Suported RFCs ##
This library aims to support:
RFC 5321, 5322, 6530, 6531, 6532.
## Requirements ## ## Requirements ##
* [Composer](https://getcomposer.org) is required for installation * [Composer](https://getcomposer.org) is required for installation
* [Spoofchecking](https://github.com/egulias/EmailValidator/blob/master/EmailValidator/Validation/SpoofCheckValidation.php) validation requires that your PHP system have the [PHP Internationalization Libraries](http://php.net/manual/en/book.intl.php) (also known as PHP Intl) * [Spoofchecking](https://github.com/egulias/EmailValidator/blob/master/EmailValidator/Validation/SpoofCheckValidation.php) and [DNSCheckValidation](https://github.com/egulias/EmailValidator/blob/master/EmailValidator/Validation/DNSCheckValidation.php) validation requires that your PHP system has the [PHP Internationalization Libraries](https://php.net/manual/en/book.intl.php) (also known as PHP Intl)
## Installation ## ## Installation ##
Run the command below to install via Composer Run the command below to install via Composer
```shell ```shell
composer require egulias/email-validator "~2.1" composer require egulias/email-validator
``` ```
## Getting Started ## ## Getting Started ##
@@ -62,7 +65,7 @@ $validator->isValid("example@example.com", $multipleValidations); //true
### How to extend ### ### How to extend ###
It's easy! You just need to extend [EmailValidation](https://github.com/egulias/EmailValidator/blob/master/EmailValidator/Validation/EmailValidation.php) and you can use your own validation. It's easy! You just need to implement [EmailValidation](https://github.com/egulias/EmailValidator/blob/master/EmailValidator/Validation/EmailValidation.php) and you can use your own validation.
## Other Contributors ## ## Other Contributors ##
@@ -70,9 +73,9 @@ It's easy! You just need to extend [EmailValidation](https://github.com/egulias/
As this is a port from another library and work, here are other people related to the previous one: As this is a port from another library and work, here are other people related to the previous one:
* Ricard Clau [@ricardclau](http://github.com/ricardclau): Performance against PHP built-in filter_var * Ricard Clau [@ricardclau](https://github.com/ricardclau): Performance against PHP built-in filter_var
* Josepf Bielawski [@stloyd](http://github.com/stloyd): For its first re-work of Dominic's lib * Josepf Bielawski [@stloyd](https://github.com/stloyd): For its first re-work of Dominic's lib
* Dominic Sayers [@dominicsayers](http://github.com/dominicsayers): The original isemail function * Dominic Sayers [@dominicsayers](https://github.com/dominicsayers): The original isemail function
## License ## ## License ##
Released under the MIT License attached with this code. Released under the MIT License attached with this code.
@@ -24,6 +24,9 @@ class DNSCheckValidationTest extends TestCase
['"Abc@def"@example.com'], ['"Abc@def"@example.com'],
['"Fred\ Bloggs"@example.com'], ['"Fred\ Bloggs"@example.com'],
['"Joe.\\Blow"@example.com'], ['"Joe.\\Blow"@example.com'],
// unicide
['ñandu.cl'],
]; ];
} }
@@ -2,19 +2,23 @@
namespace Egulias\Tests\EmailValidator\Validation; namespace Egulias\Tests\EmailValidator\Validation;
use Egulias\EmailValidator\EmailLexer;
use Egulias\EmailValidator\EmailValidator;
use Egulias\EmailValidator\Exception\CommaInDomain; use Egulias\EmailValidator\Exception\CommaInDomain;
use Egulias\EmailValidator\Exception\NoDomainPart; use Egulias\EmailValidator\Exception\NoDomainPart;
use Egulias\EmailValidator\Validation\MultipleErrors; use Egulias\EmailValidator\Validation\MultipleErrors;
use Egulias\EmailValidator\Validation\MultipleValidationWithAnd; use Egulias\EmailValidator\Validation\MultipleValidationWithAnd;
use Egulias\EmailValidator\Validation\NoRFCWarningsValidation;
use Egulias\EmailValidator\Validation\RFCValidation;
use Egulias\EmailValidator\Warning\AddressLiteral; use Egulias\EmailValidator\Warning\AddressLiteral;
use Egulias\EmailValidator\Warning\DomainLiteral; use Egulias\EmailValidator\Warning\DomainLiteral;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
class MultipleValidationWitAndTest extends TestCase class MultipleValidationWithAndTest extends TestCase
{ {
public function testUsesAndLogicalOperation() public function testUsesAndLogicalOperation()
{ {
$lexer = $this->getMockBuilder("Egulias\\EmailValidator\\EmailLexer")->getMock(); $lexer = new EmailLexer();
$validationTrue = $this->getMockBuilder("Egulias\\EmailValidator\\Validation\\EmailValidation")->getMock(); $validationTrue = $this->getMockBuilder("Egulias\\EmailValidator\\Validation\\EmailValidation")->getMock();
$validationTrue->expects($this->any())->method("isValid")->willReturn(true); $validationTrue->expects($this->any())->method("isValid")->willReturn(true);
$validationTrue->expects($this->any())->method("getWarnings")->willReturn([]); $validationTrue->expects($this->any())->method("getWarnings")->willReturn([]);
@@ -35,7 +39,7 @@ class MultipleValidationWitAndTest extends TestCase
public function testValidationIsValid() public function testValidationIsValid()
{ {
$lexer = $this->getMockBuilder("Egulias\\EmailValidator\\EmailLexer")->getMock(); $lexer = new EmailLexer();
$validation = $this->getMockBuilder("Egulias\\EmailValidator\\Validation\\EmailValidation")->getMock(); $validation = $this->getMockBuilder("Egulias\\EmailValidator\\Validation\\EmailValidation")->getMock();
$validation->expects($this->any())->method("isValid")->willReturn(true); $validation->expects($this->any())->method("isValid")->willReturn(true);
@@ -56,7 +60,7 @@ class MultipleValidationWitAndTest extends TestCase
]; ];
$expectedResult = array_merge($warnings1, $warnings2); $expectedResult = array_merge($warnings1, $warnings2);
$lexer = $this->getMockBuilder("Egulias\\EmailValidator\\EmailLexer")->getMock(); $lexer = new EmailLexer();
$validation1 = $this->getMockBuilder("Egulias\\EmailValidator\\Validation\\EmailValidation")->getMock(); $validation1 = $this->getMockBuilder("Egulias\\EmailValidator\\Validation\\EmailValidation")->getMock();
$validation1->expects($this->any())->method("isValid")->willReturn(true); $validation1->expects($this->any())->method("isValid")->willReturn(true);
$validation1->expects($this->once())->method("getWarnings")->willReturn($warnings1); $validation1->expects($this->once())->method("getWarnings")->willReturn($warnings1);
@@ -78,19 +82,43 @@ class MultipleValidationWitAndTest extends TestCase
$expectedResult = new MultipleErrors([$error1, $error2]); $expectedResult = new MultipleErrors([$error1, $error2]);
$lexer = $this->getMockBuilder("Egulias\\EmailValidator\\EmailLexer")->getMock(); $lexer = new EmailLexer();
$validation1 = $this->getMockBuilder("Egulias\\EmailValidator\\Validation\\EmailValidation")->getMock(); $validation1 = $this->getMockBuilder("Egulias\\EmailValidator\\Validation\\EmailValidation")->getMock();
$validation1->expects($this->any())->method("isValid")->willReturn(true); $validation1->expects($this->once())->method("isValid")->willReturn(false);
$validation1->expects($this->once())->method("getWarnings")->willReturn([]);
$validation1->expects($this->once())->method("getError")->willReturn($error1);
$validation2 = $this->getMockBuilder("Egulias\\EmailValidator\\Validation\\EmailValidation")->getMock();
$validation2->expects($this->once())->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());
}
public function testStopsAfterFirstError()
{
$error1 = new CommaInDomain();
$error2 = new NoDomainPart();
$expectedResult = new MultipleErrors([$error1]);
$lexer = new EmailLexer();
$validation1 = $this->getMockBuilder("Egulias\\EmailValidator\\Validation\\EmailValidation")->getMock();
$validation1->expects($this->any())->method("isValid")->willReturn(false);
$validation1->expects($this->once())->method("getWarnings")->willReturn([]); $validation1->expects($this->once())->method("getWarnings")->willReturn([]);
$validation1->expects($this->once())->method("getError")->willReturn($error1); $validation1->expects($this->once())->method("getError")->willReturn($error1);
$validation2 = $this->getMockBuilder("Egulias\\EmailValidator\\Validation\\EmailValidation")->getMock(); $validation2 = $this->getMockBuilder("Egulias\\EmailValidator\\Validation\\EmailValidation")->getMock();
$validation2->expects($this->any())->method("isValid")->willReturn(false); $validation2->expects($this->any())->method("isValid")->willReturn(false);
$validation2->expects($this->once())->method("getWarnings")->willReturn([]); $validation2->expects($this->never())->method("getWarnings")->willReturn([]);
$validation2->expects($this->once())->method("getError")->willReturn($error2); $validation2->expects($this->never())->method("getError")->willReturn($error2);
$multipleValidation = new MultipleValidationWithAnd([$validation1, $validation2]); $multipleValidation = new MultipleValidationWithAnd([$validation1, $validation2], MultipleValidationWithAnd::STOP_ON_ERROR);
$multipleValidation->isValid("example@example.com", $lexer); $multipleValidation->isValid("example@example.com", $lexer);
$this->assertEquals($expectedResult, $multipleValidation->getError()); $this->assertEquals($expectedResult, $multipleValidation->getError());
} }
@@ -101,7 +129,7 @@ class MultipleValidationWitAndTest extends TestCase
$expectedResult = new MultipleErrors([$error]); $expectedResult = new MultipleErrors([$error]);
$lexer = $this->getMockBuilder("Egulias\\EmailValidator\\EmailLexer")->getMock(); $lexer = new EmailLexer();
$validation1 = $this->getMockBuilder("Egulias\\EmailValidator\\Validation\\EmailValidation")->getMock(); $validation1 = $this->getMockBuilder("Egulias\\EmailValidator\\Validation\\EmailValidation")->getMock();
$validation1->expects($this->any())->method("isValid")->willReturn(false); $validation1->expects($this->any())->method("isValid")->willReturn(false);
@@ -117,4 +145,16 @@ class MultipleValidationWitAndTest extends TestCase
$multipleValidation->isValid("example@example.com", $lexer); $multipleValidation->isValid("example@example.com", $lexer);
$this->assertEquals($expectedResult, $multipleValidation->getError()); $this->assertEquals($expectedResult, $multipleValidation->getError());
} }
public function testBreakoutOnInvalidEmail()
{
$lexer = new EmailLexer();
$validationNotCalled = $this->getMockBuilder("Egulias\\EmailValidator\\Validation\\EmailValidation")->getMock();
$validationNotCalled->expects($this->never())->method("isValid");
$validationNotCalled->expects($this->never())->method("getWarnings");
$validationNotCalled->expects($this->never())->method("getError");
$multipleValidation = new MultipleValidationWithAnd([new RFCValidation(), $validationNotCalled], MultipleValidationWithAnd::STOP_ON_ERROR);
$this->assertFalse($multipleValidation->isValid("invalid-email", $lexer));
}
} }
@@ -166,6 +166,7 @@ class RFCValidationTest extends TestCase
['test@email>'], ['test@email>'],
['test@email<'], ['test@email<'],
['test@email{'], ['test@email{'],
['test@ '],
]; ];
} }
@@ -220,13 +221,13 @@ class RFCValidationTest extends TestCase
{ {
$this->assertTrue($this->validator->isValid($email, $this->lexer)); $this->assertTrue($this->validator->isValid($email, $this->lexer));
$warnings = $this->validator->getWarnings(); $warnings = $this->validator->getWarnings();
$this->assertTrue( $this->assertCount(
count($warnings) === count($expectedWarnings), count($warnings), $expectedWarnings,
"Expected: " . implode(",", $expectedWarnings) . " and got " . implode(",", $warnings) "Expected: " . implode(",", $expectedWarnings) . " and got " . implode(",", $warnings)
); );
foreach ($warnings as $warning) { foreach ($warnings as $warning) {
$this->assertTrue(isset($expectedWarnings[$warning->code()])); $this->assertArrayHasKey($warning->code(), $expectedWarnings);
} }
} }
+11 -7
View File
@@ -2,7 +2,6 @@
"name": "egulias/email-validator", "name": "egulias/email-validator",
"description": "A library for validating emails against several RFCs", "description": "A library for validating emails against several RFCs",
"homepage": "https://github.com/egulias/EmailValidator", "homepage": "https://github.com/egulias/EmailValidator",
"type": "Library",
"keywords": ["email", "validation", "validator", "emailvalidation", "emailvalidator"], "keywords": ["email", "validation", "validator", "emailvalidation", "emailvalidator"],
"license": "MIT", "license": "MIT",
"authors": [ "authors": [
@@ -10,7 +9,7 @@
], ],
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "2.0.x-dev" "dev-master": "2.1.x-dev"
} }
}, },
"repositories": [ "repositories": [
@@ -19,14 +18,14 @@
"url": "https://github.com/dominicsayers/isemail" "url": "https://github.com/dominicsayers/isemail"
} }
], ],
"require": { "require": {
"php": ">= 5.5", "php": ">=5.5",
"doctrine/lexer": "^1.0.1" "doctrine/lexer": "^1.0.1"
}, },
"require-dev" : { "require-dev": {
"satooshi/php-coveralls": "^1.0.1", "satooshi/php-coveralls": "^1.0.1",
"phpunit/phpunit": "^4.8.35", "phpunit/phpunit": "^4.8.36|^7.5.15",
"dominicsayers/isemail": "dev-master" "dominicsayers/isemail": "^3.0.7"
}, },
"suggest": { "suggest": {
"ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation"
@@ -35,5 +34,10 @@
"psr-4": { "psr-4": {
"Egulias\\EmailValidator\\": "EmailValidator" "Egulias\\EmailValidator\\": "EmailValidator"
} }
},
"autoload-dev": {
"psr-4": {
"Egulias\\Tests\\": "test"
}
} }
} }
Generated
-1813
View File
File diff suppressed because it is too large Load Diff
+8 -8
View File
@@ -1,23 +1,23 @@
Email length Email length
------------ ------------
http://tools.ietf.org/html/rfc5321#section-4.1.2 https://tools.ietf.org/html/rfc5321#section-4.1.2
Forward-path = Path Forward-path = Path
Path = "<" [ A-d-l ":" ] Mailbox ">" Path = "<" [ A-d-l ":" ] Mailbox ">"
http://tools.ietf.org/html/rfc5321#section-4.5.3.1.3 https://tools.ietf.org/html/rfc5321#section-4.5.3.1.3
http://tools.ietf.org/html/rfc1035#section-2.3.4 https://tools.ietf.org/html/rfc1035#section-2.3.4
DNS DNS
--- ---
http://tools.ietf.org/html/rfc5321#section-2.3.5 https://tools.ietf.org/html/rfc5321#section-2.3.5
Names that can Names that can
be resolved to MX RRs or address (i.e., A or AAAA) RRs (as discussed be resolved to MX RRs or address (i.e., A or AAAA) RRs (as discussed
in Section 5) are permitted, as are CNAME RRs whose targets can be in Section 5) are permitted, as are CNAME RRs whose targets can be
resolved, in turn, to MX or address RRs. resolved, in turn, to MX or address RRs.
http://tools.ietf.org/html/rfc5321#section-5.1 https://tools.ietf.org/html/rfc5321#section-5.1
The lookup first attempts to locate an MX record associated with the The lookup first attempts to locate an MX record associated with the
name. If a CNAME record is found, the resulting name is processed as name. If a CNAME record is found, the resulting name is processed as
if it were the initial name. ... If an empty list of MXs is returned, if it were the initial name. ... If an empty list of MXs is returned,
@@ -37,7 +37,7 @@ status to these addresses on the basis that they are more likely
to be typos than genuine addresses (unless we've already to be typos than genuine addresses (unless we've already
established that the domain does have an MX record) established that the domain does have an MX record)
http://tools.ietf.org/html/rfc5321#section-2.3.5 https://tools.ietf.org/html/rfc5321#section-2.3.5
In the case In the case
of a top-level domain used by itself in an email address, a single of a top-level domain used by itself in an email address, a single
string is used without any dots. This makes the requirement, string is used without any dots. This makes the requirement,
@@ -57,7 +57,7 @@ an ambiguity. The most authoritative statement on TLD formats that
the author can find is in a (rejected!) erratum to RFC 1123 the author can find is in a (rejected!) erratum to RFC 1123
submitted by John Klensin, the author of RFC 5321: submitted by John Klensin, the author of RFC 5321:
http://www.rfc-editor.org/errata_search.php?rfc=1123&eid=1353 https://www.rfc-editor.org/errata_search.php?rfc=1123&eid=1353
However, a valid host name can never have the dotted-decimal However, a valid host name can never have the dotted-decimal
form #.#.#.#, since this change does not permit the highest-level form #.#.#.#, since this change does not permit the highest-level
component label to start with a digit even if it is not all-numeric. component label to start with a digit even if it is not all-numeric.
@@ -66,4 +66,4 @@ Comments
-------- --------
Comments at the start of the domain are deprecated in the text Comments at the start of the domain are deprecated in the text
Comments at the start of a subdomain are obs-domain Comments at the start of a subdomain are obs-domain
(http://tools.ietf.org/html/rfc5322#section-3.4.1) (https://tools.ietf.org/html/rfc5322#section-3.4.1)
+3 -4
View File
@@ -8,7 +8,6 @@
convertWarningsToExceptions="true" convertWarningsToExceptions="true"
processIsolation="false" processIsolation="false"
stopOnFailure="false" stopOnFailure="false"
syntaxCheck="false"
bootstrap="vendor/autoload.php" bootstrap="vendor/autoload.php"
> >
<testsuites> <testsuites>
@@ -19,8 +18,8 @@
</testsuites> </testsuites>
<filter> <filter>
<blacklist> <whitelist>
<directory>./vendor</directory> <directory>./EmailValidator/</directory>
</blacklist> </whitelist>
</filter> </filter>
</phpunit> </phpunit>