Value Object should be immutable

This commit is contained in:
bkrukowski 2016-09-24 13:10:25 +02:00
parent 7d3895cfd4
commit e1eedfff75
8 changed files with 101 additions and 89 deletions

View File

@ -0,0 +1,63 @@
<?php
declare(strict_types=1);
namespace bkrukowski\TransparentEmail\Emails;
/**
* @internal
*/
class EditableEmail implements EmailInterface
{
use EmailTrait;
public function __construct(EmailInterface $email)
{
$this->localPart = $email->getLocalPart();
$this->domain = $email->getDomain();
}
public function removeFromLocalPart(string $toRemove) : EditableEmail
{
$copy = clone $this;
$copy->localPart = str_replace($toRemove, '', $this->localPart);
return $copy;
}
public function removeSuffixAlias(string $delimiter) : EditableEmail
{
$copy = clone $this;
$copy->localPart = explode($delimiter, $this->localPart, 2)[0];
return $copy;
}
public function setDomain(string $domain) : EditableEmail
{
$copy = clone $this;
$copy->domain = $domain;
return $copy;
}
public function setLocalPart(string $localPart) : EditableEmail
{
$copy = clone $this;
$copy->localPart = $localPart;
return $copy;
}
public function lowerCaseLocalPartIf(bool $condition) : EditableEmail
{
if ($condition) {
$copy = clone $this;
$copy->localPart = strtolower($this->localPart);
return $copy;
}
return $this;
}
}

View File

@ -1,56 +0,0 @@
<?php
declare(strict_types=1);
namespace bkrukowski\TransparentEmail\Emails;
/**
* @internal
*/
class MutableEmail implements EmailInterface
{
use EmailTrait;
public function __construct(EmailInterface $email)
{
$this->localPart = $email->getLocalPart();
$this->domain = $email->getDomain();
}
public function removeFromLocalPart(string $toRemove) : MutableEmail
{
$this->localPart = str_replace($toRemove, '', $this->localPart);
return $this;
}
public function removeSuffixAlias(string $delimiter) : MutableEmail
{
$this->localPart = explode($delimiter, $this->localPart, 2)[0];
return $this;
}
public function setDomain(string $domain) : MutableEmail
{
$this->domain = $domain;
return $this;
}
public function setLocalPart(string $localPart) : MutableEmail
{
$this->localPart = $localPart;
return $this;
}
public function lowerCaseLocalPartIf(bool $condition) : MutableEmail
{
if ($condition) {
$this->localPart = strtolower($this->localPart);
}
return $this;
}
}

View File

