Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
40.00% covered (danger)
40.00%
16 / 40
33.33% covered (danger)
33.33%
3 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
SenseDiffer
40.00% covered (danger)
40.00%
16 / 40
33.33% covered (danger)
33.33%
3 / 9
37.14
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 canDiffEntityType
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 diffEntities
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
3.33
 getConstructionDiff
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getDestructionDiff
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 diff
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
1
 getAddSenseDiff
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
2
 getRemoveSenseDiff
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
2
 toSenseDiffArray
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3// @phan-file-suppress PhanPluginNeverReturnMethod
4
5namespace Wikibase\Lexeme\Domain\Diff;
6
7use Diff\Differ\MapDiffer;
8use Diff\DiffOp\Diff\Diff;
9use DomainException;
10use InvalidArgumentException;
11use Wikibase\DataModel\Entity\EntityDocument;
12use Wikibase\DataModel\Services\Diff\EntityDiff;
13use Wikibase\DataModel\Services\Diff\EntityDifferStrategy;
14use Wikibase\DataModel\Services\Diff\StatementListDiffer;
15use Wikibase\DataModel\Statement\StatementList;
16use Wikibase\Lexeme\Domain\Model\Sense;
17
18/**
19 * @license GPL-2.0-or-later
20 */
21class SenseDiffer implements EntityDifferStrategy {
22
23    /**
24     * @var MapDiffer
25     */
26    private $recursiveMapDiffer;
27
28    /**
29     * @var StatementListDiffer
30     */
31    private $statementListDiffer;
32
33    public function __construct() {
34        $this->recursiveMapDiffer = new MapDiffer( true );
35        $this->statementListDiffer = new StatementListDiffer();
36    }
37
38    /**
39     * @param string $entityType
40     *
41     * @return bool
42     */
43    public function canDiffEntityType( $entityType ) {
44        return $entityType === 'sense';
45    }
46
47    /**
48     * @param EntityDocument $from
49     * @param EntityDocument $to
50     *
51     * @return EntityDiff
52     * @throws InvalidArgumentException
53     */
54    public function diffEntities( EntityDocument $from, EntityDocument $to ) {
55        if ( !( $from instanceof Sense ) || !( $to instanceof Sense ) ) {
56            throw new InvalidArgumentException( 'Can only diff Senses' );
57        }
58
59        return $this->diff( $from, $to );
60    }
61
62    /**
63     * @param EntityDocument $entity
64     *
65     * @return EntityDiff
66     * @throws InvalidArgumentException
67     */
68    public function getConstructionDiff( EntityDocument $entity ) {
69        throw new DomainException( 'Sense aren\'t stored as separate wiki pages, and can only show '
70            . 'up in regular diffs that add or remove a Sense' );
71    }
72
73    /**
74     * @param EntityDocument $entity
75     *
76     * @return EntityDiff
77     * @throws InvalidArgumentException
78     */
79    public function getDestructionDiff( EntityDocument $entity ) {
80        throw new DomainException( 'Senses aren\'t stored as separate wiki pages, and can only show '
81            . 'up in regular diffs that add or remove a Sense' );
82    }
83
84    /**
85     * @param Sense $old
86     * @param Sense $new
87     *
88     * @return ChangeSenseDiffOp
89     */
90    private function diff( Sense $old, Sense $new ) {
91        // TODO: Assert same ID
92        $diffOps = $this->recursiveMapDiffer->doDiff(
93            $this->toSenseDiffArray( $old ),
94            $this->toSenseDiffArray( $new )
95        );
96
97        $diffOps['claim'] = $this->statementListDiffer->getDiff(
98            $old->getStatements(),
99            $new->getStatements()
100        );
101
102        return new ChangeSenseDiffOp( $old->getId(), new Diff( $diffOps ) );
103    }
104
105    public function getAddSenseDiff( Sense $sense ): SenseDiff {
106        $diffOps = $this->recursiveMapDiffer->doDiff(
107            [],
108            $this->toSenseDiffArray( $sense )
109        );
110        $diffOps['claim'] = $this->statementListDiffer->getDiff(
111            new StatementList(),
112            $sense->getStatements()
113        );
114
115        return new AddSenseDiff( $sense, new Diff( $diffOps ) );
116    }
117
118    public function getRemoveSenseDiff( Sense $sense ): SenseDiff {
119        $diffOps = $this->recursiveMapDiffer->doDiff(
120            $this->toSenseDiffArray( $sense ),
121            []
122        );
123        $diffOps['claim'] = $this->statementListDiffer->getDiff(
124            $sense->getStatements(),
125            new StatementList()
126        );
127
128        return new RemoveSenseDiff( $sense->getId(), new Diff( $diffOps ) );
129    }
130
131    /**
132     * @param Sense $sense
133     *
134     * @return string[][]
135     */
136    private function toSenseDiffArray( Sense $sense ) {
137        $result = [];
138        $result['glosses'] = $sense->getGlosses()->toTextArray();
139
140        return $result;
141    }
142
143}