buildSimplifier()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 9
nc 1
nop 0
1
<?php
2
3
namespace PPP\Wikidata\TreeSimplifier;
4
5
use DataValues\StringValue;
6
use PPP\DataModel\AbstractNode;
7
use PPP\DataModel\IntersectionNode;
8
use PPP\DataModel\MissingNode;
9
use PPP\DataModel\ResourceListNode;
10
use PPP\DataModel\StringResourceNode;
11
use PPP\DataModel\TripleNode;
12
use PPP\Wikidata\WikibaseResourceNode;
13
use Wikibase\DataModel\Entity\EntityIdValue;
14
use Wikibase\DataModel\Entity\Item;
15
use Wikibase\DataModel\Entity\ItemId;
16
use Wikibase\DataModel\Entity\Property;
17
use Wikibase\DataModel\Entity\PropertyId;
18
use Wikibase\DataModel\Snak\PropertyValueSnak;
19
use Wikibase\EntityStore\InMemory\InMemoryEntityStore;
20
21
/**
22
 * @covers PPP\Wikidata\TreeSimplifier\IntersectionWithFilterNodeSimplifierTest
23
 *
24
 * @licence AGPLv3+
25
 * @author Thomas Pellissier Tanon
26
 */
27
class IntersectionWithFilterNodeSimplifierTest extends NodeSimplifierBaseTest {
28
29
	public function buildSimplifier() {
30
		$nodeSimplifierFactoryMock = $this->getMockBuilder('PPP\Module\TreeSimplifier\NodeSimplifierFactory')
31
			->disableOriginalConstructor()
32
			->getMock();
33
		$entityStoreMock = $this->getMock('Wikibase\EntityStore\EntityStore');
34
		$resourceListNodeParserMock = $this->getMockBuilder('PPP\Wikidata\ValueParsers\ResourceListNodeParser')
35
			->disableOriginalConstructor()
36
			->getMock();
37
38
		return new IntersectionWithFilterNodeSimplifier($nodeSimplifierFactoryMock, $entityStoreMock, $resourceListNodeParserMock);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return new \PPP\Wikidata...rceListNodeParserMock); (PPP\Wikidata\TreeSimplif...ithFilterNodeSimplifier) is incompatible with the return type declared by the abstract method PPP\Wikidata\TreeSimplif...seTest::buildSimplifier of type PPP\Wikidata\TreeSimplifier\NodeSimplifier.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
39
	}
40
41
	public function simplifiableProvider() {
42
		return array(
43
			array(
44
				new IntersectionNode(array())
45
			),
46
		);
47
	}
48
49
	public function nonSimplifiableProvider() {
50
		return array(
51
			array(
52
				new MissingNode()
53
			),
54
			array(
55
				new TripleNode(
56
					new ResourceListNode(array(new WikibaseResourceNode('', new EntityIdValue(new ItemId('Q42'))))),
57
					new MissingNode(),
58
					new ResourceListNode(array(new WikibaseResourceNode('', new StringValue('113230702'))))
59
				)
60
			),
61
		);
62
	}
63
64
	/**
65
	 * @dataProvider simplifiedTripleProvider
66
	 */
67
	public function testSimplify(IntersectionNode $intersectionNode, AbstractNode $responseNode, IntersectionNode $recursiveCall = null, AbstractNode $recusiveResult = null, ResourceListNode $parsedBaseList, ResourceListNode $parsedPredicates, ResourceListNode $parsedObjects, array $entities) {
68
69
		$nodeSimplifierMock = $this->getMock('PPP\Module\TreeSimplifier\NodeSimplifier');
70
		$nodeSimplifierMock->expects($this->any())
71
			->method('simplify')
72
			->with($this->equalTo($recursiveCall))
73
			->will($this->returnValue($recusiveResult));
74
75
		$nodeSimplifierFactoryMock = $this->getMockBuilder('PPP\Module\TreeSimplifier\NodeSimplifierFactory')
76
			->disableOriginalConstructor()
77
			->getMock();
78
		$nodeSimplifierFactoryMock->expects($this->any())
79
			->method('newNodeSimplifier')
80
			->will($this->returnValue($nodeSimplifierMock));
81
82
		$resourceListNodeParserMock = $this->getMockBuilder('PPP\Wikidata\ValueParsers\ResourceListNodeParser')
83
			->disableOriginalConstructor()
84
			->getMock();
85
		$resourceListNodeParserMock->expects($this->any())
86
			->method('parse')
87
			->will($this->onConsecutiveCalls(
88
				$parsedBaseList,
89
				$parsedPredicates,
90
				$parsedObjects
91
			));
92
93
		$simplifier = new IntersectionWithFilterNodeSimplifier(
94
			$nodeSimplifierFactoryMock,
95
			new InMemoryEntityStore($entities),
96
			$resourceListNodeParserMock
97
		);
98
99
		$this->assertEquals(
100
			$responseNode,
101
			$simplifier->simplify($intersectionNode)
102
		);
103
	}
