Skip to content

Commit

Permalink
Additional tests to add documentation for possible garbage references
Browse files Browse the repository at this point in the history
  • Loading branch information
clue committed Jun 12, 2018
1 parent ef228a9 commit 86d502e
Showing 1 changed file with 33 additions and 0 deletions.
33 changes: 33 additions & 0 deletions tests/PromiseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,16 @@ public function shouldNotLeaveGarbageCyclesWhenRemovingLastReferenceToPendingPro
$this->assertSame(0, gc_collect_cycles());
}

/** @test */
public function shouldNotLeaveGarbageCyclesWhenRemovingLastReferenceToPendingPromiseWithCanceller()
{
gc_collect_cycles();
$promise = new Promise(function () { }, function () { });
unset($promise);

$this->assertSame(0, gc_collect_cycles());
}

/** @test */
public function shouldNotLeaveGarbageCyclesWhenRemovingLastReferenceToPendingPromiseWithThenFollowers()
{
Expand All @@ -213,6 +223,29 @@ public function shouldNotLeaveGarbageCyclesWhenRemovingLastReferenceToPendingPro
$this->assertSame(0, gc_collect_cycles());
}

/** @test */
public function shouldNotLeaveGarbageCyclesWhenRemovingLastReferenceToPendingPromiseWithCancellerAndThenFollowers()
{
$this->markTestIncomplete('This requires a cyclic dependency by design. You should explicitly cancel() instead of leaving garbage references.');

// Having a cancellation handler and creating a follower creates a cyclic reference by design:
// - $promise holds a reference to $follower to notify when settling
// - $follower holds a reference to $promise to forward cancellation to parent
//
// There are a number of ways to avoid this cyclic reference in consumer code:
// - Ensure the $promise is fulfilled which will clear the reference to its followers
// - Do not create a $follower when it is not needed in the first place
// - Explicitly cancel() $follower when its operation should be cancelled
// - Do not use a cancellation handler when followers are commonly discarded (not recommended)

gc_collect_cycles();
$promise = new Promise(function () { }, function () { });
$promise->then();
unset($promise);

$this->assertSame(0, gc_collect_cycles());
}

/** @test */
public function shouldNotLeaveGarbageCyclesWhenRemovingLastReferenceToPendingPromiseWithDoneFollowers()
{
Expand Down

0 comments on commit 86d502e

Please sign in to comment.