Skip to content
This repository has been archived by the owner on Jan 11, 2023. It is now read-only.

Commit

Permalink
Merge pull request #27 from robations/hotfix/26
Browse files Browse the repository at this point in the history
Fix problem using IteratorAggregates with skip and take
  • Loading branch information
davidroth committed Mar 1, 2016
2 parents 1bf407e + 4ff746d commit bff72e2
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 12 deletions.
35 changes: 23 additions & 12 deletions src/Fusonic/Linq/Linq.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,17 +91,17 @@ public function where(callable $func)
return new Linq(new WhereIterator($this->iterator, $func));
}

/**
* Filters the Linq object according to type.
*
* @param string $type
*
* @return Linq Filtered results according to $func
*/
public function ofType($type)
{
return new Linq(new OfTypeIterator($this->iterator, $type));
}
/**
* Filters the Linq object according to type.
*
* @param string $type
*
* @return Linq Filtered results according to $func
*/
public function ofType($type)
{
return new Linq(new OfTypeIterator($this->iterator, $type));
}

/**
* Bypasses a specified number of elements and then returns the remaining elements.
Expand All @@ -119,6 +119,11 @@ public function skip($count)
return new Linq([]);
}
}
if (!($innerIterator instanceof \Iterator)) {
// IteratorIterator wraps $innerIterator because it is Traversable but not an Iterator.
// (see https://bugs.php.net/bug.php?id=52280)
$innerIterator = new \IteratorIterator($innerIterator);
}

return new Linq(new \LimitIterator($innerIterator, $count, -1));
}
Expand All @@ -134,8 +139,14 @@ public function take($count)
if ($count == 0) {
return new Linq([]);
}
$innerIterator = $this->iterator;
if (!($innerIterator instanceof \Iterator)) {
// IteratorIterator wraps $this->iterator because it is Traversable but not an Iterator.
// (see https://bugs.php.net/bug.php?id=52280)
$innerIterator = new \IteratorIterator($innerIterator);
}

return new Linq(new \LimitIterator($this->iterator, 0, $count));
return new Linq(new \LimitIterator($innerIterator, 0, $count));
}

/**
Expand Down
19 changes: 19 additions & 0 deletions tests/Fusonic/Linq/Test/SkipTakeTest.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php

require_once("TestBase.php");
require_once(__DIR__ . "/TestIteratorAggregate.php");

use Fusonic\Linq\Linq;

Expand Down Expand Up @@ -112,4 +113,22 @@ public function testTake_TakeValuesByAmount()
$matching = Linq::from($items)->take(0);
$this->assertEquals(0, $matching->count());
}

public function testTake_WithIteratorAggregate()
{
$items = new TestIteratorAggregate(["a", "b", "c", "d", "e", "f"]);
$matching = Linq::from($items)->take(4);

$this->assertTrue($matching instanceof Linq);
$this->assertEquals(4, $matching->count());
}

public function testSkip_WithIteratorAggregate()
{
$items = new TestIteratorAggregate(["a", "b", "c", "d", "e", "f"]);
$matching = Linq::from($items)->skip(2);

$this->assertTrue($matching instanceof Linq);
$this->assertEquals(4, $matching->count());
}
}
17 changes: 17 additions & 0 deletions tests/Fusonic/Linq/Test/TestIteratorAggregate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

/**
* @property array x
*/
class TestIteratorAggregate implements \IteratorAggregate
{
public function __construct(array $x)
{
$this->x = $x;
}

public function getIterator()
{
return new \ArrayIterator($this->x);
}
}

0 comments on commit bff72e2

Please sign in to comment.