Problem/Motivation

In writing unit tests for various parts of Component\Plugin for #2052109: [meta] Expand phpunit tests for \Drupal\Component\Plugin classes, I discovered that Drupal\Component\Plugin\Context\Context::getConstraints() tries to access an array property of an object.

  /**
   * Implements \Drupal\Component\Plugin\Context\ContextInterface::getConstraints().
   */
  public function getConstraints() {
    if (empty($this->contextDefinition['class'])) {
      throw new ContextException("An error was encountered while trying to validate the context.");
    }
    return array(new Type($this->contextDefinition['class']));
  }

$contextDefinition is defined as a \Drupal\Component\Plugin\Context\ContextDefinitionInterface.

After talking about it with @EclipseGC in IRC it seems that this is a bug.

It also seems that most of the Component aspect of Context is overridden by Core, which is why this bug hadn't been found yet.

Proposed resolution

Analyze a proper solution.

Remaining tasks

Analyze the requirements for Context::getConstraints().
Possibly modify ContextDefinitionInterface.
Modify Context::getConstraints() to conform with ContextDefinitionInterface.
Add PHPUnit test for the function Context::getConstraints()

User interface changes

API changes

Beta phase evaluation

Reference: https://www.drupal.org/core/beta-changes
Disruption Minimally disruptive because this code is mostly overridden by it's Drupal\Core namespace counterpart.

Comments

mile23’s picture

daffie’s picture

Issue summary: View changes

Updated IS with add PHPUnit test for the function Context::getConstraints().

mile23’s picture

mile23’s picture

Status: Active » Needs review
StatusFileSize
new4.2 KB

This patch properly encapsulates $contextDefinition within Context, tests getConstraints(), and updates a docblock or two.

daffie’s picture

Status: Needs review » Reviewed & tested by the community

It all looks good to me.
The patch fixed the problem as described in the issue summary.
All documentation is in order.
This issue is a normal bug fix, and doesn't include any disruptive changes, so it is allowed per beta-changes.
The patch gets a RTBC from me.

mile23’s picture

Issue summary: View changes
alexpott’s picture

Status: Reviewed & tested by the community » Needs work
  1. +++ b/core/lib/Drupal/Component/Plugin/Context/Context.php
    @@ -37,7 +37,7 @@ class Context implements ContextInterface {
    -    $this->contextDefinition = $context_definition;
    +    $this->setContextDefinition($context_definition);
    

    Why? Seems out of scope.

  2. +++ b/core/lib/Drupal/Component/Plugin/Context/Context.php
    @@ -78,13 +78,14 @@ public function getContextDefinition() {
    +    return array(new Type($constraint));
    
    +++ b/core/tests/Drupal/Tests/Component/Plugin/Context/ContextTest.php
    @@ -86,4 +86,55 @@ public function testGetContextValue($expected, $context_value, $is_required, $da
    +    $this->assertInternalType('array', $constraints);
    ...
    +    $this->assertEquals($expected_count, count($constraints));
    

    Why assert the count here and not the fact that we expect

       *   Array of constraints, each being an instance of
       *   \Symfony\Component\Validator\Constraint.
    

    according to the interface.

  3. +++ b/core/lib/Drupal/Component/Plugin/Context/ContextDefinitionInterface.php
    @@ -155,6 +155,8 @@ public function addConstraint($constraint_name, $options = NULL);
        * @return array
        *   A validation constraint definition which can be used for instantiating a
        *   \Symfony\Component\Validator\Constraint object.
    +   * @throws Drupal\Component\Plugin\Exception\ContextException
    +   *   If $constraint_name is not available, this method throws an exception.
    

    Should have a space between the @return and @throws

  4. +++ b/core/tests/Drupal/Tests/Component/Plugin/Context/ContextTest.php
    @@ -86,4 +86,55 @@ public function testGetContextValue($expected, $context_value, $is_required, $da
    +  public function providerGetConstraints() {
    +    return [
    +      [1, '\stdClass'],
    +      [0, NULL],
    +    ];
    +  }
    ...
    +    // Check whether we're expecting an exception.
    +    if (NULL === $class_constraint) {
    +      $this->setExpectedException('Drupal\Component\Plugin\Exception\ContextException');
    +    }
    

    Let's just have two tests here with a help function to set up the the context to test.

mile23’s picture

Status: Needs work » Needs review
StatusFileSize
new5.61 KB
new6.01 KB

Let's just have two tests here with a help function to set up the the context to test.

You know, that's my preference, but the last time this kind of thing came up, I was told to combine it. :-)

+++ b/core/lib/Drupal/Component/Plugin/Context/Context.php
@@ -78,13 +78,14 @@ public function getContextDefinition() {
+    return array(new Type($constraint));
+++ b/core/tests/Drupal/Tests/Component/Plugin/Context/ContextTest.php
@@ -86,4 +86,55 @@ public function testGetContextValue($expected, $context_value, $is_required, $da
+    $this->assertInternalType('array', $constraints);
...
+    $this->assertEquals($expected_count, count($constraints));

Why assert the count here and not the fact that we expect

   *   Array of constraints, each being an instance of
   *   \Symfony\Component\Validator\Constraint.

according to the interface.

Because if you do a deep-dive, you learn that the *only* place this is documented is in the interface... All other implementations are documented as returning array, without any hint of what the array is. However... If you look at the implementation we're dealing with here, it returns a Type object instead of a Constraint. Component/Context::getConstraint() is obviously sort of a reference implementation, so it might be important for DX to figure this out, but so far it's escaping me.

So here's a patch with all the changes you suggest. It will fail because it loops through the array and check for the documented expectation of Constraint objects, which is obviously wrong. It would be great if someone with expertise on this system could address it.

Status: Needs review » Needs work

The last submitted patch, 8: 2378297_8.patch, failed testing.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

smustgrave’s picture

Version: 9.4.x-dev » 10.1.x-dev
Issue tags: +Bug Smash Initiative
StatusFileSize
new0 bytes
new5.53 KB

Rerolled for D10 but as mentioned in #8 these will fail. But hopefully this puts new life in this issue.

quietone’s picture

Status: Needs work » Needs review
Issue tags: +Needs issue summary update

This issue was reviewed during a group triage meeting in #bugsmash. smustgrave and myself discussed the issue. I noted the issue looked valid and @smustgrave updated the patch.

The remaining tasks needs to be updated, tagging for an IS update.

smustgrave’s picture

Status: Needs review » Needs work
Issue tags: +Needs Review Queue Initiative

Moving to NW for issue summary update.

Also patch #21 had a failure, which seems releated.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.