diff --git a/.gitignore b/.gitignore
index 3329706..35273c9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,4 +14,7 @@ app/config/parameters.yml
# Composer
composer.phar
-composer.lock
\ No newline at end of file
+composer.lock
+
+# Code coverage
+coverage/
diff --git a/.travis.yml b/.travis.yml
index 32d07f2..e4c51b2 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,15 +2,16 @@ language: php
sudo: false
+dist: trusty
+
cache:
directories:
- $HOME/.composer/cache/files
php:
- - 5.5
- - 7.0
- 7.1
- 7.2
+ - 7.3
env:
- SYMFONY_VERSION=2.3.*
@@ -25,32 +26,14 @@ env:
- SYMFONY_VERSION=4.0.*
- SYMFONY_VERSION=4.1.*
- SYMFONY_VERSION=4.2.*
+ - SYMFONY_VERSION=4.3.*
+ - SYMFONY_VERSION=4.3.*
+ - SYMFONY_VERSION=4.4.*
+ - SYMFONY_VERSION=5.0.*
+ - SYMFONY_VERSION=5.1.*
matrix:
fast_finish: true
- exclude:
- - php: 5.5
- env: SYMFONY_VERSION=4.0.*
- - php: 7.0
- env: SYMFONY_VERSION=4.0.*
- - php: 5.5
- env: SYMFONY_VERSION=4.1.*
- - php: 7.0
- env: SYMFONY_VERSION=4.1.*
- - php: 5.5
- env: SYMFONY_VERSION=4.2.*
- - php: 7.0
- env: SYMFONY_VERSION=4.2.*
- include:
- - php: 7.1
- env: SYMFONY_VERSION=4.3.* STABILITY=dev
- - php: 7.2
- env: SYMFONY_VERSION=4.3.* STABILITY=dev
- allow_failures:
- - php: 7.1
- env: SYMFONY_VERSION=4.3.* STABILITY=dev
- - php: 7.2
- env: SYMFONY_VERSION=4.3.* STABILITY=dev
before_install:
- composer self-update
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 87b1794..6cd692b 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -19,7 +19,8 @@ public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder('thormeier_breadcrumb');
$rootNode = method_exists(TreeBuilder::class, 'getRootNode')
- ? $treeBuilder->getRootNode() : $treeBuilder->root('thormeier_breadcrumb');
+ ? $treeBuilder->getRootNode()
+ : $treeBuilder->root('thormeier_breadcrumb');
$rootNode
->children()
diff --git a/DependencyInjection/RoutingLoaderCompilerPass.php b/DependencyInjection/RoutingLoaderCompilerPass.php
index b8d8444..70c09a1 100644
--- a/DependencyInjection/RoutingLoaderCompilerPass.php
+++ b/DependencyInjection/RoutingLoaderCompilerPass.php
@@ -19,8 +19,14 @@ public function process(ContainerBuilder $container)
{
$routingLoaderDefinition = $container->getDefinition('routing.loader');
- $container->setDefinition('thormeier_breadcrumb.routing.attach_breadcrumb_loader.inner', $routingLoaderDefinition);
+ $container->setDefinition(
+ 'thormeier_breadcrumb.routing.attach_breadcrumb_loader.inner',
+ $routingLoaderDefinition
+ );
- $container->setAlias('routing.loader', 'thormeier_breadcrumb.routing.attach_breadcrumb_loader')->setPublic(true);
+ $container->setAlias(
+ 'routing.loader',
+ 'thormeier_breadcrumb.routing.attach_breadcrumb_loader'
+ )->setPublic(true);
}
}
diff --git a/DependencyInjection/ThormeierBreadcrumbExtension.php b/DependencyInjection/ThormeierBreadcrumbExtension.php
index 18bda65..6f30abe 100644
--- a/DependencyInjection/ThormeierBreadcrumbExtension.php
+++ b/DependencyInjection/ThormeierBreadcrumbExtension.php
@@ -8,7 +8,7 @@
use Symfony\Component\DependencyInjection\Loader;
/**
- * Symfony2 DI extension
+ * Symfony DI extension
*
* @codeCoverageIgnore
*/
diff --git a/README.md b/README.md
index bd70bef..27e39e4 100644
--- a/README.md
+++ b/README.md
@@ -6,9 +6,9 @@ BreadcrumbBundle
## Introduction
This Symfony bundle provides integration of breadcrumbs via route config and rendering in your Twig templates.
-This bundle is heavily inspired by the inactive https://github.com/xi-project/xi-bundle-breadcrumbs
+This bundle is heavily inspired by the inactive [https://github.com/xi-project/xi-bundle-breadcrumbs](https://github.com/xi-project/xi-bundle-breadcrumbs)
-## Installation
+## Installation / Getting started
### Step 1: Composer require
@@ -35,7 +35,7 @@ Enable the bundle in your config.yml:
# config.yml
thormeier_breadcrumb: ~
-The template defaults to a very basic one, providing a `
` with `- ` and `` for every breadcrumb.
+The template defaults to a basic one, providing a `
` with `- ` and `` for every breadcrumb.
## Usage
@@ -259,3 +259,15 @@ a `BreadcrumbCollection` on demand.
A slideshow presenting the bundle and explaining some concepts a little further is available on slideshare:
[http://www.slideshare.net/Thormeier/thormeierbreadcrumbbundle](http://www.slideshare.net/Thormeier/thormeierbreadcrumbbundle)
+
+## Development
+
+To execute tests locally, execute the following command:
+
+```
+./vendor/bin/phpunit
+```
+
+The folder `coverage/` is ignored by git, it can therefore be used for generating coverage reports with `phpunit --coverage-html ./coverage/`.
+
+If you want to contribute to this project, please feel free to open up issues and/or pull requests!
diff --git a/Tests/Functional/AbstractBreadcrumbRenderTest.php b/Tests/Functional/AbstractBreadcrumbRenderTest.php
new file mode 100644
index 0000000..563316d
--- /dev/null
+++ b/Tests/Functional/AbstractBreadcrumbRenderTest.php
@@ -0,0 +1,55 @@
+boot();
+
+ /** @var Environment $twigEnv */
+ $twigEnv = $kernel->getContainer()->get('twig');
+
+ /** @var FilesystemLoader $twigLoader */
+ $twigLoader = $twigEnv->getLoader();
+ $twigLoader->addPath(realpath('./Tests/Functional/Resources/views'));
+
+ $this->kernel = $kernel;
+
+ /** @var LoaderResolver $loaderResolver */
+ $this->kernel->getContainer()->get('routing.loader')->load(realpath('./Tests/Functional/App/routes.yml'));
+ }
+
+ /**
+ * @param $url
+ * @return string
+ * @throws \Exception
+ */
+ public function doRequest($url)
+ {
+ $request = Request::create($url);
+
+ /** @var Response $response */
+ $response = $this->kernel->handle($request);
+
+ return $response->getContent();
+ }
+}
diff --git a/Tests/Functional/App/AppKernel.php b/Tests/Functional/App/AppKernel.php
new file mode 100644
index 0000000..29425bf
--- /dev/null
+++ b/Tests/Functional/App/AppKernel.php
@@ -0,0 +1,41 @@
+load(__DIR__ . '/config.php');
+ }
+}
diff --git a/Tests/Functional/App/autoload.php b/Tests/Functional/App/autoload.php
new file mode 100644
index 0000000..36123df
--- /dev/null
+++ b/Tests/Functional/App/autoload.php
@@ -0,0 +1,4 @@
+loadFromExtension('thormeier_breadcrumb', null);
+
+$container->loadFromExtension('framework', array(
+ 'secret' => 'foobar',
+ 'session' => array(
+ 'storage_id' => 'session.storage.mock_file'
+ ),
+ 'router' => array(
+ 'resource' => realpath('./Tests/Functional/App/routes.yml'),
+ ),
+));
diff --git a/Tests/Functional/App/routes.yml b/Tests/Functional/App/routes.yml
new file mode 100644
index 0000000..2bd833b
--- /dev/null
+++ b/Tests/Functional/App/routes.yml
@@ -0,0 +1,30 @@
+acme_demo_home:
+ path: /
+ controller: Thormeier\BreadcrumbBundle\Tests\Functional\Controller\BreadcrumbController::breadcrumbAction
+ options:
+ breadcrumb:
+ label: Home
+
+acme_demo_contact:
+ path: /contact
+ controller: Thormeier\BreadcrumbBundle\Tests\Functional\Controller\BreadcrumbController::breadcrumbAction
+ options:
+ breadcrumb:
+ label: Contact
+ parent_route: acme_demo_home
+
+acme_demo_catalogue:
+ path: /catalogue
+ controller: Thormeier\BreadcrumbBundle\Tests\Functional\Controller\BreadcrumbController::breadcrumbAction
+ options:
+ breadcrumb:
+ label: 'Our Catalogue'
+ parent_route: acme_demo_home
+
+acme_demo_catalogue_categories:
+ path: /catalogue/categories
+ controller: Thormeier\BreadcrumbBundle\Tests\Functional\Controller\BreadcrumbController::breadcrumbAction
+ options:
+ breadcrumb:
+ label: 'All categories'
+ parent_route: acme_demo_catalogue
diff --git a/Tests/Functional/BreadcrumbRenderTest.php b/Tests/Functional/BreadcrumbRenderTest.php
new file mode 100644
index 0000000..5c27809
--- /dev/null
+++ b/Tests/Functional/BreadcrumbRenderTest.php
@@ -0,0 +1,25 @@
+doRequest('/');
+ $this->assertContains('Home', $response);
+ }
+
+ /**
+ * @throws \Exception
+ */
+ public function testDoubleBreadcrumb()
+ {
+ $response = $this->doRequest('/catalogue');
+ $this->assertContains('Home', $response);
+ $this->assertContains('Our Catalogue', $response);
+ }
+}
diff --git a/Tests/Functional/Controller/BreadcrumbController.php b/Tests/Functional/Controller/BreadcrumbController.php
new file mode 100644
index 0000000..9388564
--- /dev/null
+++ b/Tests/Functional/Controller/BreadcrumbController.php
@@ -0,0 +1,16 @@
+render('breadcrumbs.twig');
+ }
+}
diff --git a/Tests/Functional/Resources/views/breadcrumbs.twig b/Tests/Functional/Resources/views/breadcrumbs.twig
new file mode 100644
index 0000000..1142a2f
--- /dev/null
+++ b/Tests/Functional/Resources/views/breadcrumbs.twig
@@ -0,0 +1 @@
+{{ breadcrumbs() }}
diff --git a/Tests/Model/BreadcrumbCollectionTest.php b/Tests/Unit/Model/BreadcrumbCollectionTest.php
similarity index 84%
rename from Tests/Model/BreadcrumbCollectionTest.php
rename to Tests/Unit/Model/BreadcrumbCollectionTest.php
index 20e722a..35944bc 100644
--- a/Tests/Model/BreadcrumbCollectionTest.php
+++ b/Tests/Unit/Model/BreadcrumbCollectionTest.php
@@ -1,6 +1,6 @@
assertEquals($breadcrumbB, $collection->getBreadcrumbByRoute('baz'));
$this->assertEquals($breadcrumbA, $collection->getBreadcrumbByRoute('bar'));
+ $this->assertEquals($breadcrumbC, $collection->getBreadcrumbByRoute('qux'));
+ $this->assertEquals(null, $collection->getBreadcrumbByRoute('xyzzy'));
}
/**
@@ -115,4 +117,19 @@ public function testAddAfterBreadcrumbExceptionException()
$collection->addBreadcrumbAfterCrumb($breadcrumbA, $breadcrumbB);
}
+
+ /**
+ * Test throwing of exception if a breadcrumb doesn't exist
+ */
+ public function testAddBeforeBreadcrumbExceptionException()
+ {
+ $breadcrumbA = new Breadcrumb('foo', 'bar');
+ $breadcrumbB = new Breadcrumb('bar', 'baz');
+
+ $collection = new BreadcrumbCollection();
+
+ $this->setExpectedException('\InvalidArgumentException');
+
+ $collection->addBreadcrumbBeforeCrumb($breadcrumbA, $breadcrumbB);
+ }
}
diff --git a/Tests/Provider/BreadcrumbProviderTest.php b/Tests/Unit/Provider/BreadcrumbProviderTest.php
similarity index 63%
rename from Tests/Provider/BreadcrumbProviderTest.php
rename to Tests/Unit/Provider/BreadcrumbProviderTest.php
index f10502a..71c3431 100644
--- a/Tests/Provider/BreadcrumbProviderTest.php
+++ b/Tests/Unit/Provider/BreadcrumbProviderTest.php
@@ -1,8 +1,9 @@
setMethods(array('get'))
->getMock();
- $request = $this->getMockBuilder('\Symfony\Component\HttpFoundation\Request')
- ->disableOriginalConstructor()
- ->getMock();
+ $request = Request::create('/');
$request->attributes = $this->requestAttributes;
$this->responseEvent = $this->getMockBuilder('\Symfony\Component\HttpKernel\Event\GetResponseEvent')
@@ -136,4 +135,73 @@ public function testMultipleBreadcrumbs()
$this->assertEquals($label2, $result->getAll()[1]->getLabel());
$this->assertEquals($route2, $result->getAll()[1]->getRoute());
}
+
+ /**
+ * Tests that the breadcrumbs can be gotten multiple times without changing.
+ */
+ public function testMultipleGetBreadcrumbs()
+ {
+ $label1 = 'foo';
+ $route1 = 'bar';
+ $label2 = 'baz';
+ $route2 = 'qux';
+
+ $this->requestAttributes->expects($this->any())
+ ->method('get')
+ ->will($this->returnValue(array(
+ array(
+ 'label' => $label1,
+ 'route' => $route1,
+ ),
+ array(
+ 'label' => $label2,
+ 'route' => $route2,
+ ),
+ )));
+
+ $this->provider->onKernelRequest($this->responseEvent);
+ $resultFirst = $this->provider->getBreadcrumbs();
+ $resultSecond = $this->provider->getBreadcrumbs();
+ $resultThird = $this->provider->getBreadcrumbs();
+
+ // Transitivity ensures that $resultFirst === $resultThird
+ $this->assertEquals($resultFirst, $resultSecond);
+ $this->assertEquals($resultSecond, $resultThird);
+ }
+
+ /**
+ * Tests that the convenience method is passed to the collection.
+ */
+ public function testGetBreadcrumbByRoute()
+ {
+ $label1 = 'foo';
+ $route1 = 'bar';
+ $label2 = 'baz';
+ $route2 = 'qux';
+
+ $this->requestAttributes->expects($this->any())
+ ->method('get')
+ ->will($this->returnValue(array(
+ array(
+ 'label' => $label1,
+ 'route' => $route1,
+ ),
+ array(
+ 'label' => $label2,
+ 'route' => $route2,
+ ),
+ )));
+
+ $this->provider->onKernelRequest($this->responseEvent);
+
+ // Test result that doesn't exist
+ $this->assertNull($this->provider->getBreadcrumbByRoute('doesnt exist'));
+
+ // Test existing result.
+ $existing = $this->provider->getBreadcrumbByRoute($route1);
+ $this->assertNotNull($existing);
+ $this->assertInstanceOf(self::MODEL_CLASS, $existing);
+ $this->assertEquals($label1, $existing->getLabel());
+ $this->assertEquals($route1, $existing->getRoute());
+ }
}
diff --git a/Tests/Routing/BreadcrumbAttachLoaderTest.php b/Tests/Unit/Routing/BreadcrumbAttachLoaderTest.php
similarity index 89%
rename from Tests/Routing/BreadcrumbAttachLoaderTest.php
rename to Tests/Unit/Routing/BreadcrumbAttachLoaderTest.php
index b4b812e..dc30956 100644
--- a/Tests/Routing/BreadcrumbAttachLoaderTest.php
+++ b/Tests/Unit/Routing/BreadcrumbAttachLoaderTest.php
@@ -1,6 +1,6 @@
getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')
- ->setMethods(array('load'))
+ ->setMethods(array('load', 'supports'))
->getMockForAbstractClass();
$this->delegatingLoader = $delegatingLoader;
@@ -139,4 +139,21 @@ public function testCircularBreadcrumbs()
$this->setExpectedException('\LogicException');
$this->loader->load('foobar');
}
+
+ /**
+ * Tests passing of supports call to internal router loader.
+ */
+ public function testSupports()
+ {
+ $resource = 'foo';
+ $type = 'bar';
+ $result = 'baz';
+
+ $this->delegatingLoader->expects($this->once())
+ ->method('supports')
+ ->with($resource, $type)
+ ->will($this->returnValue($result));
+
+ $this->assertEquals($result, $this->loader->supports($resource, $type));
+ }
}
diff --git a/Tests/Twig/BreadcrumbExtensionTest.php b/Tests/Unit/Twig/BreadcrumbExtensionTest.php
similarity index 97%
rename from Tests/Twig/BreadcrumbExtensionTest.php
rename to Tests/Unit/Twig/BreadcrumbExtensionTest.php
index d92a3f2..7519f71 100644
--- a/Tests/Twig/BreadcrumbExtensionTest.php
+++ b/Tests/Unit/Twig/BreadcrumbExtensionTest.php
@@ -1,6 +1,6 @@
=5.3.3",
- "symfony/framework-bundle": "2.3.*|^2.6.0|^3.0|^4.0"
+ "php": ">=5.5",
+ "symfony/framework-bundle": "2.3.*|^2.6.0|^3.0|^4.0|^5.0"
},
"require-dev": {
"twig/twig": "^1.15|^2.0",
+ "symfony/twig-bundle": "^4.0|^5.0",
"phpunit/phpunit": "4.*"
},
"suggest": {
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index aab5632..e2c853f 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -15,7 +15,10 @@
- ./Tests
+ ./Tests/Unit
+
+
+ ./Tests/Functional
@@ -30,4 +33,4 @@
-
\ No newline at end of file
+