Thiemo Kreuz (WMDE) has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/405697 )

Change subject: Fix incomplete Form diffing not covering adding/removal of Forms
......................................................................

Fix incomplete Form diffing not covering adding/removal of Forms

Forms can not only change, Forms can also be added and removed. This
was just not covered by the code yet. The diff failed hard with quite
extreme exceptions.

This becomes obvious very easily if you try to compare two different
Lexemes, e.g. …?oldid=…&diff=… with two revision IDs from two different
Lexemes. (Which is a quite typical use case, e.g. if two entities are
duplicates and the user wants to compare the two.)

Bug: T185477
Change-Id: I9ba8622f5b060d76a7915d9bd74383b39d76fb3f
---
M src/DataModel/Services/Diff/FormDiffer.php
M src/DataModel/Services/Diff/LexemeDiffer.php
M src/Diff/FormDiffView.php
3 files changed, 58 insertions(+), 24 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/WikibaseLexeme 
refs/changes/97/405697/1

diff --git a/src/DataModel/Services/Diff/FormDiffer.php 
b/src/DataModel/Services/Diff/FormDiffer.php
index f869063..6f2fa4e 100644
--- a/src/DataModel/Services/Diff/FormDiffer.php
+++ b/src/DataModel/Services/Diff/FormDiffer.php
@@ -4,13 +4,15 @@
 
 use Diff\Differ\MapDiffer;
 use Diff\DiffOp\Diff\Diff;
-use DomainException;
 use InvalidArgumentException;
 use Wikibase\DataModel\Entity\EntityDocument;
 use Wikibase\DataModel\Services\Diff\EntityDiff;
 use Wikibase\DataModel\Services\Diff\EntityDifferStrategy;
 use Wikibase\DataModel\Services\Diff\StatementListDiffer;
+use Wikibase\DataModel\Term\Term;
+use Wikibase\DataModel\Term\TermList;
 use Wikibase\Lexeme\DataModel\Form;
+use Wikibase\Lexeme\DataModel\FormId;
 
 /**
  * @license GPL-2.0+
@@ -42,8 +44,8 @@
        }
 
        /**
-        * @param EntityDocument $from
-        * @param EntityDocument $to
+        * @param Form $from
+        * @param Form $to
         *
         * @return EntityDiff
         * @throws InvalidArgumentException
@@ -57,30 +59,40 @@
        }
 
        /**
-        * @param EntityDocument $entity
+        * @param Form $form
         *
         * @return EntityDiff
         * @throws InvalidArgumentException
         */
