Problem/Motivation

There are two DiffFormatter classes. One is in namespace \Drupal\Component\Diff, and the other is in \Drupal\Core\Diff.

When these two were separated out, there was one thing that wasn't done quite right, apparently, and it's causing exceptions in a test that is using the Component class to format a diff.

So, in my code (in a contrib module), I'm calling the component class's DiffFormatter::format() method.

It has these two lines that say:

    if (!empty($xi)) {
      $this->line_stats['counter']['x'] += $xi;
    }
    if (!empty($yi)) {
      $this->line_stats['counter']['y'] += $yi;
    }

near the bottom.

But $this->line_stats is not defined, and so I'm getting 4 exceptions in my test that say:

Undefined property: Drupal\Component\Diff\DiffFormatter::$line_stats
Undefined index: counter
Undefined index: x
Undefined index: y

The problem is that $this->line_stats is only defined in the Core class, like this:

  /**
   * The line stats.
   *
   * @var array
   */
  protected $line_stats = array(
    'counter' => array('x' => 0, 'y' => 0),
    'offset' => array('x' => 0, 'y' => 0),
  );

Proposed resolution

Either (a) move the protected $line_stats declaration into the Component class, or (b) remove those two lines of code from the Component class.

Also apparently the Component class is not being tested in Core, or this problem would have probably occurred in the test, so also a test needs to be written.

Remaining tasks

Figure out what to do and do it, and write a test for the Component class.

User interface changes

None.

API changes

Not really, except the Component class might actually work.

Data model changes

None.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

jhodgdon created an issue. See original summary.

jhodgdon’s picture

Status: Active » Needs review
FileSize
1.24 KB

Here is a patch that fixes my tests (no exceptions now). Doesn't add a test for the Core stuff...

amateescu’s picture

Issue tags: +Needs tests

Looking at the DiffFormatter class from Component, it does use this protected variable, so I think option a) from the IS (and the patch from #2) is the way to go :)

jhodgdon’s picture

Agreed. The other option would be to remove those two lines from the Component format() method, and override it in the Core format() method, because that's the only use of it in the Component (setting the values, never reads them), and the Core class is what actually I think does something with them.

Anyway it does need a test. I have a failing test on #2394603: Add tests for Drush commands but that's not going to help much... Easy to make a pure core test though. I'll see what I can do.

jhodgdon’s picture

OK, here's a patch with a simple test, and a test-only patch. Tests passes locally with the patched diffformatter classes... let's see what the bot thinks (and hopefully amateescu).

I didn't make an interdiff. The only difference is the added test.

Status: Needs review » Needs work

The last submitted patch, 5: 2824410-fix-line-stats-test-only-FAIL.patch, failed testing.

jhodgdon’s picture

Status: Needs work » Needs review

The test-only patch is failing as expected, with:
Undefined property: Drupal\Component\Diff\DiffFormatter::$line_stats

So I think this is ready to go.

@amateescu, care to review this fairly simple test and patch? The test could probably be improved, but at least it provides a basic test of the DiffFormatter component (and the Diff component as a by-product).

dawehner’s picture

Status: Needs review » Reviewed & tested by the community
+++ b/core/tests/Drupal/Tests/Component/Diff/DiffFormatterTest.php
@@ -0,0 +1,55 @@
+      'empty' => ['', [], []],
+      'add' => ["3a3\n> line2a\n",

Nice, named tests

amateescu’s picture

Looks good to me as well :)

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Nice find and great to see a test :)

Committed and pushed 3408c30 to 8.3.x and ad68e1b to 8.2.x. Thanks!

diff --git a/core/tests/Drupal/Tests/Component/Diff/DiffFormatterTest.php b/core/tests/Drupal/Tests/Component/Diff/DiffFormatterTest.php
index 8ea73fc..402e291 100644
--- a/core/tests/Drupal/Tests/Component/Diff/DiffFormatterTest.php
+++ b/core/tests/Drupal/Tests/Component/Diff/DiffFormatterTest.php
@@ -24,15 +24,18 @@ class DiffFormatterTest extends \PHPUnit_Framework_TestCase {
   public function provideTestDiff() {
     return [
       'empty' => ['', [], []],
-      'add' => ["3a3\n> line2a\n",
+      'add' => [
+        "3a3\n> line2a\n",
         ['line1', 'line2', 'line3'],
         ['line1', 'line2', 'line2a', 'line3'],
       ],
-      'delete' => ["3d3\n< line2a\n",
+      'delete' => [
+        "3d3\n< line2a\n",
         ['line1', 'line2', 'line2a', 'line3'],
         ['line1', 'line2', 'line3'],
       ],
-      'change' => ["3c3\n< line2a\n---\n> line2b\n",
+      'change' => [
+        "3c3\n< line2a\n---\n> line2b\n",
         ['line1', 'line2', 'line2a', 'line3'],
         ['line1', 'line2', 'line2b', 'line3'],
       ],

Minor code style fixes on commit.

diff --git a/core/tests/Drupal/Tests/Component/Diff/DiffFormatterTest.php b/core/tests/Drupal/Tests/Component/Diff/DiffFormatterTest.php
index 402e291..70fb0dc 100644
--- a/core/tests/Drupal/Tests/Component/Diff/DiffFormatterTest.php
+++ b/core/tests/Drupal/Tests/Component/Diff/DiffFormatterTest.php
@@ -4,7 +4,6 @@
 
 use Drupal\Component\Diff\Diff;
 use Drupal\Component\Diff\DiffFormatter;
-use Drupal\Tests\UnitTestCase;
 
 /**
  * Test DiffFormatter classes.

There's been some debate about this is other issues with people seemingly falling on the use Drupal\Tests\UnitTestCase side because it's "consistent". Given that this test is way away from the container and using config etc. \PHPUnit_Framework_TestCase is absolutely fine. All the other tests in Drupal\Tests\Component\Diff are using it and I think all of the component tests should be because components are supposed to be separate from the application. Removed unused use.

  • alexpott committed 3408c30 on 8.3.x
    Issue #2824410 by jhodgdon: DiffFormatter component class has leak from...

  • alexpott committed ad68e1b on 8.2.x
    Issue #2824410 by jhodgdon: DiffFormatter component class has leak from...

Status: Fixed » Closed (fixed)

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