Skip to content

Commit

Permalink
Merge pull request #407 from mertasan/method-match
Browse files Browse the repository at this point in the history
Adds new `match()` method
  • Loading branch information
nunomaduro authored Sep 24, 2021
2 parents 4daf7ee + f0ddd10 commit dc12419
Show file tree
Hide file tree
Showing 3 changed files with 204 additions and 0 deletions.
43 changes: 43 additions & 0 deletions src/Expectation.php
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,49 @@ public function sequence(...$callbacks): Expectation
return $this;
}

/**
* If the subject matches one of the expressions, the callback in the expression is run.
*
* @template TMatchValue
*
* @param Closure|bool|string $subject
* @param array<mixed, callable(self): void|TMatchValue> $expressions
*
* @return \Pest\Expectation
*/
public function match($subject, array $expressions): Expectation
{
$subject = is_callable($subject)
? $subject
: function () use ($subject) {
return $subject;
};

$subject = $subject();
$keys = array_keys($expressions);

if (in_array($subject, ['0', '1', false, true], true)) {
$subject = (int) $subject;
}

foreach ($expressions as $key => $callback) {
if ($subject !== $key) {
continue;
}

if (is_callable($callback)) {
$callback(new self($this->value));
continue;
}

$this->and($this->value)->toEqual($callback);

break;
}

return $this;
}

/**
* Apply the callback if the given "condition" is truthy.
*
Expand Down
11 changes: 11 additions & 0 deletions tests/.snapshots/success.txt
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,17 @@
✓ it properly parses json string
✓ fails with broken json string

PASS Tests\Features\Expect\matchExpectation
✓ it pass
✓ it failures
✓ it runs with truthy
✓ it runs with falsy
✓ it runs with truthy closure condition
✓ it runs with falsy closure condition
✓ it can be passed non-callable values
✓ it passes with empty data
✓ it can be used in higher order tests

PASS Tests\Features\Expect\not
✓ not property calls

Expand Down
150 changes: 150 additions & 0 deletions tests/Features/Expect/matchExpectation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
<?php

use PHPUnit\Framework\ExpectationFailedException;

beforeEach(function () {
$this->matched = null;
});

it('pass', function () {
expect('baz')
->match('foo', [
'bar' => function ($value) {
$this->matched = 'bar';

return $value->toEqual('bar');
},
'foo' => function ($value) {
$this->matched = 'baz';

return $value->toEqual('baz');
},
]
)
->toEqual($this->matched);

expect(static::getCount())->toBe(2);
});

it('failures', function () {
expect(true)
->match('foo', [
'bar' => function ($value) {
return $value->toBeTrue();
},
'foo' => function ($value) {
return $value->toBeFalse();
},
]
);
})->throws(ExpectationFailedException::class, 'true is false');

it('runs with truthy', function () {
expect('foo')
->match(1, [
'bar' => function ($value) {
$this->matched = 'bar';

return $value->toEqual('bar');
},
true => function ($value) {
$this->matched = 'foo';

return $value->toEqual('foo');
},
]
)
->toEqual($this->matched);

expect(static::getCount())->toBe(2);
});

it('runs with falsy', function () {
expect('foo')
->match(false, [
'bar' => function ($value) {
$this->matched = 'bar';

return $value->toEqual('bar');
},
false => function ($value) {
$this->matched = 'foo';

return $value->toEqual('foo');
},
]
)
->toEqual($this->matched);

expect(static::getCount())->toBe(2);
});

it('runs with truthy closure condition', function () {
expect('foo')
->match(
function () { return '1'; }, [
'bar' => function ($value) {
$this->matched = 'bar';

return $value->toEqual('bar');
},
true => function ($value) {
$this->matched = 'foo';

return $value->toEqual('foo');
},
]
)
->toEqual($this->matched);

expect(static::getCount())->toBe(2);
});

it('runs with falsy closure condition', function () {
expect('foo')
->match(
function () { return '0'; }, [
'bar' => function ($value) {
$this->matched = 'bar';

return $value->toEqual('bar');
},
false => function ($value) {
$this->matched = 'foo';

return $value->toEqual('foo');
},
]
)
->toEqual($this->matched);

expect(static::getCount())->toBe(2);
});

it('can be passed non-callable values', function () {
expect('foo')
->match('pest', [
'bar' => 'foo',
'pest' => 'baz',
]
);
})->throws(ExpectationFailedException::class, 'two strings are equal');

it('passes with empty data', function () {
expect('foo')
->match('bar', [])
->toEqual('foo');
});

it('can be used in higher order tests')
->expect(true)
->match(
function () { return true; }, [
false => function ($value) {
return $value->toBeFalse();
},
true => function ($value) {
return $value->toBeTrue();
},
]
);

0 comments on commit dc12419

Please sign in to comment.