PHPackages                             counterpart/counterpart - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Testing &amp; Quality](/categories/testing)
4. /
5. counterpart/counterpart

ActiveLibrary[Testing &amp; Quality](/categories/testing)

counterpart/counterpart
=======================

A set of generic matchers -- for seeing if one value matches another

1.5.0(11y ago)38.5k[2 issues](https://github.com/chrisguitarguy/Counterpart/issues)1Apache-2.0PHPPHP &gt;=5.4

Since May 5Pushed 10y ago1 watchersCompare

[ Source](https://github.com/chrisguitarguy/Counterpart)[ Packagist](https://packagist.org/packages/counterpart/counterpart)[ Docs](http://docs.counterpartphp.org)[ RSS](/packages/counterpart-counterpart/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (4)Versions (9)Used By (1)

Counterpart
===========

[](#counterpart)

[![Build Status](https://camo.githubusercontent.com/d6071e8fcadf9730aaa9d74398159657acdfa207d8046e031b2d7b926c77f102/68747470733a2f2f7472617669732d63692e6f72672f63687269736775697461726775792f436f756e746572706172742e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/chrisguitarguy/Counterpart)

Counterpart is an object matching framework for PHP inspired by [PHPUnit](http://phpunit.de/)'s constraints and [Hamcrest](http://hamcrest.org/).

Where to Use?
-------------

[](#where-to-use)

As part of a testing framework or someplace you'd need to assert a given value matches some expected constraint.

Examples
--------

[](#examples)

Two classes act as factories and are, by the far, the easiest way to get started.

You can see some pretty high-level usage of of the `Assert` and `Matchers` API.

#### Creating Matchers

[](#creating-matchers)

```
use Counterpart\Matchers;

$isTrue = Matchers::isTrue();
$isTrue->matches(false); // false
$isTrue->matches(true); // true
```

#### Assertions

[](#assertions)

All of the `assert*` methods in `Counterpart\Assert` will throw a `Counterpart\Exception\AssertionFailed` exception.

```
use Counterpart\Assert;

Assert::assertMatchesRegex(
    '/here/',
    'nope nope nope',
    "some message about business results here so you understand why it's important"
);
```

Creating Custom Matchers
------------------------

[](#creating-custom-matchers)

One of the strengths of Counterpart is that it's very easy to create new, custom `Matcher` implementations. Doing so let's you clarify your business logic and create more readable code.

For example: let's say we needed to assert that the value returned from a number between 1 and 100.

This could be done with a `LogicalAnd` matcher and a few other matchers.

```
use Counterpart\Assert;
use Counterpart\Matchers;

Assert::assertThat(
    Matchers::logicalAnd(
        Matchers::isType('integer'),
        Matchers::greaterThanOrEqual(1),
        Matchers::lessThanOrEqual(100)
    )
    $theRealNumber
);
```

There's absolutely nothing wrong with that. It's a bit wordy, especially if you have to write it out a lot. And if you do have to write it a lot, there's a good chance it's because it's part of some core business logic. Maybe you hit an API that only accepts values between 1 and 100.

This is great use case for a custom matcher.

```
use Counterpart\Matcher;
use Counterpart\Assert;

class ValidApiValueMatcher implements Matcher
{
    /**
     * {@inheritdoc}
     */
    public function matches($actual)
    {
        return is_int($actual) && $actual >= 1 && $actual
