Skip to content

Commit

Permalink
Use stateless validator
Browse files Browse the repository at this point in the history
  • Loading branch information
xepozz committed Jan 24, 2021
1 parent cb9ae99 commit ec7c929
Show file tree
Hide file tree
Showing 16 changed files with 118 additions and 87 deletions.
17 changes: 5 additions & 12 deletions src/FormModel.php
Expand Up @@ -5,13 +5,12 @@
namespace Yiisoft\Form;

use Closure;
use ReflectionClass;
use InvalidArgumentException;
use ReflectionClass;
use Yiisoft\Strings\Inflector;
use Yiisoft\Strings\StringHelper;
use Yiisoft\Validator\Rule\Required;
use Yiisoft\Validator\ValidatorFactoryInterface;

use Yiisoft\Validator\ValidatorInterface;
use function array_key_exists;
use function array_merge;
use function explode;
Expand All @@ -26,18 +25,14 @@
*/
abstract class FormModel implements FormModelInterface
{
private ValidatorFactoryInterface $validatorFactory;

private array $attributes;
private array $attributesLabels;
private array $attributesErrors = [];
private ?Inflector $inflector = null;
private bool $validated = false;

public function __construct(ValidatorFactoryInterface $validatorFactory)
public function __construct()
{
$this->validatorFactory = $validatorFactory;

$this->attributes = $this->collectAttributes();
$this->attributesLabels = $this->attributeLabels();
}
Expand Down Expand Up @@ -214,16 +209,14 @@ public function setAttribute(string $name, $value): void
}
}

