Skip to content

Commit

Permalink
Merge pull request #50 from KnpLabs/iterator
Browse files Browse the repository at this point in the history
Iterator
  • Loading branch information
stof committed May 8, 2012
2 parents 582abde + 2e16c50 commit d7eb547
Show file tree
Hide file tree
Showing 7 changed files with 199 additions and 94 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
## 1.1.0 (2012-XX-XX)

* Added a filter iterator keeping only current items
* Made the iterator recursive for the item
* Fixed building an array of breadcrumbs when a label has only digits
* Added a way to mark a label as safe
* Refactored the ListRenderer to be consistent with the TwigRenderer and provide the same extension points
Expand Down
14 changes: 14 additions & 0 deletions src/Knp/Menu/Iterator/CurrentItemFilterIterator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace Knp\Menu\Iterator;

/**
* Filter iterator keeping only curent items
*/
class CurrentItemFilterIterator extends \FilterIterator
{
public function accept()
{
return $this->current()->isCurrent();
}
}
21 changes: 21 additions & 0 deletions src/Knp/Menu/Iterator/ItemIterator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace Knp\Menu\Iterator;

/**
* Recursive iterator iterating on an item
*/
class ItemIterator extends \ArrayIterator implements \RecursiveIterator
{
public function hasChildren()
{
$current = $this->current();

return $current->getIterator() instanceof \RecursiveIterator && 0 < count($current);
}

public function getChildren()
{
return $this->current()->getIterator();
}
}
3 changes: 2 additions & 1 deletion src/Knp/Menu/MenuItem.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Knp\Menu;

use Knp\Menu\Iterator\ItemIterator;
use Knp\Menu\Renderer\RendererInterface;
use Knp\Menu\Renderer\ListRenderer;

Expand Down Expand Up @@ -1116,7 +1117,7 @@ public function count()
*/
public function getIterator()
{
return new \ArrayIterator($this->children);
return new ItemIterator($this->children);
}

/**
Expand Down
66 changes: 66 additions & 0 deletions tests/Knp/Menu/Tests/Iterator/IteratorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

namespace Knp\Menu\Tests\Iterator;

use Knp\Menu\Iterator\CurrentItemFilterIterator;
use Knp\Menu\Tests\TestCase;

class IteratorTest extends TestCase
{
public function testIterator()
{
$count = 0;
foreach ($this->pt1 as $key => $value) {
$count++;
$this->assertEquals('Child '.$count, $key);
$this->assertEquals('Child '.$count, $value->getLabel());
}
}

public function testRecursiveIterator()
{
// Adding an item which does not provide a RecursiveIterator to be sure it works properly.
$child = $this->getMock('Knp\Menu\ItemInterface');
$child->expects($this->any())
->method('getName')
->will($this->returnValue('Foo'));
$child->expects($this->any())
->method('getIterator')
->will($this->returnValue(new \EmptyIterator()));
$this->menu->addChild($child);

$names = array();
foreach (new \RecursiveIteratorIterator($this->menu, \RecursiveIteratorIterator::SELF_FIRST) as $value) {
$names[] = $value->getName();
}

$this->assertEquals(array('Parent 1', 'Child 1', 'Child 2', 'Child 3', 'Parent 2', 'Child 4', 'Grandchild 1', 'Foo'), $names);
}

public function testRecursiveIteratorLeavesOnly()
{
$names = array();
foreach (new \RecursiveIteratorIterator($this->menu, \RecursiveIteratorIterator::LEAVES_ONLY) as $value) {
$names[] = $value->getName();
}

$this->assertEquals(array('Child 1', 'Child 2', 'Child 3', 'Grandchild 1'), $names);
}

public function testFilterIterator()
{
$this->pt1->setCurrent(true);
$this->ch2->setCurrent(true);
$this->gc1->setCurrent(true);

$names = array();
$iterator = new CurrentItemFilterIterator(
new \RecursiveIteratorIterator($this->menu, \RecursiveIteratorIterator::SELF_FIRST)
);
foreach ($iterator as $value) {
$names[] = $value->getName();
}

$this->assertEquals(array('Parent 1', 'Child 2', 'Grandchild 1'), $names);
}
}
95 changes: 2 additions & 93 deletions tests/Knp/Menu/Tests/MenuItemTreeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,82 +2,14 @@

namespace Knp\Menu\Tests;

use Knp\Menu\Iterator\CurrentItemFilterIterator;
use Knp\Menu\MenuItem;
use Knp\Menu\MenuFactory;

class TestMenuItem extends MenuItem {}

class MenuItemTreeTest extends \PHPUnit_Framework_TestCase
class MenuItemTreeTest extends TestCase
{
/**
* @var \Knp\Menu\MenuItem
*/
private $menu;

/**
* @var \Knp\Menu\MenuItem
*/
private $pt1;

