# Respect\Validation - How to Contribute

This is a guide for anyone willing to contribute with Respect\Validation. Anyone
can contribute!

Please see the [project documentation](http://documentup.com/Respect/Validation)
before proceeding. You should also know about PSR-0 and basic unit testing, but
I'm sure you can learn that just by looking at other rules. Pick the simple ones
like `Int` to begin.

Before writing anything, make sure there is no validator that already does what
you need. Also, it would be awesome if you
[open an issue](http://github.com/Respect/Validation/issues) before starting,
so if anyone has the same idea the guy will see that you're already doing that.

## Adding a new Validator

A common validator on Respect is composed of three classes:

  * library/Respect/Validation/Rules/YourRuleName.php - The rule itself
  * library/Respect/Validation/Exceptions/YourRuleNameException.php - The exception thrown by the rule
  * tests/library/Respect/Validation/Exceptions/YourRuleNameTest.php - Tests for the validator

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

## Samples

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

```php
namespace Respect\Validation\Rules;

use Respect\Validation\Validatable;

class HelloWorld extends AbstractRule implements Validatable
{
    public function validate($input)
    {
        return $input === 'Hello World';
    }
}
```

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())` Respect will show
the appropriate message.

```php
namespace Respect\Validation\Exceptions;

class HelloWorldException extends ValidationException
{
    public static $defaultTemplates = array(
        self::MODE_DEFAULT => array(
            self::STANDARD => '{{name}} must be a Hello World',
        ),
        self::MODE_NEGATIVE => array(
            self::STANDARD => '{{name}} must not be a Hello World',
        )
    );
}
```

Finally, we need to test if everything is running smooth:

```php
namespace Respect\Validation\Rules;

class HelloWorldTest extends \PHPUnit_Framework_TestCase
{
    protected $validator;

    protected function setUp()
    {
        $this->validator = new HelloWorld;
    }

    public function testOk($input)
    {
        $this->assertTrue($this->validator->validate('Hello World'));
        $this->assertTrue($this->validator->check('Hello World'));
        $this->assertTrue($this->validator->assert('Hello World'));
    }

    /** @expectedException Respect\Validation\Exceptions\HelloWorldException */
    public function testFailAssert($input)
    {
        $this->assertFalse($this->validator->validate('Lorem Ipsum'));
        $this->assertFalse($this->validator->assert('Lorem Ipsum'));
    }

    /** @expectedException Respect\Validation\Exceptions\HelloWorldException */
    public function testFailCheck($input)
    {
        $this->assertFalse($this->validator->validate('Lorem Ipsum'));
        $this->assertFalse($this->validator->check('Lorem Ipsum'));
    }
}
```

## Documentation

Our docs at http://documentup.com/Respect/Validation are generated by our
README.md on the project root. Add your brand new rule there and everything will
update automatically =)

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

## 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
```

### Windows

You can test the project using the commands:
```sh
$ vendor\bin\phpunit
```

No test should fail.

## Sending your code to us

Please see http://help.github.com/pull-requests/.
