| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352 |
- <?php
- namespace think\tests;
- use Closure;
- use Exception;
- use PHPUnit\Framework\TestCase;
- use think\Pipeline;
- class PipelineTest extends TestCase
- {
- protected $pipeline;
- protected function setUp(): void
- {
- $this->pipeline = new Pipeline();
- }
- public function testSend()
- {
- $data = 'test data';
- $result = $this->pipeline->send($data);
-
- $this->assertSame($this->pipeline, $result);
- }
- public function testThroughWithArray()
- {
- $pipes = [
- function ($passable, $next) {
- return $next($passable . ' pipe1');
- },
- function ($passable, $next) {
- return $next($passable . ' pipe2');
- }
- ];
-
- $result = $this->pipeline->through($pipes);
-
- $this->assertSame($this->pipeline, $result);
- }
- public function testThroughWithArguments()
- {
- $pipe1 = function ($passable, $next) {
- return $next($passable . ' pipe1');
- };
- $pipe2 = function ($passable, $next) {
- return $next($passable . ' pipe2');
- };
-
- $result = $this->pipeline->through($pipe1, $pipe2);
-
- $this->assertSame($this->pipeline, $result);
- }
- public function testThenExecutesPipeline()
- {
- $pipes = [
- function ($passable, $next) {
- return $next($passable . ' pipe1');
- },
- function ($passable, $next) {
- return $next($passable . ' pipe2');
- }
- ];
-
- $destination = function ($passable) {
- return $passable . ' destination';
- };
-
- $result = $this->pipeline
- ->send('start')
- ->through($pipes)
- ->then($destination);
-
- $this->assertEquals('start pipe1 pipe2 destination', $result);
- }
- public function testPipelineExecutesInCorrectOrder()
- {
- $order = [];
-
- $pipes = [
- function ($passable, $next) use (&$order) {
- $order[] = 'pipe1_before';
- $result = $next($passable);
- $order[] = 'pipe1_after';
- return $result;
- },
- function ($passable, $next) use (&$order) {
- $order[] = 'pipe2_before';
- $result = $next($passable);
- $order[] = 'pipe2_after';
- return $result;
- }
- ];
-
- $destination = function ($passable) use (&$order) {
- $order[] = 'destination';
- return $passable;
- };
-
- $this->pipeline
- ->send('test')
- ->through($pipes)
- ->then($destination);
-
- $expected = ['pipe1_before', 'pipe2_before', 'destination', 'pipe2_after', 'pipe1_after'];
- $this->assertEquals($expected, $order);
- }
- public function testEmptyPipelineExecutesDestination()
- {
- $destination = function ($passable) {
- return $passable . ' processed';
- };
-
- $result = $this->pipeline
- ->send('test')
- ->through([])
- ->then($destination);
-
- $this->assertEquals('test processed', $result);
- }
- public function testPipelineCanModifyData()
- {
- $pipes = [
- function ($passable, $next) {
- $passable['pipe1'] = true;
- return $next($passable);
- },
- function ($passable, $next) {
- $passable['pipe2'] = true;
- return $next($passable);
- }
- ];
-
- $destination = function ($passable) {
- $passable['destination'] = true;
- return $passable;
- };
-
- $result = $this->pipeline
- ->send([])
- ->through($pipes)
- ->then($destination);
-
- $expected = [
- 'pipe1' => true,
- 'pipe2' => true,
- 'destination' => true
- ];
- $this->assertEquals($expected, $result);
- }
- public function testPipelineCanShortCircuit()
- {
- $pipes = [
- function ($passable, $next) {
- if ($passable === 'stop') {
- return 'stopped';
- }
- return $next($passable);
- },
- function ($passable, $next) {
- return $next($passable . ' pipe2');
- }
- ];
-
- $destination = function ($passable) {
- return $passable . ' destination';
- };
-
- $result = $this->pipeline
- ->send('stop')
- ->through($pipes)
- ->then($destination);
-
- $this->assertEquals('stopped', $result);
- }
- public function testExceptionInDestinationIsHandled()
- {
- $pipes = [
- function ($passable, $next) {
- return $next($passable);
- }
- ];
-
- $destination = function ($passable) {
- throw new Exception('Destination error');
- };
-
- $this->expectException(Exception::class);
- $this->expectExceptionMessage('Destination error');
-
- $this->pipeline
- ->send('test')
- ->through($pipes)
- ->then($destination);
- }
- public function testExceptionInPipeIsHandled()
- {
- $pipes = [
- function ($passable, $next) {
- throw new Exception('Pipe error');
- }
- ];
-
- $destination = function ($passable) {
- return $passable;
- };
-
- $this->expectException(Exception::class);
- $this->expectExceptionMessage('Pipe error');
-
- $this->pipeline
- ->send('test')
- ->through($pipes)
- ->then($destination);
- }
- public function testWhenExceptionSetsHandler()
- {
- $result = $this->pipeline->whenException(function ($passable, $e) {
- return 'handled';
- });
-
- $this->assertSame($this->pipeline, $result);
- }
- public function testExceptionHandlerIsCalledOnException()
- {
- $pipes = [
- function ($passable, $next) {
- throw new Exception('Test exception');
- }
- ];
-
- $destination = function ($passable) {
- return $passable;
- };
-
- $result = $this->pipeline
- ->send('test')
- ->through($pipes)
- ->whenException(function ($passable, $e) {
- return 'handled: ' . $e->getMessage();
- })
- ->then($destination);
-
- $this->assertEquals('handled: Test exception', $result);
- }
- public function testExceptionHandlerReceivesCorrectParameters()
- {
- $pipes = [
- function ($passable, $next) {
- throw new Exception('Test exception');
- }
- ];
-
- $destination = function ($passable) {
- return $passable;
- };
-
- $handlerCalled = false;
- $receivedPassable = null;
- $receivedException = null;
-
- $this->pipeline
- ->send('original data')
- ->through($pipes)
- ->whenException(function ($passable, $e) use (&$handlerCalled, &$receivedPassable, &$receivedException) {
- $handlerCalled = true;
- $receivedPassable = $passable;
- $receivedException = $e;
- return 'handled';
- })
- ->then($destination);
-
- $this->assertTrue($handlerCalled);
- $this->assertEquals('original data', $receivedPassable);
- $this->assertInstanceOf(Exception::class, $receivedException);
- $this->assertEquals('Test exception', $receivedException->getMessage());
- }
- public function testExceptionInDestinationWithHandler()
- {
- $destination = function ($passable) {
- throw new Exception('Destination exception');
- };
-
- $result = $this->pipeline
- ->send('test')
- ->through([])
- ->whenException(function ($passable, $e) {
- return 'destination handled: ' . $e->getMessage();
- })
- ->then($destination);
-
- $this->assertEquals('destination handled: Destination exception', $result);
- }
- public function testComplexPipelineWithExceptions()
- {
- $pipes = [
- function ($passable, $next) {
- $passable[] = 'pipe1';
- return $next($passable);
- },
- function ($passable, $next) {
- if (in_array('error', $passable)) {
- throw new Exception('Pipe2 error');
- }
- $passable[] = 'pipe2';
- return $next($passable);
- },
- function ($passable, $next) {
- $passable[] = 'pipe3';
- return $next($passable);
- }
- ];
-
- $destination = function ($passable) {
- $passable[] = 'destination';
- return $passable;
- };
-
- // Normal execution
- $result1 = $this->pipeline
- ->send(['start'])
- ->through($pipes)
- ->then($destination);
-
- $this->assertEquals(['start', 'pipe1', 'pipe2', 'pipe3', 'destination'], $result1);
-
- // With exception handling
- $result2 = $this->pipeline
- ->send(['start', 'error'])
- ->through($pipes)
- ->whenException(function ($passable, $e) {
- return ['error_handled', $e->getMessage()];
- })
- ->then($destination);
-
- $this->assertEquals(['error_handled', 'Pipe2 error'], $result2);
- }
- }
|