1<?php 2 3namespace React\Promise; 4 5use React\Promise\PromiseAdapter\CallbackPromiseAdapter; 6 7class DeferredTest extends TestCase 8{ 9 use PromiseTest\FullTestTrait; 10 11 public function getPromiseTestAdapter(callable $canceller = null) 12 { 13 $d = new Deferred($canceller); 14 15 return new CallbackPromiseAdapter([ 16 'promise' => [$d, 'promise'], 17 'resolve' => [$d, 'resolve'], 18 'reject' => [$d, 'reject'], 19 'notify' => [$d, 'progress'], 20 'settle' => [$d, 'resolve'], 21 ]); 22 } 23 24 /** @test */ 25 public function progressIsAnAliasForNotify() 26 { 27 $deferred = new Deferred(); 28 29 $sentinel = new \stdClass(); 30 31 $mock = $this->createCallableMock(); 32 $mock 33 ->expects($this->once()) 34 ->method('__invoke') 35 ->with($sentinel); 36 37 $deferred->promise() 38 ->then($this->expectCallableNever(), $this->expectCallableNever(), $mock); 39 40 $deferred->progress($sentinel); 41 } 42 43 /** @test */ 44 public function shouldRejectWithoutCreatingGarbageCyclesIfCancellerRejectsWithException() 45 { 46 gc_collect_cycles(); 47 $deferred = new Deferred(function ($resolve, $reject) { 48 $reject(new \Exception('foo')); 49 }); 50 $deferred->promise()->cancel(); 51 unset($deferred); 52 53 $this->assertSame(0, gc_collect_cycles()); 54 } 55 56 /** @test */ 57 public function shouldRejectWithoutCreatingGarbageCyclesIfParentCancellerRejectsWithException() 58 { 59 gc_collect_cycles(); 60 $deferred = new Deferred(function ($resolve, $reject) { 61 $reject(new \Exception('foo')); 62 }); 63 $deferred->promise()->then()->cancel(); 64 unset($deferred); 65 66 $this->assertSame(0, gc_collect_cycles()); 67 } 68 69 /** @test */ 70 public function shouldRejectWithoutCreatingGarbageCyclesIfCancellerHoldsReferenceAndExplicitlyRejectWithException() 71 { 72 gc_collect_cycles(); 73 $deferred = new Deferred(function () use (&$deferred) { }); 74 $deferred->reject(new \Exception('foo')); 75 unset($deferred); 76 77 $this->assertSame(0, gc_collect_cycles()); 78 } 79 80 /** @test */ 81 public function shouldNotLeaveGarbageCyclesWhenRemovingLastReferenceToPendingDeferred() 82 { 83 gc_collect_cycles(); 84 $deferred = new Deferred(); 85 $deferred->promise(); 86 unset($deferred); 87 88 $this->assertSame(0, gc_collect_cycles()); 89 } 90 91 /** @test */ 92 public function shouldNotLeaveGarbageCyclesWhenRemovingLastReferenceToPendingDeferredWithUnusedCanceller() 93 { 94 gc_collect_cycles(); 95 $deferred = new Deferred(function () { }); 96 $deferred->promise(); 97 unset($deferred); 98 99 $this->assertSame(0, gc_collect_cycles()); 100 } 101 102 /** @test */ 103 public function shouldNotLeaveGarbageCyclesWhenRemovingLastReferenceToPendingDeferredWithNoopCanceller() 104 { 105 gc_collect_cycles(); 106 $deferred = new Deferred(function () { }); 107 $deferred->promise()->cancel(); 108 unset($deferred); 109 110 $this->assertSame(0, gc_collect_cycles()); 111 } 112} 113