Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
sanmai committed Nov 7, 2022
1 parent 0d3f3ae commit bc7e7ca
Show file tree
Hide file tree
Showing 4 changed files with 216 additions and 6 deletions.
40 changes: 38 additions & 2 deletions src/Standard.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
use function array_slice;
use function array_values;
use ArrayIterator;
use function assert;
use CallbackFilterIterator;
use function count;
use Countable;
Expand Down Expand Up @@ -73,42 +74,73 @@ public function __construct(iterable $input = null)
$this->pipeline = $input;
}

/**
* Appends the contents of an interable to the end of the pipeline.
*
* @param ?iterable $values
*/
public function append(iterable $values = null): self
{
// Do we need to do anything here?
if ($this->willReplace($values)) {
return $this;
}

// Static analyzer hints
assert(null !== $this->pipeline);
assert(null !== $values);

return $this->join($this->pipeline, $values);
}

/**
* Appends a list of values to the end of the pipeline.
*
* @param mixed ...$vector
*/
public function push(...$vector): self
{
return $this->append($vector);
}

/**
* Prepends the pipeline with the contents of an iterable.
*
* @param ?iterable $values
*/
public function prepend(iterable $values = null): self
{
// Do we need to do anything here?
if ($this->willReplace($values)) {
return $this;
}

// Static analyzer hints
assert(null !== $this->pipeline);
assert(null !== $values);

return $this->join($values, $this->pipeline);
}

/**
* Prepends the pipeline with a list of values.
*
* @param mixed ...$vector
*/
public function unshift(...$vector): self
{
return $this->prepend($vector);
}

/**
* Determine if the internal pipeline will be replaced when appending/prepending.
*
* Utility method for appending/prepending methods.
*/
private function willReplace(iterable $values = null): bool
{
// Nothing needs to be done here.
/** @phan-suppress-next-line PhanTypeComparisonFromArray */
if (null === $values || [] === $values) {
return true;
}
Expand All @@ -132,6 +164,8 @@ private function willReplace(iterable $values = null): bool
}

/**
* Replace the internal pipeline with a combination of two non-empty iterables.
*
* Utility method for appending/prepending methods.
*/
private function join(iterable $left, iterable $right): self
Expand All @@ -144,10 +178,12 @@ private function join(iterable $left, iterable $right): self
}

// Last, join the hard way.
return $this->map(function () use ($left, $right) {
$this->pipeline = (static function () use ($left, $right) {
yield from $left;
yield from $right;
});
})();

return $this;
}

/**
Expand Down
3 changes: 3 additions & 0 deletions src/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ function fromArray(array $input): Standard
return new Standard($input);
}

/**
* @param mixed ...$values
*/
function fromValues(...$values): Standard
{
return new Standard($values);
Expand Down
169 changes: 169 additions & 0 deletions tests/AppendPrependTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
<?php
/**
* Copyright 2017, 2018 Alexey Kopytko <alexey@kopytko.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

declare(strict_types=1);

namespace Tests\Pipeline;

use ArrayIterator;
use function count;
use function is_numeric;
use function key;
use PHPUnit\Framework\TestCase;
use function Pipeline\take;

/**
* @covers \Pipeline\Standard
*
* @internal
*/
final class AppendPrependTest extends TestCase
{
private function generateIterableCombinations(array $arrays): iterable
{
yield $arrays;

$iterableInput = $arrays;
$iterableInput[1] = new ArrayIterator($iterableInput[1] ?? []);

yield $iterableInput;

$iterableSubjects = $arrays;

for ($i = 2; $i < count($iterableSubjects); ++$i) {
$iterableSubjects[$i] = new ArrayIterator($iterableSubjects[$i] ?? []);
}

yield $iterableSubjects;
}

public function provideAppendArrays(): iterable
{
yield [[1, 2, 3, 4, 5], [1, 2, 3], [4, 5]];

yield [[1, 2, 3, 4, 5], [1, 2, 3], [4], [5]];

yield [[1, 2, 3, 4, 5], [1, 2], [3, 4], [5]];

yield [[1, 2, 3, 4, 5], [], [1, 2, 3, 4], [5]];

yield [[1, 2, 3, 4, 5], null, [1, 2, 3, 4], [5]];

yield [[1, 2, 3, 4, 5], [], [1, 2, 3, 4, 5], [], null];

yield [['a', 'b'], ['a'], ['discard' => 'b']];

yield [['a' => 'a', 'bb' => 'b'], ['a' => 'a'], ['bb' => 'b']];
}

/**
* @dataProvider provideAppendArrays
*/
public function testPush(array $expected, ?array $initialValue, ...$iterables): void
{
$pipeline = take($initialValue);

foreach ($iterables as $iterable) {
$pipeline->push(...$iterable ?? []);
}

$useKeys = !is_numeric(key($expected));
$this->assertSame($expected, $pipeline->toArray($useKeys));
}

public function provideAppend(): iterable
{
foreach ($this->provideAppendArrays() as $arrays) {
foreach ($this->generateIterableCombinations($arrays) as $sample) {
yield $sample;
}
}
}

/**
* @dataProvider provideAppend
*/
public function testAppend(array $expected, ?iterable $initialValue, ...$iterables): void
{
$pipeline = take($initialValue);

foreach ($iterables as $iterable) {
$pipeline->append($iterable);
}

$useKeys = !is_numeric(key($expected));
$this->assertSame($expected, $pipeline->toArray($useKeys));
}

public function providePrependArrays(): iterable
{
yield [[1, 2, 3, 4, 5], [4, 5], [1, 2, 3]];

yield [[1, 2, 3, 4, 5], [5], [4], [1, 2, 3]];

yield [[1, 2, 3, 4, 5], [5], [3, 4], [1, 2]];

yield [[1, 2, 3, 4, 5], [], [5], [1, 2, 3, 4]];

yield [[1, 2, 3, 4, 5], null, [5], [1, 2, 3, 4]];

yield [[1, 2, 3, 4, 5], [], [1, 2, 3, 4, 5], [], null];

yield [['b', 'a'], ['a'], ['discard' => 'b']];

yield [['bb' => 'b', 'a' => 'a'], ['a' => 'a'], ['bb' => 'b']];
}

/**
* @dataProvider providePrependArrays
*/
public function testUnshift(array $expected, ?array $initialValue, ...$iterables): void
{
$pipeline = take($initialValue);

foreach ($iterables as $iterable) {
$pipeline->unshift(...$iterable ?? []);
}

$useKeys = !is_numeric(key($expected));
$this->assertSame($expected, $pipeline->toArray($useKeys));
}

public function providePrepend(): iterable
{
foreach ($this->providePrependArrays() as $arrays) {
foreach ($this->generateIterableCombinations($arrays) as $sample) {
yield $sample;
}
}
}

/**
* @dataProvider providePrepend
*/
public function testPrepend(array $expected, ?iterable $initialValue, ...$iterables): void
{
$pipeline = take($initialValue);

foreach ($iterables as $iterable) {
$pipeline->prepend($iterable);
}

$useKeys = !is_numeric(key($expected));
$this->assertSame($expected, $pipeline->toArray($useKeys));
}
}
10 changes: 6 additions & 4 deletions tests/LazinessTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,14 @@ private function yieldFail(): bool

public function testEagerReturn(): void
{
$this->expectException(Exception::class);

$pipeline = new Standard();
$pipeline->map(function (): void {

$exception = new Exception();
$this->expectExceptionObject($exception);

$pipeline->map(function () use ($exception): void {
// Executed on spot
throw new Exception();
throw $exception;
});
}

Expand Down

0 comments on commit bc7e7ca

Please sign in to comment.