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

Commit

Permalink
Merge pull request #9 from lukeraymonddowning/master
Browse files Browse the repository at this point in the history
Adds a `sequence` method for traversable values
  • Loading branch information
nunomaduro authored May 18, 2021
2 parents 077d4af + 59d1c3e commit c1e2139
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 0 deletions.
31 changes: 31 additions & 0 deletions src/Each.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace Pest\Expectations;

use BadMethodCallException;

/**
* @internal
*
Expand All @@ -29,6 +31,35 @@ 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
41 changes: 41 additions & 0 deletions tests/Expect/sequence.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

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.');

test('allows for sequences of checks to be run on traversable data', function () {
expect([1, 2, 3])
->each
->sequence(
function ($expectation) { $expectation->toBeInt()->toEqual(1); },
function ($expectation) { $expectation->toBeInt()->toEqual(2); },
function ($expectation) { $expectation->toBeInt()->toEqual(3); },
);

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

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); },
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 () {
expect([1, 2])
->each
->sequence(
function ($expectation) { $expectation->toBeInt()->toEqual(1); },
function ($expectation) { $expectation->toBeInt()->toEqual(2); },
function ($expectation) { $expectation->toBeInt()->toEqual(3); },
);

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

0 comments on commit c1e2139

Please sign in to comment.