104
105
	public function simplifiedTripleProvider() {
106
		$q42 = new Item(new ItemId('Q42'));
107
		$q42->getStatements()->addNewStatement(new PropertyValueSnak(new PropertyId('P214'), new StringValue('113230702')));
108
109
		return array(
110
			array(
111
				new IntersectionNode(array(new ResourceListNode())),
112
				new IntersectionNode(array(new ResourceListNode())),
113
				null,
114
				null,
115
				new ResourceListNode(),
116
				new ResourceListNode(),
117
				new ResourceListNode(),
118
				array()
119
			),
120
			array(
121
				new IntersectionNode(array(new TripleNode(
122
					new MissingNode(),
123
					new ResourceListNode(array(new WikibaseResourceNode('', new EntityIdValue(new PropertyId('P214'))))),
124
					new ResourceListNode(array(new WikibaseResourceNode('', new StringValue('113230702'))))
125
				))),
126
				new IntersectionNode(array(new TripleNode(
127
					new MissingNode(),
128
					new ResourceListNode(array(new WikibaseResourceNode('', new EntityIdValue(new PropertyId('P214'))))),
129
					new ResourceListNode(array(new WikibaseResourceNode('', new StringValue('113230702'))))
130
				))),
131
				null,
132
				null,
133
				new ResourceListNode(),
134
				new ResourceListNode(),
135
				new ResourceListNode(),
136
				array()
137
			),
138
			array(
139
				new IntersectionNode(array(
140
					new MissingNode(),
141
					new TripleNode(
142
						new MissingNode(),
143
						new ResourceListNode(array(new WikibaseResourceNode('', new EntityIdValue(new PropertyId('P214'))))),
144
						new ResourceListNode(array(new WikibaseResourceNode('', new StringValue('113230702'))))
145
					)
146
				)),
147
				new IntersectionNode(array(
148
					new TripleNode(
149
						new MissingNode(),
150
						new ResourceListNode(array(new WikibaseResourceNode('', new EntityIdValue(new PropertyId('P214'))))),
151
						new ResourceListNode(array(new WikibaseResourceNode('', new StringValue('113230702'))))
152
					),
153
					new MissingNode()
154
				)),
155
				new IntersectionNode(array(new MissingNode())),
156
				new MissingNode(),
157
				new ResourceListNode(),
158
				new ResourceListNode(),
159
				new ResourceListNode(),
160
				array()
161
			),
162
			array(
163
				new IntersectionNode(array(
164
					new ResourceListNode(array(
165
						new WikibaseResourceNode('', new EntityIdValue(new ItemId('Q42'))),
166
						new WikibaseResourceNode('', new EntityIdValue(new ItemId('Q43')))
167
					)),
168
					new TripleNode(
169
						new MissingNode(),
170
						new ResourceListNode(array(new WikibaseResourceNode('', new EntityIdValue(new PropertyId('P214'))))),
171
						new ResourceListNode(array(new WikibaseResourceNode('', new StringValue('113230702'))))
172
					)
173
				)),
174
				new ResourceListNode(array(new WikibaseResourceNode('', new EntityIdValue(new ItemId('Q42'))))),
175
				new IntersectionNode(array(new ResourceListNode(array(
176
					new WikibaseResourceNode('', new EntityIdValue(new ItemId('Q42'))),
177
					new WikibaseResourceNode('', new EntityIdValue(new ItemId('Q43')))
178
				)))),
179
				new ResourceListNode(array(
180
					new WikibaseResourceNode('', new EntityIdValue(new ItemId('Q42'))),
181
					new WikibaseResourceNode('', new EntityIdValue(new ItemId('Q43')))
182
				)),
183
				new ResourceListNode(array(
184
					new WikibaseResourceNode('', new EntityIdValue(new ItemId('Q42'))),
185
					new WikibaseResourceNode('', new EntityIdValue(new ItemId('Q43')))
186
				)),
187
				new ResourceListNode(array(new WikibaseResourceNode('', new EntityIdValue(new PropertyId('P214'))))),
188
				new ResourceListNode(array(new WikibaseResourceNode('', new StringValue('113230702')))),
189
				array(
190
					$q42,
191
					new Item(new ItemId('Q43')),
192
					new Property(new PropertyId('P214'), null, 'string')
193
				)
194
			),
195
			array(
196
				new IntersectionNode(array(
197
					new ResourceListNode(array(
198
						new WikibaseResourceNode('', new EntityIdValue(new ItemId('Q42'))),
199
						new StringResourceNode('foo')
200
					)),
201
					new TripleNode(
202
						new MissingNode(),
203
						new ResourceListNode(array(new StringResourceNode('VIAF'))),
204
						new ResourceListNode(array(new StringResourceNode('113230702')))
205
					)
206
				)),
207
				new ResourceListNode(array(new WikibaseResourceNode('', new EntityIdValue(new ItemId('Q42'))))),
208
				new IntersectionNode(array(new ResourceListNode(array(
209
					new WikibaseResourceNode('', new EntityIdValue(new ItemId('Q42'))),
210
					new StringResourceNode('foo')
211
				)))),
212
				new ResourceListNode(array(
213
					new WikibaseResourceNode('', new EntityIdValue(new ItemId('Q42'))),
214
					new StringResourceNode('foo')
215
				)),
216
				new ResourceListNode(array(
217
					new WikibaseResourceNode('', new EntityIdValue(new ItemId('Q42'))),
218
					new WikibaseResourceNode('', new EntityIdValue(new ItemId('Q43')))
219
				)),
220
				new ResourceListNode(array(new WikibaseResourceNode('', new EntityIdValue(new PropertyId('P214'))))),
221
				new ResourceListNode(array(new WikibaseResourceNode('', new StringValue('113230702')))),
222
				array(
223
					$q42,
224
					new Item(new ItemId('Q43')),
225
					new Property(new PropertyId('P214'), null, 'string')
226
				)
227
			),
228
		);
229
	}
230
}
231