This repository has been archived by the owner on Aug 5, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTestCase.php
388 lines (344 loc) · 13.9 KB
/
TestCase.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
<?php
/*
* This file is part of Saft.
*
* (c) Konrad Abicht <[email protected]>
* (c) Natanael Arndt <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Saft\Test;
use Saft\Rdf\CommonNamespaces;
use Saft\Rdf\NodeFactoryImpl;
use Saft\Rdf\RdfHelpers;
use Saft\Rdf\Statement;
use Saft\Rdf\StatementFactoryImpl;
use Saft\Rdf\StatementIterator;
use Saft\Rdf\StatementIteratorFactoryImpl;
use Saft\Sparql\Result\Result;
use Saft\Sparql\Result\SetResult;
use Symfony\Component\Yaml\Parser;
/**
* @api
* @since 0.1
*/
abstract class TestCase extends \PHPUnit_Framework_TestCase
{
/**
* @var array
*/
protected $configuration;
protected $commonNamespaces;
/**
* Contains an instance of the class to test.
*
* @var mixed
*/
protected $fixture;
protected $nodeFactory;
protected $rdfHelpers;
protected $statementFactory;
protected $statementIteratorFactory;
/**
* @var NamedNode
*/
protected $testGraph;
/**
* http://stackoverflow.com/a/12496979
* Fixes assertEquals in case of check array equality.
*
* @param array $expected
* @param array $actual
* @param string $message optional
* @api
* @since 0.1
*/
protected function assertEqualsArrays($expected, $actual, $message = '')
{
sort($expected);
sort($actual);
$this->assertEquals($expected, $actual, $message);
}
/**
* It checks of the given instance implements a certain class or interface.
*
* @param object $instance Instance to check.
* @param string $classOrInterface Name of the class or interface to check if it is implemented by $instance.
* @api
* @since 0.1
*/
public function assertClassOfInstanceImplements($instance, $classOrInterface)
{
$this->assertTrue(is_object($instance), '$instance is not an object.');
$implements = class_implements($instance);
$this->assertTrue(isset($implements[$classOrInterface]));
}
/**
* This assertion consumes the StatementIterator and counts its entries until it is empty. It automatically
* calls assertTrue and -False on $statementIterator->valid() from time to time.
*
* @param int $expectedCount
* @param StatementIterator $statementIterator
* @param string $message
* @api
* @since 0.1
*/
public function assertCountStatementIterator($expectedCount, $statementIterator, $message = null)
{
if (true == empty($message)) {
$message = 'Assertion about count of statements. Expected: '. $expectedCount .', Actual: %s';
}
$i = 0;
foreach ($statementIterator as $statement) {
++$i;
}
$this->assertEquals($i, $expectedCount, sprintf($message, $i));
}
/**
* Checks two lists which implements \Iterator interface, if they contain the same Statement instances.
* The checks will be executed using PHPUnit's assert functions.
*
* @param SetResult $expected
* @param SetResult $actual
* @api
* @since 0.1
*/
public function assertSetIteratorEquals(SetResult $expected, SetResult $actual)
{
$expectedEntries = array();
foreach ($expected as $entry) {
// serialize entry and hash it afterwards to use it as key for $entriesToCheck array.
// later on we only check the other list that each entry, serialized and hashed, has
// its equal key in the list.
// the structure of each entry is an associative array which contains Node instances.
$entryString = '';
foreach ($entry as $key => $nodeInstance) {
if ($nodeInstance->isConcrete()) {
// build a string of all entries of $entry and generate a hash based on that later on.
$entryString .= $nodeInstance->toNQuads() . ' ';
} else {
throw new \Exception('Non-concrete Node instance in SetResult instance found.');
}
}
$expectedEntries[$entryString] = $entry;
}
$actualEntries = array();
foreach ($actual as $entry) {
$entryString = '';
foreach ($entry as $key => $nodeInstance) {
if ($nodeInstance->isConcrete()) {
// build a string of all entries of $entry and generate a hash based on that later on.
$entryString .= $nodeInstance->toNQuads() . ' ';
} else {
throw new \Exception('Non-concrete Node instance in SetResult instance found.');
}
}
$actualEntries[$entryString] = $entry;
}
$notFoundEntries = array();
foreach ($expectedEntries as $expectedEntry) {
$foundExpectedEntry = false;
// 1. generate a string which represents all nodes of an expected set entry
$expectedEntryString = '';
foreach ($expectedEntry as $nodeInstance) {
$expectedEntryString .= $nodeInstance->toNQuads() . ' ';
}
// 2. for each actual entry check their generated string against the expected one
foreach ($actualEntries as $actualEntry) {
$actualEntryString = '';
foreach ($actualEntry as $nodeInstance) {
$actualEntryString .= $nodeInstance->toNQuads() . ' ';
}
if ($actualEntryString == $expectedEntryString) {
$foundExpectedEntry = true;
break;
}
}
if (false == $foundExpectedEntry) {
$notFoundEntries[] = $expectedEntryString;
}
}
// first simply check of the number of given actual entries and expected
if (count($actualEntries) != count($expectedEntries)) {
$this->fail('Expected '. count($expectedEntries) . ' entries, but got '. count($actualEntries));
}
if (!empty($notFoundEntries)) {
echo PHP_EOL . PHP_EOL . 'Given entries, but not found:' . PHP_EOL;
var_dump($notFoundEntries);
echo PHP_EOL . PHP_EOL . 'Actual entries:' . PHP_EOL;
foreach ($actualEntries as $entries) {
echo '- ';
foreach ($entries as $entry) {
echo $entry->toNQuads() .' ';
}
echo PHP_EOL;
echo PHP_EOL;
}
$this->fail(count($notFoundEntries) .' entries where not found.');
// check variables in the end
} elseif (0 == count($notFoundEntries)) {
$this->assertEquals($expected->getVariables(), $actual->getVariables());
}
}
/**
* Checks two lists which implements \Iterator interface, if they contain the same elements.
* The checks will be executed using PHPUnit's assert functions.
*
* @param StatementIterator $expected
* @param StatementIterator $actual
* @param boolean $debug optional, default: false
* @todo implement a more precise way to check blank nodes (currently we just count expected
* and actual numbers of statements with blank nodes)
* @api
* @since 0.1
*/
public function assertStatementIteratorEquals(
StatementIterator $expected,
StatementIterator $actual,
$debug = false
) {
$entriesToCheck = array();
$expectedStatementsWithBlankNodeCount = 0;
foreach ($expected as $statement) {
// serialize entry and hash it afterwards to use it as key for $entriesToCheck array.
// later on we only check the other list that each entry, serialized and hashed, has
// its equal key in the list.
if (!$statement->isConcrete()) {
$this->markTestIncomplete('Comparison of variable statements in iterators not yet implemented.');
}
if ($this->statementContainsNoBlankNodes($statement)) {
$entriesToCheck[hash('sha256', $statement->toNQuads())] = false;
} else {
++$expectedStatementsWithBlankNodeCount;
}
}
// contains a list of all entries, which were not found in $expected.
$actualEntriesNotFound = array();
$notCheckedEntries = array();
$foundEntries = array();
$actualStatementsWithBlankNodeCount = 0;
foreach ($actual as $statement) {
if (!$statement->isConcrete()) {
$this->markTestIncomplete("Comparison of variable statements in iterators not yet implemented.");
}
$statmentHash = hash('sha256', $statement->toNQuads());
// statements without blank nodes
if (isset($entriesToCheck[$statmentHash]) && $this->statementContainsNoBlankNodes($statement)) {
// if entry was found, mark it.
$entriesToCheck[$statmentHash] = true;
$foundEntries[] = $statement;
// handle statements with blank nodes separate because blanknode ID is random
// and therefore gets lost when stored (usually)
} elseif (false == $this->statementContainsNoBlankNodes($statement)) {
++$actualStatementsWithBlankNodeCount;
// statement was not found
} else {
$actualEntriesNotFound[] = $statement;
$notCheckedEntries[] = $statement;
}
}
if (!empty($actualEntriesNotFound) || !empty($notCheckedEntries)) {
$message = 'The StatementIterators are not equal.';
if (!empty($actualEntriesNotFound)) {
if ($debug) {
echo PHP_EOL . 'Following statements where not expected, but found: ';
var_dump($actualEntriesNotFound);
}
$message .= ' ' . count($actualEntriesNotFound) . ' Statements where not expected.';
}
if (!empty($notCheckedEntries)) {
if ($debug) {
echo PHP_EOL . 'Following statements where not present, but expected: ';
var_dump($notCheckedEntries);
}
$message .= ' ' . count($notCheckedEntries) . ' Statements where not present but expected.';
}
$this->assertFalse(!empty($actualEntriesNotFound) || !empty($notCheckedEntries), $message);
// compare count of statements with blank nodes
} elseif ($expectedStatementsWithBlankNodeCount != $actualStatementsWithBlankNodeCount) {
$this->assertFalse(
true,
'Some statements with blank nodes where not found. '
. 'Expected: ' . $expectedStatementsWithBlankNodeCount
. 'Actual: ' . $actualStatementsWithBlankNodeCount
);
} else {
$this->assertTrue(true);
}
}
/**
* Checks two SPARQL Results whether they are equal.
* The checks will be executed using PHPUnit's assert functions.
*
* @param Result $expected
* @param Result $actual
* @throws \Exception if unknown Result type was given.
* @api
* @since 0.1
*/
public function assertResultEquals(Result $expected, Result $actual)
{
$this->assertEquals($expected->isEmptyResult(), $actual->isEmptyResult());
$this->assertEquals($expected->isSetResult(), $actual->isSetResult());
$this->assertEquals($expected->isStatementSetResult(), $actual->isStatementSetResult());
$this->assertEquals($expected->isValueResult(), $actual->isValueResult());
// general result
if ($expected->isSetResult()) {
$this->assertSetIteratorEquals($expected, $actual);
// statement result
} elseif ($actual->isStatementSetResult() && $expected->isStatementSetResult()) {
$this->assertStatementIteratorEquals($expected, $actual);
// value result
} elseif ($expected->isValueResult()) {
$this->assertEquals($expected->getValue(), $actual->getValue());
} else {
throw new \Exception('Unknown Result type given.');
}
}
/**
* Loads configuration file test-config.yml. If the file does not exists, the according test will be
* marked as skipped with a short notification about that the file is missing.
*
* The content of the YAML-file will be transformed into an array and stored in $config property.
*
* @param string $configFilePath Path to the config file.
* @api
* @since 0.1
*/
protected function loadTestConfiguration($configFilepath)
{
// check that the config file exists
if (false === file_exists($configFilepath)) {
$this->markTestSkipped('File test-config.yml is missing.');
}
// parse YAML file
$yaml = new Parser();
$this->configuration = $yaml->parse(file_get_contents($configFilepath));
}
/**
* Place to setup stuff for Saft related tests.
*
* @api
* @since 0.1
*/
public function setUp()
{
parent::setUp();
$this->commonNamespaces = new CommonNamespaces();
$this->rdfHelpers = new RdfHelpers();
$this->nodeFactory = new NodeFactoryImpl($this->rdfHelpers);
$this->statementFactory = new StatementFactoryImpl($this->rdfHelpers);
$this->statementIteratorFactory = new StatementIteratorFactoryImpl();
$this->testGraph = $this->nodeFactory->createNamedNode('http://localhost/Saft/TestGraph/');
}
/**
* @param Statement $statement
* @return bool
*/
protected function statementContainsNoBlankNodes(Statement $statement)
{
return false == $statement->getSubject()->isBlank()
&& false == $statement->getObject()->isBlank();
}
}