Completed
Push — master ( 5d1976...30add5 )
by mw
13s
created

phpunit/includes/export/ExportSemanticDataTest.php (22 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace SMW\Tests\Export;
4
5
use SMW\DataValueFactory;
6
use SMW\DIProperty;
7
use SMW\DIWikiPage;
8
use SMW\Exporter\Escaper;
9
use SMW\Subobject;
10
use SMW\Tests\Utils\Fixtures\FixturesProvider;
11
use SMW\Tests\Utils\SemanticDataFactory;
12
use SMW\Tests\Utils\Validators\ExportDataValidator;
13
use SMWExpNsResource as ExpNsResource;
14
use SMWExporter as Exporter;
15
use SMWExpResource as ExpResource;
16
17
/**
18
 * @covers \SMWExporter
19
 *
20
 *
21
 * @group SMW
22
 * @group SMWExtension
23
 *
24
 * @license GNU GPL v2+
25
 * @since 2.0
26
 *
27
 * @author mwjames
28
 */
29
class ExportSemanticDataTest extends \PHPUnit_Framework_TestCase {
30
31
	private $semanticDataFactory;
32
	private $dataValueFactory;
33
	private $exportDataValidator;
34
	private $fixturesProvider;
35
36
	protected function setUp() {
37
		parent::setUp();
38
39
		$this->dataValueFactory = DataValueFactory::getInstance();
40
		$this->semanticDataFactory = new SemanticDataFactory();
41
		$this->exportDataValidator = new ExportDataValidator();
42
43
		$this->fixturesProvider = new FixturesProvider();
44
	}
45
46
	public function testExportRedirect() {
47
48
		$semanticData = $this->semanticDataFactory->newEmptySemanticData( __METHOD__ );
49
50
		$redirectProperty = new DIProperty( '_REDI' );
51
		$redirectTarget = new DIWikiPage( 'FooRedirectTarget', NS_MAIN, '' );
52
53
		$semanticData->addPropertyObjectValue(
54
			$redirectProperty,
55
			DIWikiPage::newFromTitle( $redirectTarget->getTitle(), '__red' )
0 ignored issues
show
It seems like $redirectTarget->getTitle() can be null; however, newFromTitle() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
The call to DIWikiPage::newFromTitle() has too many arguments starting with '__red'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
56
		);
57
58
		$exportData = Exporter::getInstance()->makeExportData( $semanticData );
0 ignored issues
show
$semanticData of type object<SMW\SemanticData> is not a sub-type of object<SMWSemanticData>. It seems like you assume a child class of the class SMW\SemanticData to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
59
60
		$this->assertCount(
61
			1,
62
			$exportData->getValues( Exporter::getInstance()->getSpecialNsResource( 'swivt', 'redirectsTo' ) )
0 ignored issues
show
\SMWExporter::getInstanc...'swivt', 'redirectsTo') is of type object<SMW\Exporter\Element\ExpNsResource>, but the function expects a object<SMWExpResource>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
63
		);
64
65
		$this->assertCount(
66
			1,
67
			$exportData->getValues( Exporter::getInstance()->getSpecialNsResource(  'owl', 'sameAs' ) )
0 ignored issues
show
\SMWExporter::getInstanc...source('owl', 'sameAs') is of type object<SMW\Exporter\Element\ExpNsResource>, but the function expects a object<SMWExpResource>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
68
		);
69
70
		$expectedResourceElement = new ExpNsResource(
71
			'FooRedirectTarget',
72
			Exporter::getInstance()->getNamespaceUri( 'wiki' ),
73
			'wiki',
74
			$redirectTarget
75
		);
76
77
		$this->exportDataValidator->assertThatExportDataContainsResource(
78
			$expectedResourceElement,
79
			Exporter::getInstance()->getSpecialNsResource( 'owl', 'sameAs' ),
80
			$exportData
81
		);
82
	}
83
84
	public function testExportPageWithNumericProperty() {
85
86
		$semanticData = $this->semanticDataFactory->newEmptySemanticData( __METHOD__ );
87
88
		$property = new DIProperty( '123' );
89
90
		$semanticData->addPropertyObjectValue(
91
			$property,
92
			new DIWikiPage( '345', NS_MAIN )
93
		);
94
95
		$exportData = Exporter::getInstance()->makeExportData( $semanticData );
0 ignored issues
show
$semanticData of type object<SMW\SemanticData> is not a sub-type of object<SMWSemanticData>. It seems like you assume a child class of the class SMW\SemanticData to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
96
97
		$expectedProperty = new ExpNsResource(
98
			Escaper::encodePage( $property->getDiWikiPage() ),
0 ignored issues
show
It seems like $property->getDiWikiPage() can be null; however, encodePage() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
99
			Exporter::getInstance()->getNamespaceUri( 'wiki' ),
100
			'wiki',
101
			new DIWikiPage( '123', SMW_NS_PROPERTY )
102
		);
103
104
		$this->assertCount(
105
			1,
106
			$exportData->getValues( $expectedProperty )
107
		);
108
109
		$this->exportDataValidator->assertThatExportDataContainsProperty(
110
			$expectedProperty,
111
			$exportData
112
		);
113
114
		$expectedResourceElement = new ExpNsResource(
115
			'345',
116
			Exporter::getInstance()->getNamespaceUri( 'wiki' ),
117
			'wiki',
118
			new DIWikiPage( '345', NS_MAIN )
119
		);
120
121
		$this->exportDataValidator->assertThatExportDataContainsResource(
122
			$expectedResourceElement,
123
			$expectedProperty,
124
			$exportData
125
		);
126
	}
127
128
	public function testExportPageWithNonNumericProperty() {
129
130
		$semanticData = $this->semanticDataFactory->newEmptySemanticData( __METHOD__ );
131
132
		$property = new DIProperty( 'A123' );
133
134
		$semanticData->addPropertyObjectValue(
135
			$property,
136
			new DIWikiPage( '345', NS_MAIN )
137
		);
138
139
		$exportData = Exporter::getInstance()->makeExportData( $semanticData );
0 ignored issues
show
$semanticData of type object<SMW\SemanticData> is not a sub-type of object<SMWSemanticData>. It seems like you assume a child class of the class SMW\SemanticData to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
140
141
		$expectedProperty = new ExpNsResource(
142
			'A123',
143
			Exporter::getInstance()->getNamespaceUri( 'property' ),
144
			'property',
145
			new DIWikiPage( 'A123', SMW_NS_PROPERTY )
146
		);
147
148
		$this->assertCount(
149
			1,
150
			$exportData->getValues( $expectedProperty )
151
		);
152
153
		$this->exportDataValidator->assertThatExportDataContainsProperty(
154
			$expectedProperty,
155
			$exportData
156
		);
157
158
		$expectedResource = new ExpNsResource(
159
			'345',
160
			Exporter::getInstance()->getNamespaceUri( 'wiki' ),
161
			'wiki',
162
			new DIWikiPage( '345', NS_MAIN )
163
		);
164
165
		$this->exportDataValidator->assertThatExportDataContainsResource(
166
			$expectedResource,
167
			$expectedProperty,
168
			$exportData
169
		);
170
	}
171
172
	public function testExportSubproperty() {
173
174
		$semanticData = $this->semanticDataFactory
175
			->setSubject( new DIWikiPage( 'SomeSubproperty', SMW_NS_PROPERTY ) )
176
			->newEmptySemanticData();
177
178
		$semanticData->addDataValue(
179
			$this->dataValueFactory->newPropertyObjectValue( new DIProperty( '_SUBP' ), 'SomeTopProperty' )
0 ignored issues
show
'SomeTopProperty' is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
180
		);
181
182
		$exportData = Exporter::getInstance()->makeExportData( $semanticData );
0 ignored issues
show
$semanticData of type object<SMW\SemanticData> is not a sub-type of object<SMWSemanticData>. It seems like you assume a child class of the class SMW\SemanticData to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
183
184
		$this->assertCount(
185
			1,
186
			$exportData->getValues( Exporter::getInstance()->getSpecialNsResource( 'rdfs', 'subPropertyOf' ) )
0 ignored issues
show
\SMWExporter::getInstanc...rdfs', 'subPropertyOf') is of type object<SMW\Exporter\Element\ExpNsResource>, but the function expects a object<SMWExpResource>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
187
		);
188
189
		$expectedResourceElement = new ExpNsResource(
190
			'SomeTopProperty',
191
			Exporter::getInstance()->getNamespaceUri( 'property' ),
192
			'property',
193
			new DIWikiPage( 'SomeTopProperty', SMW_NS_PROPERTY )
194
		);
195
196
		$this->exportDataValidator->assertThatExportDataContainsResource(
197
			$expectedResourceElement,
198
			Exporter::getInstance()->getSpecialNsResource( 'rdfs', 'subPropertyOf' ),
199
			$exportData
200
		);
201
	}
202
203
	public function testExportCategory() {
204
205
		$semanticData = $this->semanticDataFactory->newEmptySemanticData( __METHOD__ );
206
207
		$semanticData->addDataValue(
208
			$this->dataValueFactory->newPropertyObjectValue( new DIProperty( '_INST' ), 'SomeCategory' )
0 ignored issues
show
'SomeCategory' is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
209
		);
210
211
		$exportData = Exporter::getInstance()->makeExportData( $semanticData );
0 ignored issues
show
$semanticData of type object<SMW\SemanticData> is not a sub-type of object<SMWSemanticData>. It seems like you assume a child class of the class SMW\SemanticData to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
212
213
		$this->assertCount(
214
			2,
215
			$exportData->getValues( Exporter::getInstance()->getSpecialNsResource( 'rdf', 'type' ) )
0 ignored issues
show
\SMWExporter::getInstanc...Resource('rdf', 'type') is of type object<SMW\Exporter\Element\ExpNsResource>, but the function expects a object<SMWExpResource>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
216
		);
217
218
		$expectedResourceElement = new ExpNsResource(
219
			'SomeCategory',
220
			Exporter::getInstance()->getNamespaceUri( 'category' ),
221
			'category',
222
			new DIWikiPage( 'SomeCategory', NS_CATEGORY )
223
		);
224
225
		$this->exportDataValidator->assertThatExportDataContainsResource(
226
			$expectedResourceElement,
227
			Exporter::getInstance()->getSpecialNsResource( 'rdf', 'type' ),
228
			$exportData
229
		);
230
	}
231
232
	public function testExportSubcategory() {
233
234
		$semanticData = $this->semanticDataFactory
235
			->setSubject( new DIWikiPage( 'SomeSubcategory', NS_CATEGORY ) )
236
			->newEmptySemanticData();
237
238
		$semanticData->addDataValue(
239
			$this->dataValueFactory->newPropertyObjectValue( new DIProperty( '_SUBC' ), 'SomeTopCategory' )
0 ignored issues
show
'SomeTopCategory' is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
240
		);
241
242
		$exportData = Exporter::getInstance()->makeExportData( $semanticData );
0 ignored issues
show
$semanticData of type object<SMW\SemanticData> is not a sub-type of object<SMWSemanticData>. It seems like you assume a child class of the class SMW\SemanticData to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
243
244
		$this->assertCount(
245
			1,
246
			$exportData->getValues( Exporter::getInstance()->getSpecialNsResource( 'rdfs', 'subClassOf' ) )
0 ignored issues
show
\SMWExporter::getInstanc...e('rdfs', 'subClassOf') is of type object<SMW\Exporter\Element\ExpNsResource>, but the function expects a object<SMWExpResource>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
247
		);
248
249
		$expectedResourceElement = new ExpNsResource(
250
			'SomeTopCategory',
251
			Exporter::getInstance()->getNamespaceUri( 'category' ),
252
			'category',
253
			new DIWikiPage( 'SomeTopCategory', NS_CATEGORY )
254
		);
255
256
		$this->exportDataValidator->assertThatExportDataContainsResource(
257
			$expectedResourceElement,
258
			Exporter::getInstance()->getSpecialNsResource( 'rdfs', 'subClassOf' ),
259
			$exportData
260
		);
261
	}
262
263
	public function testExportSubobject() {
264
265
		$semanticData = $this->semanticDataFactory->newEmptySemanticData( __METHOD__ );
266
267
		$subobject = new Subobject( $semanticData->getSubject()->getTitle() );
0 ignored issues
show
It seems like $semanticData->getSubject()->getTitle() can be null; however, __construct() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
268
		$subobject->setEmptyContainerForId( 'Foo' );
269
270
		$semanticData->addPropertyObjectValue(
271
			$subobject->getProperty(),
272
			$subobject->getContainer()
273
		);
274
275
		$exportData = Exporter::getInstance()->makeExportData( $semanticData );
0 ignored issues
show
$semanticData of type object<SMW\SemanticData> is not a sub-type of object<SMWSemanticData>. It seems like you assume a child class of the class SMW\SemanticData to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
276
277
		$expectedProperty = new ExpNsResource(
278
			$this->transformPropertyLabelToAuxiliary( $subobject->getProperty() ),
279
			Exporter::getInstance()->getNamespaceUri( 'property' ),
280
			'property',
281
			new DIWikiPage( 'Has_subobject', SMW_NS_PROPERTY )
282
		);
283
284
		$this->assertTrue(
285
			Exporter::getInstance()->hasHelperExpElement( $subobject->getProperty() )
286
		);
287
288
		$this->assertCount(
289
			1,
290
			$exportData->getValues( $expectedProperty )
291
		);
292
293
		$this->exportDataValidator->assertThatExportDataContainsProperty(
294
			$expectedProperty,
295
			$exportData
296
		);
297
298
		$expectedResource = new ExpNsResource(
299
			Escaper::encodePage( $subobject->getSemanticData()->getSubject() ) . '-23' . 'Foo',
300
			Exporter::getInstance()->getNamespaceUri( 'wiki' ),
301
			'wiki',
302
			$subobject->getSemanticData()->getSubject()
303
		);
304
305
		$this->exportDataValidator->assertThatExportDataContainsResource(
306
			$expectedResource,
307
			$expectedProperty,
308
			$exportData
309
		);
310
	}
311
312
	public function testExportSubSemanticData() {
313
314
		$semanticData = $this->semanticDataFactory->newEmptySemanticData( __METHOD__ );
315
316
		$factsheet = $this->fixturesProvider->getFactsheet( 'berlin' );
317
		$factsheet->setTargetSubject( $semanticData->getSubject() );
318
319
		$demographicsSubobject = $factsheet->getDemographics();
320
321
		$semanticData->addPropertyObjectValue(
322
			$demographicsSubobject->getProperty(),
323
			$demographicsSubobject->getContainer()
324
		);
325
326
		$exportData = Exporter::getInstance()->makeExportData(
327
			$semanticData->findSubSemanticData( $demographicsSubobject->getSubobjectId() )
0 ignored issues
show
$semanticData->findSubSe...ject->getSubobjectId()) is of type object<SMW\SemanticData>|array, but the function expects a object<SMWSemanticData>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
328
		);
329
330
		$this->assertCount(
331
			1,
332
			$exportData->getValues( Exporter::getInstance()->getSpecialPropertyResource( '_SKEY' ) )
0 ignored issues
show
\SMWExporter::getInstanc...opertyResource('_SKEY') is of type object<SMW\Exporter\Element\ExpNsResource>|null, but the function expects a object<SMWExpResource>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
333
		);
334
335
		$this->assertCount(
336
			1,
337
			$exportData->getValues( Exporter::getInstance()->getSpecialNsResource( 'swivt', 'wikiNamespace' ) )
0 ignored issues
show
\SMWExporter::getInstanc...wivt', 'wikiNamespace') is of type object<SMW\Exporter\Element\ExpNsResource>, but the function expects a object<SMWExpResource>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
338
		);
339
	}
340
341
	private function transformPropertyLabelToAuxiliary( DIProperty $property ) {
342
		return str_replace( ' ', '_', $property->getLabel() );
343
	}
344
345
}
346