Skip to content
This repository has been archived by the owner on Jun 16, 2021. It is now read-only.

Commit

Permalink
feat: moves "sequence" to expectation class
Browse files Browse the repository at this point in the history
  • Loading branch information
nunomaduro committed May 18, 2021
1 parent c1e2139 commit 3b89b7d
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 39 deletions.
31 changes: 0 additions & 31 deletions src/Each.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

namespace Pest\Expectations;

use BadMethodCallException;

/**
* @internal
*
Expand All @@ -31,35 +29,6 @@ public function __construct(Expectation $original)
$this->original = $original;
}

/**
* Allows you to specify a sequential set of
* expectations for each item in a
* traversable "value".
*
* @param callable ...$expectations
*/
public function sequence(...$expectations): Each
{
if (!is_iterable($this->original->value)) {
throw new BadMethodCallException('Expectation value is not traversable.');
}

$expectationIndex = 0;

/* @phpstan-ignore-next-line */
while (count($expectations) < count($this->original->value)) {
$expectations[] = $expectations[$expectationIndex];
/* @phpstan-ignore-next-line */
$expectationIndex = $expectationIndex < count($this->original->value) - 1 ? $expectationIndex + 1 : 0;
}

foreach ($this->original->value as $index => $item) {
call_user_func($expectations[$index], expect($item));
}

return $this;
}

/**
* Creates a new expectation.
*
Expand Down
28 changes: 27 additions & 1 deletion src/Expectation.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public function not(): OppositeExpectation
public function each(callable $callback = null): Each
{
if (!is_iterable($this->value)) {
throw new BadMethodCallException('Expectation value is not traversable.');
throw new BadMethodCallException('Expectation value is not iterable.');
}

if (is_callable($callback)) {
Expand All @@ -84,6 +84,32 @@ public function each(callable $callback = null): Each
return new Each($this);
}

/**
* Allows you to specify a sequential set of expectations for each item in a iterable "value".
*/
public function sequence(callable ...$callbacks): Expectation
{
if (!is_iterable($this->value)) {
throw new BadMethodCallException('Expectation value is not iterable.');
}

$index = 0;

/* @phpstan-ignore-next-line */
while (count($callbacks) < count($this->value)) {
$callbacks[] = $callbacks[$index];
/* @phpstan-ignore-next-line */
$index = $index < count($this->value) - 1 ? $index + 1 : 0;
}

/* @phpstan-ignore-next-line */
foreach ($this->value as $index => $item) {
call_user_func($callbacks[$index], expect($item));
}

return $this;
}

/**
* Asserts that two variables have the same type and
* value. Used on objects, it asserts that two
Expand Down
2 changes: 1 addition & 1 deletion tests/Expect/each.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

test('an exception is thrown if the the type is not iterable', function () {
expect('Foobar')->each()->toEqual('Foobar');
})->throws(BadMethodCallException::class, 'Expectation value is not traversable.');
})->throws(BadMethodCallException::class, 'Expectation value is not iterable.');

it('expects on each item', function () {
expect([1, 1, 1])
Expand Down
9 changes: 3 additions & 6 deletions tests/Expect/sequence.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@

test('an exception is thrown if the the type is not iterable', function () {
expect('Foobar')->each->sequence();
})->throws(BadMethodCallException::class, 'Expectation value is not traversable.');
})->throws(BadMethodCallException::class, 'Expectation value is not iterable.');

test('allows for sequences of checks to be run on traversable data', function () {
test('allows for sequences of checks to be run on iterable data', function () {
expect([1, 2, 3])
->each
->sequence(
function ($expectation) { $expectation->toBeInt()->toEqual(1); },
function ($expectation) { $expectation->toBeInt()->toEqual(2); },
Expand All @@ -18,7 +17,6 @@ function ($expectation) { $expectation->toBeInt()->toEqual(3); },

test('loops back to the start if it runs out of sequence items', function () {
expect([1, 2, 3, 1, 2, 3, 1, 2])
->each
->sequence(
function ($expectation) { $expectation->toBeInt()->toEqual(1); },
function ($expectation) { $expectation->toBeInt()->toEqual(2); },
Expand All @@ -28,9 +26,8 @@ function ($expectation) { $expectation->toBeInt()->toEqual(3); },
expect(static::getCount())->toBe(16);
});

test('it works if the number of items in the traversable is smaller than the number of expectations', function () {
test('it works if the number of items in the iterable is smaller than the number of expectations', function () {
expect([1, 2])
->each
->sequence(
function ($expectation) { $expectation->toBeInt()->toEqual(1); },
function ($expectation) { $expectation->toBeInt()->toEqual(2); },
Expand Down

0 comments on commit 3b89b7d

Please sign in to comment.