257 lines
7.2 KiB
Markdown
257 lines
7.2 KiB
Markdown
# 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
|
|
* `library/Exceptions/YourRuleNameException.php`: the exception thrown by the rule
|
|
* `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 `AbstractRule` 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
|
|
<?php
|
|
|
|
/*
|
|
* This file is part of Respect/Validation.
|
|
*
|
|
* (c) Alexandre Gomes Gaigalas <alexandre@gaigalas.net>
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE file
|
|
* that was distributed with this source code.
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Respect\Validation\Rules;
|
|
|
|
/**
|
|
* Explain in one sentence what this rule does.
|
|
*
|
|
* @author Your Name <youremail@yourdomain.tld>
|
|
*/
|
|
final class HelloWorld extends AbstractRule
|
|
{
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
public function validate($input): bool
|
|
{
|
|
return $input === 'Hello World';
|
|
}
|
|
}
|
|
```
|
|
|
|
### Creating the rule exception
|
|
|
|
Just that and we're done with the rule code. The Exception requires you to
|
|
declare messages used by `assert()` and `check()`. Messages are declared in
|
|
affirmative and negative moods, so if anyone calls `v::not(v::helloWorld())` the
|
|
library will show the appropriate message.
|
|
|
|
```php
|
|
<?php
|
|
|
|
/*
|
|
* This file is part of Respect/Validation.
|
|
*
|
|
* (c) Alexandre Gomes Gaigalas <alexandre@gaigalas.net>
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE file
|
|
* that was distributed with this source code.
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Respect\Validation\Exceptions;
|
|
|
|
/**
|
|
* @author Your Name <youremail@yourdomain.tld>
|
|
*/
|
|
final class HelloWorldException extends ValidationException
|
|
{
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
protected $defaultTemplates = [
|
|
self::MODE_DEFAULT => [
|
|
self::STANDARD => '{{name}} must be a Hello World',
|
|
],
|
|
self::MODE_NEGATIVE => [
|
|
self::STANDARD => '{{name}} must not be a 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
|
|
<?php
|
|
|
|
/*
|
|
* This file is part of Respect/Validation.
|
|
*
|
|
* (c) Alexandre Gomes Gaigalas <alexandre@gaigalas.net>
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE file
|
|
* that was distributed with this source code.
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Respect\Validation\Rules;
|
|
|
|
use Respect\Validation\Test\RuleTestCase;
|
|
|
|
/**
|
|
* @group rule
|
|
*
|
|
* @covers \Respect\Validation\Rules\HelloWorld
|
|
*
|
|
* @author Your Name <youremail@yourdomain.tld>
|
|
*/
|
|
final class HelloWorldTest extends RuleTestCase
|
|
{
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
public function providerForValidInput(): array
|
|
{
|
|
$rule = new HelloWorld();
|
|
|
|
return [
|
|
[$rule, 'Hello World'],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
public function providerForInvalidInput(): array
|
|
{
|
|
$rule = new HelloWorld();
|
|
|
|
return [
|
|
[$rule, 'Not a hello'],
|
|
[$rule, 'Hello darkness, my old friend'],
|
|
[$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, exception 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:
|
|
```sh
|
|
$ vendor/bin/phpunit
|
|
```
|
|
|
|
or
|
|
|
|
```sh
|
|
$ composer phpunit
|
|
```
|
|
|
|
### Windows
|
|
|
|
You can test the project using the commands:
|
|
```sh
|
|
> vendor\bin\phpunit
|
|
```
|
|
|
|
or
|
|
|
|
```sh
|
|
> 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.
|
|
|
|
[ArrayType]: https://github.com/Respect/Validation/commit/f08a1fa
|
|
[data provider]: https://phpunit.de/manual/current/en/writing-tests-for-phpunit.html#writing-tests-for-phpunit.data-providers "PHPUnit Data Providers"
|
|
[open an issue]: http://github.com/Respect/Validation/issues
|
|
[PHP-FIG]: http://www.php-fig.org "PHP Framework Interop Group"
|
|
[project documentation]: https://respect-validation.readthedocs.io/ "Respect\Validation documentation"
|
|
[pull requests]: http://help.github.com/pull-requests "GitHub pull requests"
|