Updated: Comment #N

Problem/Motivation

Drupal\system\Tests\Routing\* contain some great unit tests for the routing system, but we're missing a unit test for RouteBuilder. To do so, we need to remove the module_list() dependency, so postponing this on #1331486: Move module_invoke_*() and friends to an Extensions class.

Some of the tests needed to mock the router dumper. The current code typehints the matcher dumper interfaces, though calls "addRoutes" which is not
defined yet as an interface.

Proposed resolution

Let's add a specific dumper interface which contains the addRoutes method()

Remaining tasks

User interface changes

API changes

Original report by @username

The current code
In order to write proper tests we intro

Comments

effulgentsia’s picture

#1855204-5: RouteBuilder needs to respect route options set in yaml file contains some starter unit tests for this we might want to bring over when we're ready to do this.

jibran’s picture

katbailey’s picture

Title: Replace module_list() dependency in RouteBuilder with an injected service and then add RouteBuilder unit tests » Add RouteBuilder unit tests

The "replace module_list()" bit was done as part of #1331486: Move module_invoke_*() and friends to an Extensions class, so we just need to write the tests.

dawehner’s picture

Issue tags: +PHPUnit

.

dawehner’s picture

Status: Active » Needs review
Issue tags: +WSCCI, +Stalking Crell

While writing the tests I actually realized that the it is actually not true that the routes are not in memory all the time.
The test file was just some random test writing until I realized that they actually should not pass. Note: At the end all routes
are in the dumper.

Note: RouteCollection->addCollection does not remove old entries.

mile23’s picture

RouteBuilder says things like this: $yaml_discovery = new YamlDiscovery('routing', $this->moduleHandler->getModuleDirectories());

I say things like this: #2095037: Add vfsStream as a dependency in composer.json.

dawehner’s picture

StatusFileSize
new17.99 KB

There we go, this fixes the actual bug as well as tests the rest of the class.

Status: Needs review » Needs work

The last submitted patch, route_builder-1859684-7.patch, failed testing.

dawehner’s picture

Status: Needs work » Needs review
StatusFileSize
new17.89 KB

Some fixes later.

Status: Needs review » Needs work

The last submitted patch, router_builder-1859684-9.patch, failed testing.

dawehner’s picture

Status: Needs work » Needs review
StatusFileSize
new17.48 KB
new1.79 KB

There we go.

dawehner’s picture

Title: Add RouteBuilder unit tests » Fix routeBuilder performance and unit test

Let's be honest.

dawehner’s picture

StatusFileSize
new571 bytes
new17.49 KB

Fixed a missing whitespace.

Crell’s picture

Status: Needs review » Needs work

Discussed with dawehner in IRC. We don't need to mess with the interface for MatcherDumper; there was a bug in the tests he was using. :-)

dawehner’s picture

Status: Needs work » Needs review
StatusFileSize
new6.25 KB
new16.91 KB

We have been talking about removing the matcher dumper to be a service, thought this is not part of the patch as it would be kind of out of scope.

Status: Needs review » Needs work
Issue tags: -PHPUnit, -WSCCI, -Stalking Crell

The last submitted patch, route_rebuild-1859684-15.patch, failed testing.

dawehner’s picture

Status: Needs work » Needs review
Issue tags: +PHPUnit, +WSCCI, +Stalking Crell
StatusFileSize
new13.21 KB
new3.71 KB

Fixed the errors.

damiankloip’s picture

Overall, that is some good unit testing.

  1. +++ b/core/lib/Drupal/Core/Routing/RouteBuilder.php
    @@ -113,4 +121,17 @@ public function rebuild() {
    +   * Returns the yaml discovery for getting all the .routing.yml files.
    

    Should we use YAML?

  2. +++ b/core/tests/Drupal/Tests/Core/Routing/RouteBuilderTest.php
    @@ -0,0 +1,240 @@
    +    $this->assertNull($this->routeBuilder->rebuild());
    

    Won't this always return NULL anyway? regardless of whether the lock fails.

  3. +++ b/core/tests/Drupal/Tests/Core/Routing/RouteBuilderTest.php
    @@ -0,0 +1,240 @@
    +      ->with($this->equalTo(RoutingEvents::ALTER), $this->isInstanceOf('Drupal\Core\Routing\RouteBuildEvent'));
    

    Nice!

dawehner’s picture

StatusFileSize
new1.08 KB
new13.29 KB

Thanks for the review!

Won't this always return NULL anyway? regardless of whether the lock fails.

Someone had the idea that phpunit strict mode would be a good idea.

damiankloip’s picture

:) Maybe we should make rebuild() return something?

dawehner’s picture

Well, we could just return TRUE/FALSE but it is kind of pointless to be honest.

dawehner’s picture

StatusFileSize
new2.34 KB
new13.92 KB

Here is a patch for that.

Crell’s picture

