Skip to content

Commit

Permalink
[8.x] Add tests for LazyCollection constructor laziness (#36846)
Browse files Browse the repository at this point in the history
* Move enumeration counting to trait

* Add tests for `LazyCollection` constructor laziness
  • Loading branch information
JosephSilber authored Apr 1, 2021
1 parent b92d7b9 commit 79ffd4c
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 73 deletions.
97 changes: 97 additions & 0 deletions tests/Support/Concerns/CountsEnumerations.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?php

namespace Illuminate\Tests\Support\Concerns;

use Illuminate\Support\Collection;
use Illuminate\Support\LazyCollection;

trait CountsEnumerations
{
protected function makeGeneratorFunctionWithRecorder($numbers = 10)
{
$recorder = new Collection();

$generatorFunction = function () use ($numbers, $recorder) {
for ($i = 1; $i <= $numbers; $i++) {
$recorder->push($i);

yield $i;
}
};

return [$generatorFunction, $recorder];
}

protected function assertDoesNotEnumerate(callable $executor)
{
$this->assertEnumerates(0, $executor);
}

protected function assertDoesNotEnumerateCollection(
LazyCollection $collection,
callable $executor
) {
$this->assertEnumeratesCollection($collection, 0, $executor);
}

protected function assertEnumerates($count, callable $executor)
{
$this->assertEnumeratesCollection(
LazyCollection::times(100),
$count,
$executor
);
}

protected function assertEnumeratesCollection(
LazyCollection $collection,
$count,
callable $executor
) {
$enumerated = 0;

$data = $this->countEnumerations($collection, $enumerated);

$executor($data);

$this->assertEnumerations($count, $enumerated);
}

protected function assertEnumeratesOnce(callable $executor)
{
$this->assertEnumeratesCollectionOnce(LazyCollection::times(10), $executor);
}

protected function assertEnumeratesCollectionOnce(
LazyCollection $collection,
callable $executor
) {
$enumerated = 0;
$count = $collection->count();
$collection = $this->countEnumerations($collection, $enumerated);

$executor($collection);

$this->assertEquals(
$count,
$enumerated,
$count > $enumerated ? 'Failed to enumerate in full.' : 'Enumerated more than once.'
);
}

protected function assertEnumerations($expected, $actual)
{
$this->assertEquals(
$expected,
$actual,
"Failed asserting that {$actual} items that were enumerated matches expected {$expected}."
);
}

protected function countEnumerations(LazyCollection $collection, &$count)
{
return $collection->tapEach(function () use (&$count) {
$count++;
});
}
}
100 changes: 27 additions & 73 deletions tests/Support/SupportLazyCollectionIsLazyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,33 @@

class SupportLazyCollectionIsLazyTest extends TestCase
{
use Concerns\CountsEnumerations;

public function testMakeWithClosureIsLazy()
{
[$closure, $recorder] = $this->makeGeneratorFunctionWithRecorder();

LazyCollection::make($closure);

$this->assertEquals([], $recorder->all());
}

public function testMakeWithLazyCollectionIsLazy()
{
$this->assertDoesNotEnumerate(function ($collection) {
LazyCollection::make($collection);
});
}

public function testMakeWithGeneratorIsNotLazy()
{
[$closure, $recorder] = $this->makeGeneratorFunctionWithRecorder(5);

LazyCollection::make($closure());

$this->assertEquals([1, 2, 3, 4, 5], $recorder->all());
}

public function testEagerEnumeratesOnce()
{
$this->assertEnumeratesOnce(function ($collection) {
Expand Down Expand Up @@ -1446,77 +1473,4 @@ protected function make($source)
{
return new LazyCollection($source);
}

protected function assertDoesNotEnumerate(callable $executor)
{
$this->assertEnumerates(0, $executor);
}

protected function assertDoesNotEnumerateCollection(
LazyCollection $collection,
callable $executor
) {
$this->assertEnumeratesCollection($collection, 0, $executor);
}

protected function assertEnumerates($count, callable $executor)
{
$this->assertEnumeratesCollection(
LazyCollection::times(100),
$count,
$executor
);
}

protected function assertEnumeratesCollection(
LazyCollection $collection,
$count,
callable $executor
) {
$enumerated = 0;

$data = $this->countEnumerations($collection, $enumerated);

$executor($data);

$this->assertEnumerations($count, $enumerated);
}

protected function assertEnumeratesOnce(callable $executor)
{
$this->assertEnumeratesCollectionOnce(LazyCollection::times(10), $executor);
}

protected function assertEnumeratesCollectionOnce(
LazyCollection $collection,
callable $executor
) {
$enumerated = 0;
$count = $collection->count();
$collection = $this->countEnumerations($collection, $enumerated);

$executor($collection);

$this->assertEquals(
$count,
$enumerated,
$count > $enumerated ? 'Failed to enumerate in full.' : 'Enumerated more than once.'
);
}

protected function assertEnumerations($expected, $actual)
{
$this->assertEquals(
$expected,
$actual,
"Failed asserting that {$actual} items that were enumerated matches expected {$expected}."
);
}

protected function countEnumerations(LazyCollection $collection, &$count)
{
return $collection->tapEach(function () use (&$count) {
$count++;
});
}
}

0 comments on commit 79ffd4c

Please sign in to comment.