Permalink
Browse files

Add test for conditional constraints

  • Loading branch information...
enumag committed Nov 9, 2016
1 parent 89e5028 commit 3efc82717b9965bb19a2609e4caddc0c5467552d
View
@@ -0,0 +1,5 @@
/tests export-ignore
.gitattributes export-ignore
.gitignore export-ignore
.travis.yml export-ignore
phpunit.xml export-ignore
View
@@ -6,8 +6,17 @@
"tomasvotruba/sculpin-translation-bundle": "@dev"
},
"require-dev": {
"nette/utils": "^2.4",
"phpunit/phpunit": "^5.6",
"symfony/validator": "^3.2@dev",
"tracy/tracy": "^2.4"
},
"autoload-dev": {
"classmap": [
"src/",
"tests/"
]
},
"repositories": [
{ "type": "path", "url": "packages/tomasvotruba/sculpin-blog-bundle" },
{ "type": "path", "url": "packages/tomasvotruba/sculpin-translation-bundle" }
View
@@ -0,0 +1,18 @@
<phpunit
bootstrap="tests/bootstrap.php"
colors="true"
>
<testsuites>
<testsuite>
<directory>tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">src</directory>
</whitelist>
</filter>
<listeners>
<listener class="Tests\ClearLogAndCacheTestListener" />
</listeners>
</phpunit>
@@ -26,6 +26,7 @@ class Client
/**
* @var int
* @Assert\NotNull()
* @Assert\Choice({Client::TYPE_COMPANY, CLIENT::TYPE_PERSON})
*/
protected $type;
@@ -70,25 +71,26 @@ class Client
/**
* @var int
* @Assert\NotNull()
* @Assert\Choice({Client::TYPE_COMPANY, CLIENT::TYPE_PERSON})
*/
protected $type;
/**
* @var string
* @Assert\NotBlank(groups={"company"})
* @Assert\NotBlank(groups = {"company"})
*/
protected $company;
/**
* @var string
* @Assert\NotBlank(groups={"person"})
* @Assert\NotBlank(groups = {"person"})
*/
protected $firstname;
/**
* @var string
* @Assert\NotBlank(groups={"person"})
* @Assert\NotBlank(groups = {"person"})
*/
protected $lastname;
}
@@ -102,17 +104,21 @@ To make the validation truly conditional it's better to let the Client entity de
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\GroupSequenceProviderInterface;
/**
* @Assert\GroupSequenceProvider()
*/
class Client implements GroupSequenceProviderInterface
{
// same as before
public function getGroupSequence()
{
return [
// Include the default group to validate the $type property as well.
'Default',
// Include the "Client" group to validate the $type property as well.
// Note that using the "Default" group here won't work!
'Client',
// Use either the person or company group based on whether company is filled or not.
$this->type === TYPE_COMPANY ? 'company' : 'person',
$this->type === self::TYPE_PERSON ? 'person' : 'company',
];
}
}
@@ -126,6 +132,9 @@ Prior to Symfony 3.2 there was a drawback to this solution. Symfony/Validator ru
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\GroupSequenceProviderInterface;
/**
* @Assert\GroupSequenceProvider()
*/
class Client implements GroupSequenceProviderInterface
{
// same as before
@@ -137,8 +146,8 @@ class Client implements GroupSequenceProviderInterface
// If we want to get all violations at once we will return just
// one validation step containing an array of the groups to validate.
[
'Default',
$this->type === TYPE_COMPANY ? 'company' : 'person',
'Client',
$this->type === self::TYPE_PERSON ? 'person' : 'company',
]
];
}
@@ -0,0 +1,117 @@
<?php
namespace ConditionalConstraints;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\GroupSequenceProviderInterface;
/**
* @Assert\GroupSequenceProvider()
*/
class Client implements GroupSequenceProviderInterface
{
const TYPE_COMPANY = 1;
const TYPE_PERSON = 2;
/**
* @var int
* @Assert\NotNull()
* @Assert\Choice({Client::TYPE_COMPANY, CLIENT::TYPE_PERSON})
*/
private $type;
/**
* @var string
* @Assert\NotBlank(groups = {"company"})
*/
private $company;
/**
* @var string
* @Assert\NotBlank(groups = {"person"})
*/
private $firstname;
/**
* @var string
* @Assert\NotBlank(groups = {"person"})
*/
private $lastname;
/**
* @return array
*/
public function getGroupSequence()
{
return [
[
'Client',
$this->type === self::TYPE_PERSON ? 'person' : 'company',
],
];
}
/**
* @return int
*/
public function getType(): int
{
return $this->type;
}
/**
* @param int $type
*/
public function setType(int $type)
{
$this->type = $type;
}
/**
* @return string
*/
public function getCompany(): string
{
return $this->company;
}
/**
* @param string $company
*/
public function setCompany(string $company)
{
$this->company = $company;
}
/**
* @return string
*/
public function getFirstname(): string
{
return $this->firstname;
}
/**
* @param string $firstname
*/
public function setFirstname(string $firstname)
{
$this->firstname = $firstname;
}
/**
* @return string
*/
public function getLastname(): string
{
return $this->lastname;
}
/**
* @param string $lastname
*/
public function setLastname(string $lastname)
{
$this->lastname = $lastname;
}
}
@@ -0,0 +1,76 @@
<?php
namespace Tests\ConditionalConstraints;
use ConditionalConstraints\Client;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Validator\ConstraintViolationInterface;
use Symfony\Component\Validator\ConstraintViolationListInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Symfony\Component\Validator\ValidatorBuilder;
class ConditionalConstraintsTest extends TestCase
{
/**
* @var ValidatorInterface
*/
private $validator;
public function setUp()
{
$builder = new ValidatorBuilder();
$builder->enableAnnotationMapping();
$this->validator = $builder->getValidator();
}
public function testViolationsFromDefaultAndCustomGroup()
{
$client = new Client();
$this->assertViolations(
[
'type' => 'This value should not be null.',
'company' => 'This value should not be blank.',
],
$this->validator->validate($client)
);
}
public function testViolationsFromCompanyGroup()
{
$client = new Client();
$client->setType(Client::TYPE_COMPANY);
$this->assertViolations(
[
'company' => 'This value should not be blank.',
],
$this->validator->validate($client)
);
}
public function testViolationsFromPersonGroup()
{
$client = new Client();
$client->setType(Client::TYPE_PERSON);
$this->assertViolations(
[
'firstname' => 'This value should not be blank.',
'lastname' => 'This value should not be blank.',
],
$this->validator->validate($client)
);
}
private function assertViolations(array $expected, ConstraintViolationListInterface $violationList)
{
$violations = [];
foreach ($violationList as $violation) {
/** @var ConstraintViolationInterface $violation */
$violations[$violation->getPropertyPath()] = $violation->getMessage();
}
$this->assertSame($expected, $violations);
}
}
@@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
namespace Tests;
use Nette\Utils\FileSystem;
use PHPUnit_Framework_BaseTestListener;
use PHPUnit_Framework_TestSuite;
final class ClearLogAndCacheTestListener extends PHPUnit_Framework_BaseTestListener
{
public function endTestSuite(PHPUnit_Framework_TestSuite $testSuite)
{
if ($testSuite->getName()) {
return;
}
foreach ($this->getTempAndLogDirectories() as $path => $info) {
FileSystem::delete($path);
}
}
/**
* @return string[]
*/
private function getTempAndLogDirectories(): array
{
return [
__DIR__ . '/cache',
__DIR__ . '/logs',
];
}
}
View
@@ -0,0 +1,7 @@
<?php
use Doctrine\Common\Annotations\AnnotationRegistry;
require __DIR__ . '/../vendor/autoload.php';
AnnotationRegistry::registerLoader('class_exists');

0 comments on commit 3efc827

Please sign in to comment.