diff --git a/tests/.snapshots/success.txt b/tests/.snapshots/success.txt index 1818c459..73cd151e 100644 --- a/tests/.snapshots/success.txt +++ b/tests/.snapshots/success.txt @@ -178,7 +178,12 @@ ✓ not property calls PASS Tests\Features\Expect\pipe - ✓ pass + ✓ pipe is applied and can stop pipeline + ✓ pipe is run and can let the pipeline keep going + ✓ intercept is applied + ✓ intercept stops the pipeline + ✓ interception is called only when filter is met + ✓ intercept can be filtered with a closure PASS Tests\Features\Expect\ray ✓ ray calls do not fail when ray is not installed @@ -723,5 +728,5 @@ ✓ it is a test ✓ it uses correct parent class - Tests: 4 incompleted, 9 skipped, 479 passed + Tests: 4 incompleted, 9 skipped, 484 passed \ No newline at end of file diff --git a/tests/Features/Expect/pipe.php b/tests/Features/Expect/pipe.php index e2c6ac98..1d864f9c 100644 --- a/tests/Features/Expect/pipe.php +++ b/tests/Features/Expect/pipe.php @@ -2,6 +2,7 @@ use function PHPUnit\Framework\assertEquals; use function PHPUnit\Framework\assertInstanceOf; +use function PHPUnit\Framework\assertIsNumeric; class Number { @@ -23,8 +24,54 @@ class Character } } -expect()->pipe('toBe', function ($expected, $next) { +class Symbol +{ + public $value; + + public function __construct($value) + { + $this->value = $value; + } +} + +class State +{ + public $runCount = []; + public $appliedCount = []; + + public function __construct() + { + $this->reset(); + } + + public function reset(): void + { + $this->runCount = [ + 'character' => 0, + 'number' => 0, + 'wildcard' => 0, + 'symbol' => 0, + ]; + + $this->appliedCount = [ + 'character' => 0, + 'number' => 0, + 'wildcard' => 0, + 'symbol' => 0, + ]; + } +} + +$state = new State(); + +/* + * Asserts two Characters are the same + */ +expect()->pipe('toBe', function ($expected, $next) use ($state) { + $state->runCount['character']++; + if ($this->value instanceof Character) { + $state->appliedCount['character']++; assertInstanceOf(Character::class, $expected); assertEquals($this->value->value, $expected->value); @@ -34,16 +81,129 @@ expect()->pipe('toBe', function ($expected, $next) { $next($expected); }); -expect()->intercept('toBe', Number::class, function ($expected) { +/* + * Asserts two Numbers are the same + */ +expect()->intercept('toBe', Number::class, function ($expected) use ($state) { + $state->runCount['number']++; + $state->appliedCount['number']++; assertEquals($this->value->value, $expected->value); }); -test('pass', function () { - $number = new Number(1); +/* + * Asserts all integers are allowed if value is an '*' + */ +expect()->intercept('toBe', function ($value) { + return $value === '*'; +}, function ($expected) use ($state) { + $state->runCount['wildcard']++; + $state->appliedCount['wildcard']++; + assertIsNumeric($expected); +}); +/* + * Asserts two Symbols are the same + */ +expect()->pipe('toBe', function ($expected, $next) use ($state) { + $state->runCount['symbol']++; + + if ($this->value instanceof Symbol) { + $state->appliedCount['symbol']++; + assertInstanceOf(Symbol::class, $expected); + assertEquals($this->value->value, $expected->value); + + return; + } + + $next($expected); +}); + +test('pipe is applied and can stop pipeline', function () use ($state) { $letter = new Character('A'); - expect($number)->toBe(new Number(1)); - expect($letter)->toBe(new Character('A')); - expect(3)->toBe(3); + $state->reset(); + + expect($letter)->toBe(new Character('A')) + ->and($state) + ->runCount->toMatchArray([ + 'character' => 1, + 'number' => 0, + 'wildcard' => 0, + 'symbol' => 0, + ]) + ->appliedCount->toMatchArray([ + 'character' => 1, + 'number' => 0, + 'wildcard' => 0, + 'symbol' => 0, + ]); +}); + +test('pipe is run and can let the pipeline keep going', function () use ($state) { + $state->reset(); + + expect(3)->toBe(3) + ->and($state) + ->runCount->toMatchArray([ + 'character' => 1, + 'number' => 0, + 'wildcard' => 0, + 'symbol' => 1, + ]) + ->appliedCount->toMatchArray([ + 'character' => 0, + 'number' => 0, + 'wildcard' => 0, + 'symbol' => 0, + ]); +}); + +test('intercept is applied', function () use ($state) { + $number = new Number(1); + + $state->reset(); + + expect($number)->toBe(new Number(1)) + ->and($state) + ->runCount->toHaveKey('number', 1) + ->appliedCount->toHaveKey('number', 1); +}); + +test('intercept stops the pipeline', function () use ($state) { + $number = new Number(1); + + $state->reset(); + + expect($number)->toBe(new Number(1)) + ->and($state) + ->runCount->toMatchArray([ + 'character' => 1, + 'number' => 1, + 'wildcard' => 0, + 'symbol' => 0, + ]) + ->appliedCount->toMatchArray([ + 'character' => 0, + 'number' => 1, + 'wildcard' => 0, + 'symbol' => 0, + ]); +}); + +test('interception is called only when filter is met', function () use ($state) { + $state->reset(); + + expect(1)->toBe(1) + ->and($state) + ->runCount->toHaveKey('number', 0) + ->appliedCount->toHaveKey('number', 0); +}); + +test('intercept can be filtered with a closure', function () use ($state) { + $state->reset(); + + expect('*')->toBe(1) + ->and($state) + ->runCount->toHaveKey('wildcard', 1) + ->appliedCount->toHaveKey('wildcard', 1); });