DiffOpOutputBuilder does not correctly match the 10.0.x implementation and produces unexpected output (part 2)

Created on 12 September 2023, about 1 year ago
Updated 14 September 2023, about 1 year ago

Problem/Motivation

The \Drupal\Component\Diff\DiffOpOutputBuilder implementation added in 📌 Deprecate DiffEngine and replace with sebastian/diff Fixed doesn't match the ouput of 10.0.x diffing. This results in test failures for the update_helper module on 10.1.x.

Steps to reproduce


$a = <<<EOF
persist_with_no_fields : b:1;
settings : a:0:{}
status : b:1;
translatable : b:1;
type : s:17:"text_with_summary";
EOF;

$b = <<<EOF
persist_with_no_fields : b:1;
settings
settings::max_length : i:123;
status : b:1;
translatable : b:1;
type : s:4:"text";
EOF;

$a = explode("\n", $a);
$b = explode("\n", $b);

$diff = new \Drupal\Component\Diff\Diff($a, $b);

dump($diff->getEdits());

On 10.0.x this produces:

^ array:4 [
  0 => Drupal\Component\Diff\Engine\DiffOpCopy^ {#1971
    +type: "copy"
    +orig: array:1 [
      0 => "persist_with_no_fields : b:1;"
    ]
    +closing: array:1 [
      0 => "persist_with_no_fields : b:1;"
    ]
  }
  1 => Drupal\Component\Diff\Engine\DiffOpChange^ {#1973
    +type: "change"
    +orig: array:1 [
      0 => "settings : a:0:{}"
    ]
    +closing: array:2 [
      0 => "settings"
      1 => "settings::max_length : i:123;"
    ]
  }
  2 => Drupal\Component\Diff\Engine\DiffOpCopy^ {#1944
    +type: "copy"
    +orig: array:2 [
      0 => "status : b:1;"
      1 => "translatable : b:1;"
    ]
    +closing: array:2 [
      0 => "status : b:1;"
      1 => "translatable : b:1;"
    ]
  }
  3 => Drupal\Component\Diff\Engine\DiffOpChange^ {#1943
    +type: "change"
    +orig: array:1 [
      0 => "type : s:17:"text_with_summary";"
    ]
    +closing: array:1 [
      0 => "type : s:4:"text";"
    ]
  }
]

On 10.1.x this produces:

^ array:5 [
  0 => Drupal\Component\Diff\Engine\DiffOpCopy^ {#1971
    +type: "copy"
    +orig: array:1 [
      0 => "persist_with_no_fields : b:1;"
    ]
    +closing: array:1 [
      0 => "persist_with_no_fields : b:1;"
    ]
  }
  1 => Drupal\Component\Diff\Engine\DiffOpChange^ {#1973
    +type: "change"
    +orig: array:1 [
      0 => "settings : a:0:{}"
    ]
    +closing: array:1 [
      0 => "settings"
    ]
  }
  2 => Drupal\Component\Diff\Engine\DiffOpAdd^ {#1944
    +type: "add"
    +orig: false
    +closing: array:1 [
      0 => "settings::max_length : i:123;"
    ]
  }
  3 => Drupal\Component\Diff\Engine\DiffOpCopy^ {#1943
    +type: "copy"
    +orig: array:2 [
      0 => "status : b:1;"
      1 => "translatable : b:1;"
    ]
    +closing: array:2 [
      0 => "status : b:1;"
      1 => "translatable : b:1;"
    ]
  }
  4 => Drupal\Component\Diff\Engine\DiffOpChange^ {#1974
    +type: "change"
    +orig: array:1 [
      0 => "type : s:17:"text_with_summary";"
    ]
    +closing: array:1 [
      0 => "type : s:4:"text";"
    ]
  }
]

Proposed resolution

This is due to how DiffOpOutputBuilder changes a series of deletions and additions into a change.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

🐛 Bug report
Status

Fixed

Version

10.1

Component
Base 

Last updated 3 minutes ago

Created by

🇬🇧United Kingdom alexpott 🇪🇺🌍

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Production build 0.71.5 2024