diff --git a/README.md b/README.md index b4194283..d7426ca0 100644 --- a/README.md +++ b/README.md @@ -387,6 +387,37 @@ Feature: Listing user toys """ ``` +## PHPUnit integration + +The `assertMatchesPattern()` is a handy assertion that matches values in PHPUnit tests. +To use it either include the `Coduo\PHPMatcher\PHPUnit\PHPMatcherAssertions` trait, +or extend the `Coduo\PHPMatcher\PHPUnit\PHPMatcherTestCase`: + +```php +namespace Coduo\PHPMatcher\Tests\PHPUnit; + +use Coduo\PHPMatcher\PHPUnit\PHPMatcherAssertions; + +class PHPMatcherAssertionsTest extends \PHPUnit_Framework_TestCase +{ + use PHPMatcherAssertions; + + public function test_it_asserts_if_a_value_matches_the_pattern() + { + $this->assertMatchesPattern('@string@', 'foo'); + } +} +``` + +The `matchesPattern()` method can be used in PHPUnit stubs or mocks: + +```php +$mock = $this->getMock(Foo::class); +$mock->method('bar') + ->with($this->matchesPattern('@string@')) + ->willReturn('foo'); +``` + ## License This library is distributed under the MIT license. Please see the LICENSE file. diff --git a/phpunit.xml.dist b/phpunit.xml.dist index c2cbcfc9..60e0cdae 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -13,11 +13,13 @@ ./tests/ + tests/PHPUnit/PHPMatcherAssertionsTest.php + tests/PHPUnit/PHPMatcherAssertionsTest.php - ./src/Coduo/PHPMatcher/ + ./src/ diff --git a/src/PHPUnit/PHPMatcherAssertions.php b/src/PHPUnit/PHPMatcherAssertions.php new file mode 100644 index 00000000..4a71afc1 --- /dev/null +++ b/src/PHPUnit/PHPMatcherAssertions.php @@ -0,0 +1,26 @@ +pattern = $pattern; + $this->matcher = $this->createMatcher(); + } + + /** + * @return string + */ + public function toString() + { + return 'matches the pattern'; + } + + /** + * @param mixed $other + * + * @return null|string + */ + protected function additionalFailureDescription($other) + { + return $this->matcher->getError(); + } + + /** + * @param mixed $value + * + * @return bool + */ + protected function matches($value) + { + return $this->matcher->match($value, $this->pattern); + } + + /** + * @return Matcher + */ + private function createMatcher() + { + $factory = new SimpleFactory(); + + return $factory->createMatcher(); + } +} \ No newline at end of file diff --git a/src/PHPUnit/PHPMatcherTestCase.php b/src/PHPUnit/PHPMatcherTestCase.php new file mode 100644 index 00000000..42c92762 --- /dev/null +++ b/src/PHPUnit/PHPMatcherTestCase.php @@ -0,0 +1,26 @@ +assertThat($value, self::matchesPattern($pattern), $message); + } + + /** + * @param string $pattern + * + * @return PHPMatcherConstraint + */ + protected static function matchesPattern($pattern) + { + return new PHPMatcherConstraint($pattern); + } +} \ No newline at end of file diff --git a/tests/PHPUnit/PHPMatcherAssertionsTest.php b/tests/PHPUnit/PHPMatcherAssertionsTest.php new file mode 100644 index 00000000..bc394055 --- /dev/null +++ b/tests/PHPUnit/PHPMatcherAssertionsTest.php @@ -0,0 +1,41 @@ +assertMatchesPattern('@string@', 'foo'); + } + + /** + * @expectedException \PHPUnit_Framework_ExpectationFailedException + * @expectedExceptionMessage Failed asserting that '{"foo":"bar"}' matches the pattern + */ + public function test_it_throws_an_expectation_failed_exception_if_a_value_does_not_match_the_pattern() + { + $this->assertMatchesPattern('{"foo": "@integer@"}', json_encode(array('foo' => 'bar'))); + } + + /** + * @expectedException \PHPUnit_Framework_ExpectationFailedException + * @expectedExceptionMessage Failed asserting that 42 matches the pattern. + */ + public function test_it_creates_a_constraint_for_stubs() + { + $mock = $this->getMockBuilder('stdClass') + ->setMethods(array('getTitle')) + ->getMock(); + + $mock->method('getTitle') + ->with($this->matchesPattern('@string@')) + ->willReturn('foo'); + + $mock->getTitle(42); + } +} diff --git a/tests/PHPUnit/PHPMatcherConstraintTest.php b/tests/PHPUnit/PHPMatcherConstraintTest.php new file mode 100644 index 00000000..a0870977 --- /dev/null +++ b/tests/PHPUnit/PHPMatcherConstraintTest.php @@ -0,0 +1,56 @@ +assertInstanceOf('PHPUnit_Framework_Constraint', new PHPMatcherConstraint('@string@')); + } + + public function test_it_returns_true_if_a_value_matches_the_pattern() + { + $constraint = new PHPMatcherConstraint('@string@'); + + $this->assertTrue($constraint->evaluate('foo', '', true)); + } + + public function test_it_returns_false_if_a_value_does_not_match_the_pattern() + { + $constraint = new PHPMatcherConstraint('@string@'); + + $this->assertFalse($constraint->evaluate(42, '', true)); + } + + public function test_it_returns_false_if_a_pattern_is_not_a_string() + { + $constraint = new PHPMatcherConstraint(new \stdClass()); + + $this->assertFalse($constraint->evaluate('foo', '', true)); + } + + /** + * @expectedException \PHPUnit_Framework_ExpectationFailedException + * @expectedExceptionMessage Failed asserting that 42 matches the pattern + */ + public function test_it_sets_a_failure_description_if_not_given() + { + $constraint = new PHPMatcherConstraint('@string@'); + + $this->assertFalse($constraint->evaluate(42)); + } + + /** + * @expectedException \PHPUnit_Framework_ExpectationFailedException + * @expectedExceptionMessage integer "42" is not a valid string + */ + public function test_it_sets_additional_failure_description() + { + $constraint = new PHPMatcherConstraint('@string@'); + + $this->assertFalse($constraint->evaluate(42)); + } +} diff --git a/tests/PHPUnit/PHPMatcherTestCaseTest.php b/tests/PHPUnit/PHPMatcherTestCaseTest.php new file mode 100644 index 00000000..b5f63a22 --- /dev/null +++ b/tests/PHPUnit/PHPMatcherTestCaseTest.php @@ -0,0 +1,39 @@ +assertMatchesPattern('@string@', 'foo'); + } + + /** + * @expectedException \PHPUnit_Framework_ExpectationFailedException + * @expectedExceptionMessage Failed asserting that '{"foo":"bar"}' matches the pattern + */ + public function test_it_throws_an_expectation_failed_exception_if_a_value_does_not_match_the_pattern() + { + $this->assertMatchesPattern('{"foo": "@integer@"}', json_encode(array('foo' => 'bar'))); + } + + /** + * @expectedException \PHPUnit_Framework_ExpectationFailedException + * @expectedExceptionMessage Failed asserting that 42 matches the pattern. + */ + public function test_it_creates_a_constraint_for_stubs() + { + $mock = $this->getMockBuilder('stdClass') + ->setMethods(array('getTitle')) + ->getMock(); + + $mock->method('getTitle') + ->with($this->matchesPattern('@string@')) + ->willReturn('foo'); + + $mock->getTitle(42); + } +}