-       public function getConstructionDiff( EntityDocument $entity ) {
-               throw new DomainException( 'Forms aren\'t stored as separate 
wiki pages, and can only show '
-                       . 'up in regular diffs that add or remove a Form' );
+       public function getConstructionDiff( EntityDocument $form ) {
+               if ( !( $form instanceof Form ) ) {
+                       throw new InvalidArgumentException( 'Can only diff 
Forms' );
+               }
+
+               return $this->diff( $this->newEmptyForm( $form->getId() ), 
$form );
        }
 
        /**
-        * @param EntityDocument $entity
+        * @param Form $form
         *
         * @return EntityDiff
         * @throws InvalidArgumentException
         */
-       public function getDestructionDiff( EntityDocument $entity ) {
-               throw new DomainException( 'Forms aren\'t stored as separate 
wiki pages, and can only show '
-                       . 'up in regular diffs that add or remove a Form' );
+       public function getDestructionDiff( EntityDocument $form ) {
+               if ( !( $form instanceof Form ) ) {
+                       throw new InvalidArgumentException( 'Can only diff 
Forms' );
+               }
+
+               return $this->diff( $form, $this->newEmptyForm( $form->getId() 
) );
+       }
+
+       private function newEmptyForm( FormId $id ) {
+               $form = new Form( $id, new TermList( [ new Term( 'dummy', 
'dummy' ) ] ), [] );
+               $form->getRepresentations()->clear();
+               return $form;
        }
 
        /**
-        * @deprecated use self::diffEntities instead
-        *
         * @param Form $old
         * @param Form $new
         *
diff --git a/src/DataModel/Services/Diff/LexemeDiffer.php 
b/src/DataModel/Services/Diff/LexemeDiffer.php
index 1494c7e..e59fdce 100644
--- a/src/DataModel/Services/Diff/LexemeDiffer.php
+++ b/src/DataModel/Services/Diff/LexemeDiffer.php
@@ -4,7 +4,10 @@
 
 use Diff\Differ\MapDiffer;
 use Diff\DiffOp\Diff\Diff;
+use Diff\DiffOp\DiffOpAdd;
 use Diff\DiffOp\DiffOpChange;
+use Diff\DiffOp\DiffOpRemove;
+use LogicException;
 use UnexpectedValueException;
 use Wikibase\DataModel\Entity\EntityDocument;
 use Wikibase\DataModel\Services\Diff\EntityDiff;
@@ -153,7 +156,7 @@
         * @param FormSet $from
         * @param FormSet $to
         *
-        * @return Diff;
+        * @return Diff
         */
        private function getFormsDiff( FormSet $from, FormSet $to ) {
                $differ = new MapDiffer();
@@ -167,13 +170,28 @@
                $formDiffOps = $differ->doDiff( $from, $to );
 
                foreach ( $formDiffOps as $index => $formDiffOp ) {
-                       if ( $formDiffOp instanceof DiffOpChange ) {
-                               /** @var DiffOpChange $formDiffOp */
-                               $formDiffOps[$index] = $this->formDiffer->diff(
-                                       $formDiffOp->getOldValue(),
-                                       $formDiffOp->getNewValue()
-                               );
+                       switch ( true ) {
+                               case $formDiffOp instanceof DiffOpChange:
+                                       $formDiffOps[$index] = 
$this->formDiffer->diffEntities(
+                                               $formDiffOp->getOldValue(),
+                                               $formDiffOp->getNewValue()
+                                       );
+                                       break;
 
+                               case $formDiffOp instanceof DiffOpAdd:
+                                       $formDiffOps[$index] = 
$this->formDiffer->getConstructionDiff(
+                                               $formDiffOp->getNewValue()
+                                       );
+                                       break;
+
+                               case $formDiffOp instanceof DiffOpRemove:
+                                       $formDiffOps[$index] = 
$this->formDiffer->getDestructionDiff(
+                                               $formDiffOp->getOldValue()
+                                       );
+                                       break;
+
+                               default:
+                                       throw new LogicException( 'Invalid form 
diff' );
                        }
                }
 
diff --git a/src/Diff/FormDiffView.php b/src/Diff/FormDiffView.php
index 1d82223..46484bb 100644
--- a/src/Diff/FormDiffView.php
+++ b/src/Diff/FormDiffView.php
@@ -65,22 +65,26 @@
         * @throws MWException
         */
        protected function generateOpHtml( array $path, DiffOp $op ) {
-               $html = '';
                if ( $op->isAtomic() ) {
                        return parent::generateOpHtml( $path, $op );
                }
+
+               $html = '';
+
                foreach ( $op as $key => $subOp ) {
-                       if ( !$subOp instanceof ChangeFormDiffOp ) {
-                               $html .= $this->generateOpHtml( array_merge( 
$path, [ $key ] ), $subOp );
-                       } else {
+                       if ( $subOp instanceof ChangeFormDiffOp ) {
                                $html .= $this->generateFormOpHtml( $path, 
$subOp, $key );
+                       } else {
+                               $html .= $this->generateOpHtml( array_merge( 
$path, [ $key ] ), $subOp );
                        }
                }
+
                return $html;
        }
 
        private function generateFormOpHtml( $path, ChangeFormDiffOp $op, $key 
) {
                $html = '';
+
                foreach ( $op->getStatementsDiffOps() as $claimDiffOp ) {
                        $html .= $this->getClaimDiffHtml(
                                $claimDiffOp,

-- 
To view, visit https://gerrit.wikimedia.org/r/405697
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I9ba8622f5b060d76a7915d9bd74383b39d76fb3f
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/WikibaseLexeme
Gerrit-Branch: master
Gerrit-Owner: Thiemo Kreuz (WMDE) <thiemo.kr...@wikimedia.de>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to