@ -4,14 +4,14 @@ declare(strict_types=1);
namespace bkrukowski\TransparentEmail\Services; namespace bkrukowski\TransparentEmail\Services;
use bkrukowski\TransparentEmail\Emails\MutableEmail; use bkrukowski\TransparentEmail\Emails\EditableEmail;
use bkrukowski\TransparentEmail\Emails\EmailInterface; use bkrukowski\TransparentEmail\Emails\EmailInterface;
class GmailCom implements ServiceInterface class GmailCom implements ServiceInterface
{ {
public function getPrimaryEmail(EmailInterface $email) : EmailInterface public function getPrimaryEmail(EmailInterface $email) : EmailInterface
{ {
return (new MutableEmail($email)) return (new EditableEmail($email))
->removeFromLocalPart('.') ->removeFromLocalPart('.')
->removeSuffixAlias('+') ->removeSuffixAlias('+')
->lowerCaseLocalPartIf(true) ->lowerCaseLocalPartIf(true)

View File

@ -4,14 +4,14 @@ declare(strict_types=1);
namespace bkrukowski\TransparentEmail\Services; namespace bkrukowski\TransparentEmail\Services;
use bkrukowski\TransparentEmail\Emails\MutableEmail; use bkrukowski\TransparentEmail\Emails\EditableEmail;
use bkrukowski\TransparentEmail\Emails\EmailInterface; use bkrukowski\TransparentEmail\Emails\EmailInterface;
abstract class MultiDomain implements ServiceInterface abstract class MultiDomain implements ServiceInterface
{ {
public function getPrimaryEmail(EmailInterface $email) : EmailInterface public function getPrimaryEmail(EmailInterface $email) : EmailInterface
{ {
return (new MutableEmail($email)) return (new EditableEmail($email))
->setDomain($this->getPrimaryDomain()) ->setDomain($this->getPrimaryDomain())
->lowerCaseLocalPartIf(!$this->isCaseSensitive()); ->lowerCaseLocalPartIf(!$this->isCaseSensitive());
} }

View File

@ -4,14 +4,14 @@ declare(strict_types=1);
namespace bkrukowski\TransparentEmail\Services; namespace bkrukowski\TransparentEmail\Services;
use bkrukowski\TransparentEmail\Emails\MutableEmail; use bkrukowski\TransparentEmail\Emails\EditableEmail;
use bkrukowski\TransparentEmail\Emails\EmailInterface; use bkrukowski\TransparentEmail\Emails\EmailInterface;
class OutlookCom implements ServiceInterface class OutlookCom implements ServiceInterface
{ {
public function getPrimaryEmail(EmailInterface $email) : EmailInterface public function getPrimaryEmail(EmailInterface $email) : EmailInterface
{ {
return (new MutableEmail($email)) return (new EditableEmail($email))
->removeSuffixAlias('+') ->removeSuffixAlias('+')
->lowerCaseLocalPartIf(true); ->lowerCaseLocalPartIf(true);
} }

View File

@ -4,14 +4,14 @@ declare(strict_types=1);
namespace bkrukowski\TransparentEmail\Services; namespace bkrukowski\TransparentEmail\Services;
use bkrukowski\TransparentEmail\Emails\MutableEmail; use bkrukowski\TransparentEmail\Emails\EditableEmail;
use bkrukowski\TransparentEmail\Emails\EmailInterface; use bkrukowski\TransparentEmail\Emails\EmailInterface;
class Www33MailCom implements ServiceInterface class Www33MailCom implements ServiceInterface
{ {
public function getPrimaryEmail(EmailInterface $email) : EmailInterface public function getPrimaryEmail(EmailInterface $email) : EmailInterface
{ {
return (new MutableEmail($email)) return (new EditableEmail($email))
->setLocalPart(preg_replace('/\\.33mail\\.com$/', '', $email->getDomain())); ->setLocalPart(preg_replace('/\\.33mail\\.com$/', '', $email->getDomain()));
} }

View File

@ -4,14 +4,14 @@ declare(strict_types=1);
namespace bkrukowski\TransparentEmail\Services; namespace bkrukowski\TransparentEmail\Services;
use bkrukowski\TransparentEmail\Emails\MutableEmail; use bkrukowski\TransparentEmail\Emails\EditableEmail;
use bkrukowski\TransparentEmail\Emails\EmailInterface; use bkrukowski\TransparentEmail\Emails\EmailInterface;
class YahooCom implements ServiceInterface class YahooCom implements ServiceInterface
{ {
public function getPrimaryEmail(EmailInterface $email) : EmailInterface public function getPrimaryEmail(EmailInterface $email) : EmailInterface
{ {
return (new MutableEmail($email)) return (new EditableEmail($email))
->removeSuffixAlias('-') ->removeSuffixAlias('-')
->lowerCaseLocalPartIf(true); ->lowerCaseLocalPartIf(true);
} }

View File

@ -2,11 +2,11 @@
namespace bkrukowski\TransparentEmail\Tests\Emails; namespace bkrukowski\TransparentEmail\Tests\Emails;
use bkrukowski\TransparentEmail\Emails\MutableEmail; use bkrukowski\TransparentEmail\Emails\EditableEmail;
use bkrukowski\TransparentEmail\Emails\Email; use bkrukowski\TransparentEmail\Emails\Email;
use bkrukowski\TransparentEmail\Emails\EmailInterface; use bkrukowski\TransparentEmail\Emails\EmailInterface;
class MutableEmailTest extends \PHPUnit_Framework_TestCase class EditableEmailTest extends \PHPUnit_Framework_TestCase
{ {
/** /**
* @dataProvider providerRemoveFromLocalPart * @dataProvider providerRemoveFromLocalPart
@ -16,10 +16,11 @@ class MutableEmailTest extends \PHPUnit_Framework_TestCase
*/ */
public function testRemoveFromLocalPart(EmailInterface $email, string $toRemove) public function testRemoveFromLocalPart(EmailInterface $email, string $toRemove)
{ {
$editable = new MutableEmail($email); $editable = new EditableEmail($email);
$this->assertSame($editable, $editable->removeFromLocalPart($toRemove)); $new = $editable->removeFromLocalPart($toRemove);
$this->assertNotContains((string) $editable, $toRemove); $this->assertNotSame($editable, $new);
$this->assertSame($email->getDomain(), $editable->getDomain()); $this->assertNotContains((string) $new, $toRemove);
$this->assertSame($email->getDomain(), $new->getDomain());
} }
public function providerRemoveFromLocalPart() public function providerRemoveFromLocalPart()
@ -39,9 +40,10 @@ class MutableEmailTest extends \PHPUnit_Framework_TestCase
*/ */
public function testRemoveSuffixAlias(EmailInterface $email, string $delimiter, string $expected) public function testRemoveSuffixAlias(EmailInterface $email, string $delimiter, string $expected)
{ {
$editable = new MutableEmail($email); $editable = new EditableEmail($email);
$this->assertSame($editable, $editable->removeSuffixAlias($delimiter)); $new = $editable->removeSuffixAlias($delimiter);
$this->assertEquals($expected, $editable); $this->assertNotSame($editable, $new);
$this->assertEquals($expected, $new);
$this->assertSame($email->getDomain(), $editable->getDomain()); $this->assertSame($email->getDomain(), $editable->getDomain());
} }
@ -62,10 +64,11 @@ class MutableEmailTest extends \PHPUnit_Framework_TestCase
*/ */
public function testSetDomain(EmailInterface $email, string $domain) public function testSetDomain(EmailInterface $email, string $domain)
{ {
$editable = new MutableEmail($email); $editable = new EditableEmail($email);
$this->assertSame($editable, $editable->setDomain($domain)); $new = $editable->setDomain($domain);
$this->assertSame($domain, $editable->getDomain()); $this->assertNotSame($editable, $new);
$this->assertSame($email->getLocalPart(), $editable->getLocalPart()); $this->assertSame($domain, $new->getDomain());
$this->assertSame($email->getLocalPart(), $new->getLocalPart());
} }
public function providerSetDomain() public function providerSetDomain()
@ -85,10 +88,11 @@ class MutableEmailTest extends \PHPUnit_Framework_TestCase
*/ */
public function testLocalPart(EmailInterface $email, string $localPart) public function testLocalPart(EmailInterface $email, string $localPart)
{ {
$editable = new MutableEmail($email); $editable = new EditableEmail($email);
$this->assertSame($editable, $editable->setLocalPart($localPart)); $new = $editable->setLocalPart($localPart);
$this->assertSame($localPart, $editable->getLocalPart()); $this->assertNotSame($editable, $new);
$this->assertSame($email->getDomain(), $editable->getDomain()); $this->assertSame($localPart, $new->getLocalPart());
$this->assertSame($email->getDomain(), $new->getDomain());
} }
public function providerSetLocalPart() public function providerSetLocalPart()
@ -105,14 +109,15 @@ class MutableEmailTest extends \PHPUnit_Framework_TestCase
* *
* @param EmailInterface $email * @param EmailInterface $email
* @param bool $condition * @param bool $condition
* @param bool $expected * @param bool $isLowerCase
*/ */
public function testLowerCaseLocalPartIf(EmailInterface $email, bool $condition, bool $expected) public function testLowerCaseLocalPartIf(EmailInterface $email, bool $condition, bool $isLowerCase)
{ {
$editable = new MutableEmail($email); $editable = new EditableEmail($email);
$this->assertSame($editable, $editable->lowerCaseLocalPartIf($condition)); $new = $editable->lowerCaseLocalPartIf($condition);
$this->assertSame($expected, strtolower($editable->getLocalPart()) === $editable->getLocalPart()); $this->assertSame(!$condition, $editable === $new);
$this->assertSame($email->getDomain(), $editable->getDomain()); $this->assertSame($isLowerCase, strtolower($editable->getLocalPart()) === $new->getLocalPart());
$this->assertSame($email->getDomain(), $new->getDomain());
} }
public function providerLowerCaseLocalPartIf() public function providerLowerCaseLocalPartIf()