Merge pull request #399 from mertasan/sequence

Fix: `sequence()` can generate false positives
This commit is contained in:
Nuno Maduro
2021-09-24 22:15:49 +01:00
committed by GitHub
3 changed files with 13 additions and 8 deletions

View File

@ -154,9 +154,10 @@ final class Expectation
throw new BadMethodCallException('Expectation value is not iterable.');
}
$value = is_array($this->value) ? $this->value : iterator_to_array($this->value);
$keys = array_keys($value);
$values = array_values($value);
$value = is_array($this->value) ? $this->value : iterator_to_array($this->value);
$keys = array_keys($value);
$values = array_values($value);
$callbacksCount = count($callbacks);
$index = 0;
@ -165,6 +166,10 @@ final class Expectation
$index = $index < count($values) - 1 ? $index + 1 : 0;
}
if ($callbacksCount > count($values)) {
Assert::assertLessThanOrEqual(count($value), count($callbacks));
}
foreach ($values as $key => $item) {
if (is_callable($callbacks[$key])) {
call_user_func($callbacks[$key], new self($item), new self($keys[$key]));

View File

@ -184,7 +184,7 @@
✓ an exception is thrown if the the type is not iterable
✓ allows for sequences of checks to be run on iterable data
✓ loops back to the start if it runs out of sequence items
it works if the number of items in the iterable is smaller than the number of expectations
fails if the number of iterable items is greater than the number of expectations
✓ it works with associative arrays
✓ it can be passed non-callable values
✓ it can be passed a mixture of value types

View File

@ -1,5 +1,7 @@
<?php
use PHPUnit\Framework\ExpectationFailedException;
test('an exception is thrown if the the type is not iterable', function () {
expect('Foobar')->each->sequence();
})->throws(BadMethodCallException::class, 'Expectation value is not iterable.');
@ -26,16 +28,14 @@ test('loops back to the start if it runs out of sequence items', function () {
expect(static::getCount())->toBe(16);
});
test('it works if the number of items in the iterable is smaller than the number of expectations', function () {
test('fails if the number of iterable items is greater than the number of expectations', function () {
expect([1, 2])
->sequence(
function ($expectation) { $expectation->toBeInt()->toEqual(1); },
function ($expectation) { $expectation->toBeInt()->toEqual(2); },
function ($expectation) { $expectation->toBeInt()->toEqual(3); },
);
expect(static::getCount())->toBe(4);
});
})->throws(ExpectationFailedException::class);
test('it works with associative arrays', function () {
expect(['foo' => 'bar', 'baz' => 'boom'])