+++ b/core/lib/Drupal/Core/Routing/MatcherDumperInterface.php
@@ -0,0 +1,26 @@
+/**
+ * Extends the symfony matcher dumper interface with a setRoutes method.
+ */
+interface MatcherDumperInterface extends SymfonyMatcherDumperInterface {
+
+  /**
+   * Adds additional routes to be dumped.
+   *
+   * @param \Symfony\Component\Routing\RouteCollection $routes
+   *   A collection of routes to add to this dumper.
+   */
+  public function addRoutes(RouteCollection $routes);
+
+}

Why are we still doing this? It's not needed.

dawehner’s picture

Why are we still doing this? It's not needed.

I potentially agree that it is scope-creep though addRoutes is not part of the symfony interface, so as the router
system should be possible to be used on whatever other database system we should introduce an interface. Do you want to add a new issue for that or is it okay in this issue?

dawehner’s picture

#23: route_rebuild-1859684-23.patch queued for re-testing.

klausi’s picture

Title: Fix routeBuilder performance and unit test » Expand routeBuilder unit test
  1. +++ b/core/lib/Drupal/Core/Routing/RouteBuilder.php
    @@ -56,12 +62,14 @@ class RouteBuilder {
    +   * @param \Drupal\Core\Routing\MatcherDumperInterface|\Symfony\Component\Routing\Matcher\Dumper\MatcherDumperInterface $dumper
    

    why the "|" OR here? the first is a child of the second, so just use the second.

  2. +++ b/core/lib/Drupal/Core/Routing/RouteBuilder.php
    @@ -72,6 +80,9 @@ public function __construct(MatcherDumperInterface $dumper, LockBackendInterface
    +   *   Returns TRUE if the rebuild succeeds, otherwise FALSE.
    

    should be "FALSE otherwise".

Can't say much about the rest, looks like we are merely expanding test coverage here? No actual bug is fixed here?

dawehner’s picture

StatusFileSize
new1.08 KB
new13.85 KB

why the "|" OR here? the first is a child of the second, so just use the second.

Ah this was not on purpose.

Can't say much about the rest, looks like we are merely expanding test coverage here? No actual bug is fixed here?

The only actual bug was the missing interface.

Crell’s picture

We should drop addRoutes(). The dumper not being a true-service is a separate matter (and my fault for not catching originally). Adding another method that duplicates existing functionality is not necessary.

dawehner’s picture

So you suggest to just leave the method but just skip to use an interface?

Crell’s picture

Status: Needs review » Reviewed & tested by the community

Never mind, I was misreading the patch. :-) Ignore my objections.

catch’s picture

Issue summary: View changes
Status: Reviewed & tested by the community » Needs work
+/**
+ * Extends the symfony matcher dumper interface with a setRoutes method.
+ */
+interface MatcherDumperInterface extends SymfonyMatcherDumperInterface {
+
+  /**
+   * Adds additional routes to be dumped.
+   *
+   * @param \Symfony\Component\Routing\RouteCollection $routes
+   *   A collection of routes to add to this dumper.
+   */
+  public function addRoutes(RouteCollection $routes);
+
+}

Where is this setRoutes() method that's supposed to be added?

dawehner’s picture

@catch
I was wrong on that. All we need is the already existing addRoutes method.

dawehner’s picture

Status: Needs work » Reviewed & tested by the community
catch’s picture

Status: Reviewed & tested by the community » Needs work

In that case, we should update the comment so it's not talking about a method that doesn't exist, and I'm wondering why we're extending the interface at all if it has exactly the same single identical method to the Symfony one. If there's a reason it could use a comment as to why.

dawehner’s picture

Issue summary: View changes
dawehner’s picture

Status: Needs work » Reviewed & tested by the community

Added some comment about the need for an interface: https://drupal.org/node/1859684

Crell’s picture

Background: The Symfony dumper interface doesn't define how routes get queued up to be dumped, just how they're dumped. Our dumper defines a method for doing so, but when I wrote it I didn't bother to make an interface for it. (The Symfony default one uses a constructor parameter for a single RouteCollection, which wouldn't scale for us.) This issue fixes that oversight on my part.

I was confused by this too, earlier in the thread. We're good now.

catch’s picture

Status: Reviewed & tested by the community » Needs work

Sorry I still don't get it.

The comment says

Extends the symfony matcher dumper interface with a setRoutes method.

However the interface does not extend the interface with a setRoutes method, it just defines an addRoutes() method.

If I'm missing something please let me know, but I don't see how the patch is possibly correct at the moment.

Crell’s picture

I think that's just the comment being a bit out of date. It should now read addRoutes(). Does that make more sense?

catch’s picture

Yes that's all I really wanted in #32 (assuming that was the problem).

dawehner’s picture

Status: Needs work » Needs review
StatusFileSize
new583 bytes
new13.85 KB

Oh sometimes I am just blind.

Crell’s picture

Status: Needs review » Reviewed & tested by the community

Seems to happen to a lot of people in this thread. :-)

catch’s picture

Committed/pushed to 8.x, thanks!

dawehner’s picture

Status: Reviewed & tested by the community » Fixed

Let's also mark the issue as fixed.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.