diff --git a/.travis.yml b/.travis.yml index e045108e..b21bab46 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,11 +3,11 @@ language: php php: - 5.3 - 5.4 + - 5.5 env: -# - SYMFONY_VERSION=2.1.* - SYMFONY_VERSION=2.2.* -# - SYMFONY_VERSION=2.3.* + - SYMFONY_VERSION=2.3.* # - SYMFONY_VERSION=dev-master before_script: diff --git a/Templating/Helper/CmfHelper.php b/Templating/Helper/CmfHelper.php index 7f80314e..b50b0d7a 100644 --- a/Templating/Helper/CmfHelper.php +++ b/Templating/Helper/CmfHelper.php @@ -101,18 +101,12 @@ public function find($path) /** * Gets a document instance and validate if its eligible. * -<<<<<<< HEAD:Twig/TwigExtension.php * @param string|object $document the id of a document or the document * object itself * @param boolean|null $ignoreRole whether the bypass role should be * ignored (leading to only show published content regardless of the * current user) or null to skip the published check completely. * @param null|string $class class name to filter on -======= - * @param string|object $document the id of a document or the document object itself - * @param Boolean|null $ignoreRole if the role should be ignored or null if publish workflow should be ignored - * @param null|string $class class name to filter on ->>>>>>> origin/master:Templating/Helper/CmfHelper.php * * @return null|object */ @@ -171,19 +165,11 @@ public function findMany($paths = array(), $limit = false, $offset = false, $ign } /** -<<<<<<< HEAD:Twig/TwigExtension.php * Check if a document is published, regardless of the current users role. * * @param object $document * * @return boolean -======= - * Checks if a document is published. - * - * @param string $document - * - * @return Boolean ->>>>>>> origin/master:Templating/Helper/CmfHelper.php */ public function isPublished($document) { @@ -377,38 +363,28 @@ public function getDescendants($parent, $depth = null) /** * Check children for a possible following document * - * @param \Traversable $childNames - * @param Boolean $reverse - * @param string $parentPath + * @param array $childNames + * @param string $path * @param Boolean $ignoreRole * @param null|string $class - * @param null|string $nodeName * * @return null|object */ - private function checkChildren($childNames, $reverse, $parentPath, $ignoreRole = false, $class = null, $nodeName = null) + private function checkChildren(array $childNames, $path, $ignoreRole = false, $class = null) { - if ($reverse) { - $childNames = array_reverse($childNames->getArrayCopy()); - } - - $check = empty($nodeName); foreach ($childNames as $name) { if (strpos($name, 'phpcr_locale:') === 0) { continue; } - if ($check) { - try { - $child = $this->getDocument("$parentPath/$name", $ignoreRole, $class); - if ($child) { - return $child; - } - } catch (MissingTranslationException $e) { - continue; - } - } elseif ($nodeName == $name) { - $check = true; + try { + $child = $this->getDocument(ltrim($path, '/')."/$name", $ignoreRole, $class); + } catch (MissingTranslationException $e) { + continue; + } + + if ($child) { + return $child; } } @@ -416,130 +392,288 @@ private function checkChildren($childNames, $reverse, $parentPath, $ignoreRole = } /** - * Search for a following document + * Traverse the depth to find previous documents * - * @param string|object $path document instance or path - * @param string|object $anchor document instance or path - * @param null|integer $depth - * @param Boolean $reverse - * @param Boolean $ignoreRole - * @param null|string $class + * @param null|integer $depth + * @param integer $anchorDepth + * @param array $childNames + * @param string $path + * @param Boolean $ignoreRole + * @param null|string $class * * @return null|object */ - private function search($path, $anchor = null, $depth = null, $reverse = false, $ignoreRole = false, $class = null) + private function traversePrevDepth($depth, $anchorDepth, array $childNames, $path, $ignoreRole, $class) { - if (empty($path)) { - return null; + foreach ($childNames as $childName) { + $childPath = "$path/$childName"; + $node = $this->dm->getPhpcrSession()->getNode($childPath); + if (null === $depth || PathHelper::getPathDepth($childPath) - $anchorDepth < $depth) { + $childNames = $node->getNodeNames()->getArrayCopy(); + if (!empty($childNames)) { + $childNames = array_reverse($childNames); + $result = $this->traversePrevDepth($depth, $anchorDepth, $childNames, $childPath, $ignoreRole, $class); + if ($result) { + return $result; + } + } + } + + $result = $this->checkChildren($childNames, $node->getPath(), $ignoreRole, $class); + if ($result) { + return $result; + } } + } + /** + * Search for a previous document + * + * @param string|object $path document instance or path from which to search + * @param string|object $anchor document instance or path which serves as an anchor from which to flatten the hierarchy + * @param null|integer $depth depth up to which to traverse down the tree when an anchor is provided + * @param Boolean $ignoreRole if to ignore the role + * @param null|string $class the class to filter by + * + * @return null|object + */ + private function searchDepthPrev($path, $anchor, $depth = null, $ignoreRole = false, $class = null) + { if (is_object($path)) { $path = $this->dm->getUnitOfWork()->getDocumentId($path); } + if (null === $path || '/' === $path) { + return null; + } + $node = $this->dm->getPhpcrSession()->getNode($path); - if ($anchor) { - if (is_object($anchor)) { - $anchor = $this->dm->getUnitOfWork()->getDocumentId($anchor); - } + if (is_object($anchor)) { + $anchor = $this->dm->getUnitOfWork()->getDocumentId($anchor); + } + + if (0 !== strpos($path, $anchor)) { + throw new \RuntimeException("The anchor path '$anchor' is not a parent of the current path '$path'."); + } + + if ($path === $anchor) { + return null; + } - if (strpos($path, $anchor) !== 0) { - throw new \RuntimeException("The anchor path '$anchor' is not a parent of the current path '$path'."); + $parent = $node->getParent(); + $parentPath = $parent->getPath(); + + $childNames = $parent->getNodeNames()->getArrayCopy(); + if (!empty($childNames)) { + $childNames = array_reverse($childNames); + $key = array_search($node->getName(), $childNames); + $childNames = array_slice($childNames, $key + 1); + } + + // traverse the previous siblings down the tree + $result = $this->traversePrevDepth($depth, PathHelper::getPathDepth($anchor), $childNames, $parentPath, $ignoreRole, $class); + if ($result) { + return $result; + } + + // check siblings + $result = $this->checkChildren($childNames, $parentPath, $ignoreRole, $class); + if ($result) { + return $result; + } + + // check parents + // TODO do we need to traverse towards the anchor? + if (0 === strpos($parentPath, $anchor)) { + $parent = $parent->getParent(); + $childNames = $parent->getNodeNames()->getArrayCopy(); + $key = array_search(PathHelper::getNodeName($parentPath), $childNames); + $childNames = array_slice($childNames, 0, $key + 1); + $childNames = array_reverse($childNames); + $result = $this->checkChildren($childNames, $parent->getPath(), $ignoreRole, $class); + if ($result) { + return $result; } + } - if (!$reverse - && (null === $depth || PathHelper::getPathDepth($path() - PathHelper::getPathDepth($anchor)) < $depth) - ) { - $childNames = $node->getNodeNames(); - if ($childNames->count()) { - $result = $this->checkChildren($childNames, $reverse, $path, $ignoreRole, $class); - if ($result) { - return $result; - } - } + return null; + } + + /** + * Search for a next document + * + * @param string|object $path document instance or path from which to search + * @param string|object $anchor document instance or path which serves as an anchor from which to flatten the hierarchy + * @param null|integer $depth depth up to which to traverse down the tree when an anchor is provided + * @param Boolean $ignoreRole if to ignore the role + * @param null|string $class the class to filter by + * + * @return null|object + */ + private function searchDepthNext($path, $anchor, $depth = null, $ignoreRole = false, $class = null) + { + if (is_object($path)) { + $path = $this->dm->getUnitOfWork()->getDocumentId($path); + } + + if (null === $path || '/' === $path) { + return null; + } + + $node = $this->dm->getPhpcrSession()->getNode($path); + + if (is_object($anchor)) { + $anchor = $this->dm->getUnitOfWork()->getDocumentId($anchor); + } + + if (0 !== strpos($path, $anchor)) { + throw new \RuntimeException("The anchor path '$anchor' is not a parent of the current path '$path'."); + } + + // take the first eligible child if there are any + // TODO do we need to traverse away from the anchor up to the depth here? + if (null === $depth || PathHelper::getPathDepth($path) - PathHelper::getPathDepth($anchor) < $depth) { + $childNames = $node->getNodeNames()->getArrayCopy(); + $result = $this->checkChildren($childNames, $path, $ignoreRole, $class); + if ($result) { + return $result; } } - $nodename = $node->getName(); + $parent = $node->getParent(); + $parentPath = PathHelper::getParentPath($path); - do { - $parentNode = $node->getParent(); - $childNames = $parentNode->getNodeNames(); - $result = $this->checkChildren($childNames, $reverse, $parentNode->getPath(), $ignoreRole, $class, $nodename); - if ($result || !$anchor) { + // take the first eligible sibling + if (0 === strpos($parentPath, $anchor)) { + $childNames = $parent->getNodeNames()->getArrayCopy(); + $key = array_search($node->getName(), $childNames); + $childNames = array_slice($childNames, $key + 1); + $result = $this->checkChildren($childNames, $parentPath, $ignoreRole, $class); + if ($result) { return $result; } + } + + // take the first eligible parent, traverse up + while ('/' !== $parentPath) { + $parent = $parent->getParent(); + if (false === strpos($parent->getPath(), $anchor)) { + return null; + } - $node = $parentNode; - if ($nodename) { - $reverse = !$reverse; - $nodename = null; + $childNames = $parent->getNodeNames()->getArrayCopy(); + $key = array_search(PathHelper::getNodeName($parentPath), $childNames); + $childNames = array_slice($childNames, $key + 1); + $parentPath = $parent->getPath(); + $result = $this->checkChildren($childNames, $parentPath, $ignoreRole, $class); + if ($result) { + return $result; } - } while (!$anchor || $anchor !== $node->getPath()); + } return null; } + /** + * Search for a following document + * + * @param string|object $path document instance or path from which to search + * @param Boolean $reverse if to traverse back + * @param Boolean $ignoreRole if to ignore the role + * @param null|string $class the class to filter by + * + * @return null|object + */ + private function search($path, $reverse = false, $ignoreRole = false, $class = null) + { + if (is_object($path)) { + $path = $this->dm->getUnitOfWork()->getDocumentId($path); + } + + if (null === $path || '/' === $path) { + return null; + } + + $node = $this->dm->getPhpcrSession()->getNode($path); + $parentNode = $node->getParent(); + $childNames = $parentNode->getNodeNames()->getArrayCopy(); + if ($reverse) { + $childNames = array_reverse($childNames); + } + + $key = array_search($node->getName(), $childNames); + $childNames = array_slice($childNames, $key + 1); + return $this->checkChildren($childNames, $parentNode->getPath(), $ignoreRole, $class); + } + /** * Gets the previous document. * - * @param string|object $current document instance or path - * @param string|object $parent document instance or path - * @param null|integer $depth - * @param Boolean $ignoreRole - * @param null|string $class + * @param string|object $path document instance or path from which to search + * @param null|string|object $anchor document instance or path which serves as an anchor from which to flatten the hierarchy + * @param null|integer $depth depth up to which to traverse down the tree when an anchor is provided + * @param Boolean $ignoreRole if to ignore the role + * @param null|string $class the class to filter by * * @return null|object */ - public function getPrev($current, $parent = null, $depth = null, $ignoreRole = false, $class = null) + public function getPrev($current, $anchor = null, $depth = null, $ignoreRole = false, $class = null) { - return $this->search($current, $parent, $depth, true, $ignoreRole, $class); + if ($anchor) { + return $this->searchDepthPrev($current, $anchor, $depth, true, $ignoreRole, $class); + } + + return $this->search($current, true, $ignoreRole, $class); } /** * Gets the next document. * - * @param string|object $current document instance or path - * @param string|object $parent document instance or path - * @param null|integer $depth - * @param Boolean $ignoreRole - * @param null|string $class + * @param string|object $path document instance or path from which to search + * @param null|string|object $anchor document instance or path which serves as an anchor from which to flatten the hierarchy + * @param null|integer $depth depth up to which to traverse down the tree when an anchor is provided + * @param Boolean $ignoreRole if to ignore the role + * @param null|string $class the class to filter by * * @return null|object */ - public function getNext($current, $parent = null, $depth = null, $ignoreRole = false, $class = null) + public function getNext($current, $anchor = null, $depth = null, $ignoreRole = false, $class = null) { - return $this->search($current, $parent, $depth, false, $ignoreRole, $class); + if ($anchor) { + return $this->searchDepthNext($current, $anchor, $depth, $ignoreRole, $class); + } + + return $this->search($current, false, $ignoreRole, $class); } /** * Gets the previous linkable document. * - * @param string|object $current document instance or path - * @param string|object $parent document instance or path - * @param null|integer $depth - * @param Boolean $ignoreRole + * @param string|object $path document instance or path from which to search + * @param null|string|object $anchor document instance or path which serves as an anchor from which to flatten the hierarchy + * @param null|integer $depth depth up to which to traverse down the tree when an anchor is provided + * @param Boolean $ignoreRole if to ignore the role * * @return null|object */ - public function getPrevLinkable($current, $parent = null, $depth = null, $ignoreRole = false) + public function getPrevLinkable($current, $anchor = null, $depth = null, $ignoreRole = false) { - return $this->search($current, $parent, $depth, true, $ignoreRole, 'Symfony\Cmf\Component\Routing\RouteAwareInterface'); + return $this->getPrev($current, $anchor, $depth, $ignoreRole, 'Symfony\Cmf\Component\Routing\RouteAwareInterface'); } /** * Gets the next linkable document. * - * @param string|object $current document instance or path - * @param string|object $parent document instance or path - * @param null|integer $depth - * @param Boolean $ignoreRole + * @param string|object $path document instance or path from which to search + * @param null|string|object $anchor document instance or path which serves as an anchor from which to flatten the hierarchy + * @param null|integer $depth depth up to which to traverse down the tree when an anchor is provided + * @param Boolean $ignoreRole if to ignore the role * * @return null|object */ - public function getNextLinkable($current, $parent = null, $depth = null, $ignoreRole = false) + public function getNextLinkable($current, $anchor = null, $depth = null, $ignoreRole = false) { - return $this->search($current, $parent, $depth, false, $ignoreRole, 'Symfony\Cmf\Component\Routing\RouteAwareInterface'); + return $this->getNext($current, $anchor, $depth, $ignoreRole, 'Symfony\Cmf\Component\Routing\RouteAwareInterface'); } } diff --git a/Tests/Functional/Templating/Helper/CmfHelperHierarchyTest.php b/Tests/Functional/Templating/Helper/CmfHelperHierarchyTest.php new file mode 100644 index 00000000..238e459f --- /dev/null +++ b/Tests/Functional/Templating/Helper/CmfHelperHierarchyTest.php @@ -0,0 +1,212 @@ +getContainer(); + $managerRegistry = $container->get('doctrine_phpcr'); + /** @var $session SessionInterface */ + $session = $managerRegistry->getConnection(); + $root = $session->getRootNode(); + if ($root->hasNode('a')) { + $session->removeItem('/a'); + } + + /* + * /a + * /a/b + * /a/b/c + * /a/b/d + * /a/b/e + * /a/f + * /a/f/g + * /a/f/g/h + * /a/i + */ + $a = $root->addNode('a'); + $b = $a->addNode('b'); + $c = $b->addNode('c'); + $c->addMixin('phpcr:managed'); + $c->setProperty('phpcr:class', 'Symfony\Cmf\Bundle\CoreBundle\Tests\Resources\Document\RouteAware'); + $b->addNode('d'); + $e = $b->addNode('e'); + $e->addMixin('phpcr:managed'); + $e->setProperty('phpcr:class', 'Symfony\Cmf\Bundle\CoreBundle\Tests\Resources\Document\RouteAware'); + $f = $a->addNode('f'); + $g = $f->addNode('g'); + $g->addNode('h'); + $a->addNode('i'); + + $session->save(); + + $this->pwc = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface'); + $this->pwc->expects($this->any()) + ->method('isGranted') + ->will($this->returnValue(true)) + ; + + $this->extension = new CmfHelper($this->pwc, $managerRegistry, 'default'); + } + + public function testGetDescendants() + { + $this->assertEquals(array(), $this->extension->getDescendants(null)); + + $expected = array('/a/b', '/a/b/c', '/a/b/d', '/a/b/e', '/a/f', '/a/f/g', '/a/f/g/h', '/a/i'); + $this->assertEquals($expected, $this->extension->getDescendants('/a')); + + $expected = array('/a/b', '/a/f', '/a/i'); + $this->assertEquals($expected, $this->extension->getDescendants('/a', 1)); + } + + /** + * @dataProvider getPrevData + */ + public function testGetPrev($expected, $path, $anchor = null, $depth = null, $class = 'Doctrine\ODM\PHPCR\Document\Generic') + { + $prev = $this->extension->getPrev($path, $anchor, $depth); + if (null === $expected) { + $this->assertNull($prev); + } else { + $this->assertInstanceOf($class, $prev); + $this->assertEquals($expected, $prev->getId()); + } + } + + public static function getPrevData() + { + return array( + array(null, null), + array(null, '/a'), + array(null, '/a/b'), + array(null, '/a/b/c'), + array('/a/b/c', '/a/b/d', null, null, 'Symfony\Cmf\Bundle\CoreBundle\Tests\Resources\Document\RouteAware'), + array('/a/b/d', '/a/b/e'), + array('/a/b', '/a/f'), + array(null, '/a/f/g'), + array(null, '/a/f/g/h'), + array(null, '/a', '/a'), + array('/a', '/a/b', '/a'), + array('/a/b', '/a/b/c', '/a'), + array('/a/b/c', '/a/b/d', '/a', null, 'Symfony\Cmf\Bundle\CoreBundle\Tests\Resources\Document\RouteAware'), + array('/a/b/d', '/a/b/e', '/a'), + array('/a/b/e', '/a/f', '/a', null, 'Symfony\Cmf\Bundle\CoreBundle\Tests\Resources\Document\RouteAware'), + array('/a/f', '/a/f/g', '/a'), + array('/a/f/g', '/a/f/g/h', '/a'), + array('/a/f/g/h', '/a/i', '/a'), + array('/a/f/g', '/a/i', '/a', 2), + ); + } + + /** + * @dataProvider getNextData + */ + public function testGetNext($expected, $path, $anchor = null, $depth = null, $class = 'Doctrine\ODM\PHPCR\Document\Generic') + { + $next = $this->extension->getNext($path, $anchor, $depth); + if (null === $expected) { + $this->assertNull($next); + } else { + $this->assertInstanceOf($class, $next); + $this->assertEquals($expected, $next->getId()); + } + } + + public static function getNextData() + { + return array( + array(null, null), + array(null, '/a'), + array('/a/f', '/a/b'), + array('/a/b/d', '/a/b/c'), + array('/a/b/e', '/a/b/d', null, null, 'Symfony\Cmf\Bundle\CoreBundle\Tests\Resources\Document\RouteAware'), + array(null, '/a/b/e'), + array('/a/i', '/a/f'), + array(null, '/a/f/g'), + array(null, '/a/f/g/h'), + array('/a/b', '/a', '/a'), + array('/a/b/c', '/a/b', '/a', null, 'Symfony\Cmf\Bundle\CoreBundle\Tests\Resources\Document\RouteAware'), + array('/a/b/d', '/a/b/c', '/a'), + array('/a/b/e', '/a/b/d', '/a', null, 'Symfony\Cmf\Bundle\CoreBundle\Tests\Resources\Document\RouteAware'), + array('/a/f', '/a/b/e', '/a'), + array('/a/f/g', '/a/f', '/a'), + array('/a/f/g/h', '/a/f/g', '/a'), + array('/a/i', '/a/f/g/h', '/a'), + array(null, '/a/i', '/a'), + array(null, '/a/b/e', '/a/b'), + array('/a/i', '/a/f/g', '/a', 2), + ); + } + + /** + * @dataProvider getPrevLinkableData + */ + public function testGetPrevLinkable($expected, $path, $anchor = null, $depth = null) + { + $prev = $this->extension->getPrevLinkable($path, $anchor, $depth); + if (null === $expected) { + $this->assertNull($prev); + } else { + $this->assertInstanceOf('Symfony\Cmf\Bundle\CoreBundle\Tests\Resources\Document\RouteAware', $prev); + $this->assertEquals($expected, $prev->getId()); + } + } + + public static function getPrevLinkableData() + { + // TODO: expand test case + return array( + array(null, null), + array(null, '/a/b/c'), + array('/a/b/c', '/a/b/d'), + array('/a/b/c', '/a/b/e'), + ); + } + + /** + * @dataProvider getNextLinkableData + */ + public function testGetNextLinkable($expected, $path, $anchor = null, $depth = null) + { + $next = $this->extension->getNextLinkable($path, $anchor, $depth); + if (null === $expected) { + $this->assertNull($next); + } else { + $this->assertInstanceOf('Symfony\Cmf\Bundle\CoreBundle\Tests\Resources\Document\RouteAware', $next); + $this->assertEquals($expected, $next->getId()); + } + } + + public static function getNextLinkableData() + { + // TODO: expand test case + return array( + array(null, null), + array('/a/b/e', '/a/b/c'), + array('/a/b/e', '/a/b/d'), + array(null, '/a/b/e'), + ); + } +} \ No newline at end of file diff --git a/Tests/Functional/Twig/Extension/CmfExtensionHierarchyTest.php b/Tests/Functional/Twig/Extension/CmfExtensionHierarchyTest.php deleted file mode 100644 index 65bc7fc9..00000000 --- a/Tests/Functional/Twig/Extension/CmfExtensionHierarchyTest.php +++ /dev/null @@ -1,134 +0,0 @@ -getContainer(); - $managerRegistry = $container->get('doctrine_phpcr'); - /** @var $session SessionInterface */ - $session = $managerRegistry->getConnection(); - $root = $session->getRootNode(); - if ($root->hasNode('a')) { - $session->removeItem('/a'); - } - - $a = $root->addNode('a'); - $b = $a->addNode('b'); - $c = $b->addNode('c'); - $d = $b->addNode('d'); - $e = $b->addNode('e'); - $f = $a->addNode('f'); - $g = $f->addNode('g'); - $h = $g->addNode('h'); - - $session->save(); - - $this->pwc = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface'); - $this->pwc->expects($this->any()) - ->method('isGranted') - ->will($this->returnValue(true)) - ; - - $this->extension = new CmfExtension($this->pwc, $managerRegistry, 'default'); - } - - public function testGetDescendants() - { - $this->assertEquals(array(), $this->extension->getDescendants(null)); - - $this->assertEquals(array('/a/b', '/a/b/c', '/a/b/d', '/a/b/e', '/a/f', '/a/f/g', '/a/f/g/h'), $this->extension->getDescendants('/a')); - - $this->assertEquals(array('/a/b', '/a/f'), $this->extension->getDescendants('/a', 1)); - } - - /** - * @dataProvider getPrevData - */ - public function testGetPrev($expected, $path) - { - $prev = $this->extension->getPrev($path); - if (null === $expected) { - $this->assertNull($prev); - } else { - $this->assertInstanceOf('Doctrine\ODM\PHPCR\Document\Generic', $prev); - $this->assertEquals($expected, $prev->getId()); - } - } - - public static function getPrevData() - { - return array( - array(null, null), - array(null, '/a'), - array('/a', '/a/b'), - array('/a/b', '/a/b/c'), - array('/a/b/c', '/a/b/d'), - array('/a/b/d', '/a/b/e'), - array('/a/b/e', '/a/f'), - array('/a/f', '/a/f/g'), - array('/a/f/g', '/a/f/g/h'), - ); - } - - /** - * @dataProvider getNextData - */ - public function testGetNext($expected, $path) - { - $next = $this->extension->getNext($path); - if (null === $expected) { - $this->assertNull($next); - } else { - $this->assertInstanceOf('Doctrine\ODM\PHPCR\Document\Generic', $next); - $this->assertEquals($expected, $next->getId()); - } - } - - public static function getNextData() - { - return array( - array(null, null), - array('/a/b', '/a'), - array('/a/b/c', '/a/b'), - array('/a/b/d', '/a/b/c'), - array('/a/b/e', '/a/b/d'), - array('/a/f', '/a/b/e'), - array('/a/f/g', '/a/f'), - array('/a/f/g/h', '/a/f/g'), - array(null, '/a/f/g/h'), - ); - } - - public function testGetPrevLinkable() - { - $this->assertNull($this->extension->getPrevLinkable(null)); - - $this->markTestIncomplete('TODO: write test'); - } - - public function testGetNextLinkable() - { - $this->assertNull($this->extension->getNextLinkable(null)); - - $this->markTestIncomplete('TODO: write test'); - } -} diff --git a/Tests/Resources/Document/RouteAware.php b/Tests/Resources/Document/RouteAware.php new file mode 100644 index 00000000..08996528 --- /dev/null +++ b/Tests/Resources/Document/RouteAware.php @@ -0,0 +1,24 @@ +id; + } + + public function getRoutes() + { + } +} \ No newline at end of file