respect-validation/CONTRIBUTING.md
Henrique Moody 66faefd695
Remove previous validation engine
After many refactorings, no rules use the previous validation engine.
That means we can remove the unused code from the repository and switch
from the previous to the new validation engine everywhere.

This commit will also soft deprecate the methods "validate()", and
"check()" in all the rules and the "assert()" in all rules but the
Validator itself. That means using those methods will still be allowed,
but static analysis tools might complain.

This is a big step toward releasing the next major version, as the code
is pretty much the way it should be when I release the next version.
There's some documentation to be updated, and I would like to change the
behavior of a couple of rules.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-25 12:28:25 +01:00

5.9 KiB

Contributing

Contributions to Respect\Validation are always welcome. You make our lives easier by sending us your contributions through pull requests.

Pull requests for bug fixes must be based on the oldest stable version's branch whereas pull requests for new features must be based on the master branch.

Due to time constraints, we are not always able to respond as quickly as we would like. Please do not take delays personal and feel free to remind us here, on IRC, or on Gitter if you feel that we forgot to respond.

Please see the project documentation before proceeding. You should also know about PHP-FIG's standards and basic unit testing, but we're sure you can learn that just by looking at other rules. Pick the simple ones like ArrayType to begin.

Before writing anything, feature or bug fix:

  • Check if there is already an issue related to it (opened or closed) and if someone is already working on that;
    • If there is not, open an issue and notify everybody that you're going to work on that;
    • If there is, create a comment to notify everybody that you're going to work on that.
  • Make sure that what you need is not done yet

Adding a new validator

A common validator (rule) on Respect\Validation is composed of three classes:

  • library/Rules/YourRuleName.php: the rule itself
  • tests/unit/Rules/YourRuleNameTest.php: tests for the rule

The classes are pretty straightforward. In the sample below, we're going to create a validator that validates if a string is equal to "Hello World".

  • Classes should be final unless they are used in a different scope;
  • Properties should be private unless they are used in a different scope;
  • Classes should use strict typing;
  • Some docblocks are required.

Creating the rule

The rule itself needs to implement the Validatable interface but, it is convenient to just extend the Simple or Standard class. Doing that, you'll only need to declare one method: validate($input). This method must return true or false.

If your validator class is HelloWorld, it will be available as v::helloWorld() and will natively have support for chaining and everything else.

<?php

/*
 * Copyright (c) Alexandre Gomes Gaigalas <alganet@gmail.com>
 * SPDX-License-Identifier: MIT
 */

declare(strict_types=1);

namespace Respect\Validation\Rules;

use Respect\Validation\Message\Template;
use Respect\Validation\Rules\Core\Simple;

#[Template(
    '{{name}} must be a Hello World',
    '{{name}} must not be a Hello World',
)]
final class HelloWorld extends Simple
{
    protected function isValid(mixed $input): bool
    {
        return $input === 'Hello World';
    }
}

Creating unit tests

Finally, we need to test if everything is running smooth. We have RuleTestCase that allows us to make easier to test rules, but you fell free to use the PHPUnit\Framework\TestCase if you want or you need it's necessary.

The RuleTestCase extends PHPUnit's PHPUnit\Framework\TestCase class, so you are able to use any methods of it. By extending RuleTestCase you should implement two methods that should return a data provider with the rule as first item of the arrays:

  • providerForValidInput: Will test when validate() should return true
  • providerForInvalidInput: Will test when validate() should return false
<?php

/*
 * Copyright (c) Alexandre Gomes Gaigalas <alganet@gmail.com>
 * SPDX-License-Identifier: MIT
 */

declare(strict_types=1);

namespace Respect\Validation\Rules;

use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Group;
use Respect\Validation\Test\RuleTestCase;

#[Group('rule')]
#[CoversClass(HelloWorld::class)]
final class HelloWorldTest extends RuleTestCase
{
    /** @return array<array{HelloWorld, mixed}> */
    public static function providerForValidInput(): iterable
    {
        yield [new HelloWorld(), 'Hello World'];
    }

    /** @return array<array{HelloWorld, mixed}> */
    public static function providerForInvalidInput(): iterable
    {
        $rule = new HelloWorld();

        yield [$rule, 'Not a hello'];
        yield [$rule, 'Hello darkness, my old friend'];
        yield [$rule, 'Hello is it me you\'re looking for?'];
    }
}

If the constructor of your rule accepts arguments you may create specific tests for it other than what is covered by RuleTestCase.

Helping us a little bit more

You rule will be accepted only with these 3 files (rule and unit test), but if you really want to help us, you can follow the example of ArrayType by:

  • Adding your new rule on the Validator's class docblock;
  • Writing a documentation for your new rule;
  • Creating integration tests with PHPT.

As we already said, none of them are required but you will help us a lot.

Documentation

Our docs at https://respect-validation.readthedocs.io are generated from our Markdown files. Add your brand new rule and it should be soon available.

Running Tests

After run composer install on the library's root directory you must run PHPUnit.

Linux

You can test the project using the commands:

$ vendor/bin/phpunit

or

$ composer phpunit

Windows

You can test the project using the commands:

> vendor\bin\phpunit

or

> composer phpunit

No test should fail.

You can tweak the PHPUnit's settings by copying phpunit.xml.dist to phpunit.xml and changing it according to your needs.