public function validate(): bool
public function validate(ValidatorInterface $validator): bool
{
$this->clearErrors();

$rules = $this->rules();

if (!empty($rules)) {
$results = $this->validatorFactory
->create($rules)
->validate($this);
$results = $validator->validate($this, $rules);

foreach ($results as $attribute => $result) {
if ($result->isValid() === false) {
Expand Down
3 changes: 2 additions & 1 deletion src/FormModelInterface.php
Expand Up @@ -5,6 +5,7 @@
namespace Yiisoft\Form;

use Yiisoft\Validator\DataSetInterface;
use Yiisoft\Validator\ValidatorInterface;

/**
* FormModelInterface model represents an HTML form: its data, validation and presentation.
Expand Down Expand Up @@ -221,7 +222,7 @@ public function load(array $data, ?string $formName = null): bool;
*
* @return bool whether the validation is successful without any error.
*/
public function validate(): bool;
public function validate(ValidatorInterface $validator): bool;

/**
* Set specified attribute
Expand Down
37 changes: 17 additions & 20 deletions tests/FormModelTest.php
Expand Up @@ -7,8 +7,9 @@
use InvalidArgumentException;
use Yiisoft\Form\FormModel;
use Yiisoft\Form\Tests\Stub\LoginForm;
use Yiisoft\Form\Tests\Stub\ValidatorMock;
use Yiisoft\Validator\Rule\Required;

use Yiisoft\Validator\ValidatorInterface;
use function str_repeat;

require __DIR__ . '/Stub/NonNamespacedForm.php';
Expand All @@ -17,7 +18,7 @@ final class FormModelTest extends TestCase
{
public function testAnonymousFormName(): void
{
$form = new class(new ValidatorFactoryMock()) extends FormModel {};
$form = new class() extends FormModel {};
$this->assertEquals('', $form->formName());
}

Expand Down Expand Up @@ -46,7 +47,7 @@ public function testUnknownPropertyType(): void
'/You must specify the type hint for "%s" property in "([^"]+)" class./',
'property',
));
$form = new class(new ValidatorFactoryMock()) extends FormModel {
$form = new class() extends FormModel {
private $property;
};
}
Expand Down Expand Up @@ -138,7 +139,7 @@ public function testErrorSummary(): void
];

$this->assertTrue($form->load($data));
$this->assertFalse($form->validate());
$this->assertFalse($form->validate($this->createValidatorMock()));

$this->assertEquals(
$expected,
Expand Down Expand Up @@ -208,7 +209,7 @@ public function testLoadWithNestedAttribute(): void
public function testFailedLoadForm(): void
{
$form1 = new LoginForm();
$form2 = new class(new ValidatorFactoryMock()) extends FormModel {
$form2 = new class() extends FormModel {
};

$data1 = [
Expand All @@ -230,7 +231,7 @@ public function testFailedLoadForm(): void

public function testLoadWithEmptyScope()
{
$form = new class(new ValidatorFactoryMock()) extends FormModel {
$form = new class() extends FormModel {
private int $int = 1;
private string $string = 'string';
private float $float = 3.14;
Expand Down Expand Up @@ -275,51 +276,47 @@ public function testValidatorRules(): void
$form = new LoginForm();

$form->login('');
$form->validate();
$form->validate($this->createValidatorMock());

$this->assertEquals(
['Value cannot be blank.'],
$form->error('login')
);

$form->login('x');
$form->validate();
$form->validate($this->createValidatorMock());
$this->assertEquals(
['Is too short.'],
$form->error('login')
);

$form->login(str_repeat('x', 60));
$form->validate();
$form->validate($this->createValidatorMock());
$this->assertEquals(
'Is too long.',
$form->firstError('login')
);

$form->login('admin@.com');
$form->validate();
$form->validate($this->createValidatorMock());
$this->assertEquals(
'This value is not a valid email address.',
$form->firstError('login')
);
}

private function createValidatorMock(): ValidatorInterface
{
return new ValidatorMock();
}
}

final class DefaultFormNameForm extends FormModel
{
public function __construct()
{
parent::__construct(new ValidatorFactoryMock());
}
}

final class CustomFormNameForm extends FormModel
{
public function __construct()
{
parent::__construct(new ValidatorFactoryMock());
}

public function formName(): string
{
return 'my-best-form-name';
Expand All @@ -334,7 +331,7 @@ final class FormWithNestedAttribute extends FormModel
public function __construct()
{
$this->user = new LoginForm();
parent::__construct(new ValidatorFactoryMock());
parent::__construct();
}

public function attributeLabels(): array
Expand Down
3 changes: 1 addition & 2 deletions tests/Helper/HtmlFormTest.php
Expand Up @@ -9,7 +9,6 @@
use Yiisoft\Form\Helper\HtmlForm;
use Yiisoft\Form\Tests\Stub\LoginForm;
use Yiisoft\Form\Tests\TestCase;
use Yiisoft\Form\Tests\ValidatorFactoryMock;

final class HtmlFormTest extends TestCase
{
Expand All @@ -26,7 +25,7 @@ public function testGetAttributeName(): void
public function dataGetInputName(): array
{
$loginForm = new LoginForm();
$anonymousForm = new class(new ValidatorFactoryMock()) extends FormModel {
$anonymousForm = new class() extends FormModel {
};
return [
[$loginForm, '[0]content', 'LoginForm[0][content]'],
Expand Down
6 changes: 0 additions & 6 deletions tests/Stub/LoginForm.php
Expand Up @@ -5,7 +5,6 @@
namespace Yiisoft\Form\Tests\Stub;

use Yiisoft\Form\FormModel;
use Yiisoft\Form\Tests\ValidatorFactoryMock;
use Yiisoft\Validator\Rule\Email;
use Yiisoft\Validator\Rule\HasLength;
use Yiisoft\Validator\Rule\Required;
Expand All @@ -17,11 +16,6 @@ class LoginForm extends FormModel
private ?string $password = null;
private bool $rememberMe = false;

public function __construct()
{
parent::__construct(new ValidatorFactoryMock());
}

public function getLogin(): ?string
{
return $this->login;
Expand Down
5 changes: 0 additions & 5 deletions tests/Stub/NonNamespacedForm.php
Expand Up @@ -3,12 +3,7 @@
declare(strict_types=1);

use Yiisoft\Form\FormModel;
use Yiisoft\Form\Tests\ValidatorFactoryMock;

class NonNamespacedForm extends FormModel
{
public function __construct()
{
parent::__construct(new ValidatorFactoryMock());
}
}
6 changes: 0 additions & 6 deletions tests/Stub/PersonalForm.php
Expand Up @@ -5,7 +5,6 @@
namespace Yiisoft\Form\Tests\Stub;

use Yiisoft\Form\FormModel;
use Yiisoft\Form\Tests\ValidatorFactoryMock;
use Yiisoft\Validator\Rule\Email;
use Yiisoft\Validator\Rule\HasLength;
use Yiisoft\Validator\Rule\MatchRegularExpression;
Expand All @@ -27,11 +26,6 @@ final class PersonalForm extends FormModel
private bool $terms = false;
private ?string $attachFiles = null;

public function __construct()
{
parent::__construct(new ValidatorFactoryMock());
}

public function attributeLabels(): array
{
return [];
Expand Down
26 changes: 26 additions & 0 deletions tests/Stub/ValidatorMock.php
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Form\Tests\Stub;

use Yiisoft\Validator\DataSetInterface;
use Yiisoft\Validator\Formatter;
use Yiisoft\Validator\ResultSet;
use Yiisoft\Validator\Validator;
use Yiisoft\Validator\ValidatorInterface;

final class ValidatorMock implements ValidatorInterface
{
private Validator $validator;

public function __construct()
{
$this->validator = new Validator(new Formatter());
}

public function validate(DataSetInterface $dataSet, iterable $rules): ResultSet
{
return $this->validator->validate($dataSet, $rules);
}
}
17 changes: 0 additions & 17 deletions tests/ValidatorFactoryMock.php

This file was deleted.

9 changes: 8 additions & 1 deletion tests/Widget/ErrorSummaryTest.php
Expand Up @@ -5,8 +5,10 @@
namespace Yiisoft\Form\Tests\Widget;

use Yiisoft\Form\Tests\Stub\PersonalForm;
use Yiisoft\Form\Tests\Stub\ValidatorMock;
use Yiisoft\Form\Tests\TestCase;
use Yiisoft\Form\Widget\ErrorSummary;
use Yiisoft\Validator\ValidatorInterface;

final class ErrorSummaryTest extends TestCase
{
Expand Down Expand Up @@ -61,8 +63,13 @@ public function testErrorSummary(string $name, string $email, string $password,
$data = new PersonalForm();

$data->load($record);
$data->validate();
$data->validate($this->createValidatorMock());
$html = ErrorSummary::widget()->config($data, $options)->run();
$this->assertEqualsWithoutLE($expected, $html);
}

private function createValidatorMock(): ValidatorInterface
{
return new ValidatorMock();
}
}

0 comments on commit ec7c929

Please sign in to comment.