Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Iterator #50

Merged
merged 5 commits into from
May 8, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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");
}
}