/**
* @var \Knp\Menu\MenuItem
*/
private $ch1;

/**
* @var \Knp\Menu\MenuItem
*/
private $ch2;

/**
* @var \Knp\Menu\MenuItem
*/
private $ch3;

/**
* @var \Knp\Menu\MenuItem
*/
private $pt2;

/**
* @var \Knp\Menu\MenuItem
*/
private $ch4;

/**
* @var \Knp\Menu\MenuItem
*/
private $gc1;

public function setUp()
{
$factory = new MenuFactory();
$this->menu = $factory->createItem('Root li', array('attributes' => array('class' => 'root')));
$this->pt1 = $this->menu->addChild('Parent 1');
$this->ch1 = $this->pt1->addChild('Child 1');
$this->ch2 = $this->pt1->addChild('Child 2');

// add the 3rd child via addChild with an object
$this->ch3 = new MenuItem('Child 3', $factory);
$this->pt1->addChild($this->ch3);

$this->pt2 = $this->menu->addChild('Parent 2');
$this->ch4 = $this->pt2->addChild('Child 4');
$this->gc1 = $this->ch4->addChild('Grandchild 1');
}

public function tearDown()
{
$this->menu = null;
$this->pt1 = null;
$this->ch1 = null;
$this->ch2 = null;
$this->ch3 = null;
$this->pt2 = null;
$this->ch4 = null;
$this->gc1 = null;
}

public function testSampleTreeIntegrity()
{
$this->assertCount(2, $this->menu);
Expand Down Expand Up @@ -210,16 +142,6 @@ public function testCountable()
$this->assertCount(2, $this->menu);
}

public function testIterator()
{
$count = 0;
foreach ($this->pt1 as $key => $value) {
$count++;
$this->assertEquals('Child '.$count, $key);
$this->assertEquals('Child '.$count, $value->getLabel());
}
}

public function testGetChildren()
{
$children = $this->ch4->getChildren();
Expand Down Expand Up @@ -453,17 +375,4 @@ protected function addChildWithExternalUrl()
{
$this->menu->addChild('child', array('uri' => 'http://www.symfony-reloaded.org'));
}

// prints a visual representation of our basic testing tree
protected function printTestTree()
{
print(' Menu Structure '."\n");
print(' rt '."\n");
print(' / \ '."\n");
print(' pt1 pt2 '."\n");
print(' / | \ | '."\n");
print(' ch1 ch2 ch3 ch4 '."\n");
print(' | '."\n");
print(' gc1 '."\n");
}
}
92 changes: 92 additions & 0 deletions tests/Knp/Menu/Tests/TestCase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?php

namespace Knp\Menu\Tests;

use Knp\Menu\Iterator\CurrentItemFilterIterator;
use Knp\Menu\MenuItem;
use Knp\Menu\MenuFactory;

abstract class TestCase extends \PHPUnit_Framework_TestCase
{
/**
* @var \Knp\Menu\MenuItem
*/
protected $menu;

/**
* @var \Knp\Menu\MenuItem
*/
protected $pt1;

/**
* @var \Knp\Menu\MenuItem
*/
protected $ch1;

/**
* @var \Knp\Menu\MenuItem
*/
protected $ch2;

/**
* @var \Knp\Menu\MenuItem
*/
protected $ch3;

/**
* @var \Knp\Menu\MenuItem
*/
protected $pt2;

/**
* @var \Knp\Menu\MenuItem
*/
protected $ch4;

/**
* @var \Knp\Menu\MenuItem
*/
protected $gc1;

protected function setUp()
{
$factory = new MenuFactory();
$this->menu = $factory->createItem('Root li', array('attributes' => array('class' => 'root')));
$this->pt1 = $this->menu->addChild('Parent 1');
$this->ch1 = $this->pt1->addChild('Child 1');
$this->ch2 = $this->pt1->addChild('Child 2');

// add the 3rd child via addChild with an object
$this->ch3 = new MenuItem('Child 3', $factory);
$this->pt1->addChild($this->ch3);

$this->pt2 = $this->menu->addChild('Parent 2');
$this->ch4 = $this->pt2->addChild('Child 4');
$this->gc1 = $this->ch4->addChild('Grandchild 1');
}

protected function tearDown()
{
$this->menu = null;
$this->pt1 = null;
$this->ch1 = null;
$this->ch2 = null;
$this->ch3 = null;
$this->pt2 = null;
$this->ch4 = null;
$this->gc1 = null;
}

// prints a visual representation of our basic testing tree
protected function printTestTree()
{
print(' Menu Structure '."\n");
print(' rt '."\n");
print(' / \ '."\n");
print(' pt1 pt2 '."\n");
print(' / | \ | '."\n");
print(' ch1 ch2 ch3 ch4 '."\n");
print(' | '."\n");
print(' gc1 '."\n");
}
}

0 comments on commit d7eb547

Please sign in to comment.