Completed
Push — master ( f7068e...f8eeae )
by Jeroen De
12:31
created

EntityDumpIteratorTest::testInitialPosition()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 26
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 26
rs 8.8571
cc 1
eloc 16
nc 1
nop 0
1
<?php
2
3
namespace Tests\Wikibase\JsonDumpReader;
4
5
use DataValues\Deserializers\DataValueDeserializer;
6
use Iterator;
7
use Wikibase\DataModel\DeserializerFactory;
8
use Wikibase\DataModel\Entity\BasicEntityIdParser;
9
use Wikibase\JsonDumpReader\Iterator\EntityDumpIterator;
10
use Wikibase\JsonDumpReader\JsonDumpFactory;
11
use Wikibase\JsonDumpReader\Reader\ExtractedDumpReader;
12
13
/**
14
 * @covers Wikibase\JsonDumpReader\Iterator\EntityDumpIterator
15
 * @covers Wikibase\JsonDumpReader\JsonDumpFactory
16
 *
17
 * @licence GNU GPL v2+
18
 * @author Jeroen De Dauw < [email protected] >
19
 */
20
class EntityDumpIteratorTest extends \PHPUnit_Framework_TestCase {
21
22
	private function newIteratorForFile( $filePath, callable $onError = null ) {
23
		return ( new JsonDumpFactory() )->newEntityDumpIterator(
24
			new ExtractedDumpReader( $filePath ),
25
			$this->newCurrentEntityDeserializer(),
26
			$onError
27
		);
28
	}
29
30
	private function newCurrentEntityDeserializer() {
31
		$factory = new DeserializerFactory(
32
			$this->newDataValueDeserializer(),
33
			new BasicEntityIdParser()
34
		);
35
36
		return $factory->newEntityDeserializer();
37
	}
38
39
	private function newDataValueDeserializer() {
40
		$dataValueClasses = [
41
			'boolean' => 'DataValues\BooleanValue',
42
			'number' => 'DataValues\NumberValue',
43
			'string' => 'DataValues\StringValue',
44
			'unknown' => 'DataValues\UnknownValue',
45
			'globecoordinate' => 'DataValues\Geo\Values\GlobeCoordinateValue',
46
			'monolingualtext' => 'DataValues\MonolingualTextValue',
47
			'multilingualtext' => 'DataValues\MultilingualTextValue',
48
			'quantity' => 'DataValues\QuantityValue',
49
			'time' => 'DataValues\TimeValue',
50
			'wikibase-entityid' => 'Wikibase\DataModel\Entity\EntityIdValue',
51
		];
52
53
		return new DataValueDeserializer( $dataValueClasses );
54
	}
55
56
	private function assertFindsEntities( array $expectedIds, Iterator $dumpIterator, $message = '' ) {
57
		$actualIds = [];
58
59
		foreach ( $dumpIterator as $entity ) {
60
			$actualIds[] = $entity->getId()->getSerialization();
61
		}
62
63
		$this->assertEquals( $expectedIds, $actualIds, $message );
64
	}
65
66
	public function testGivenFileWithNoEntities_noEntitiesAreReturned() {
67
		$iterator = $this->newIteratorForFile( ( new \JsonDumpData() )->getEmptyDumpPath() );
68
69
		$this->assertFindsEntities( [], $iterator );
70
	}
71
72
	public function testGivenFileWithOneEntity_oneEntityIsFound() {
73
		$iterator = $this->newIteratorForFile( ( new \JsonDumpData() )->getOneItemDumpPath() );
74
75
		$this->assertFindsEntities( [ 'Q1' ], $iterator );
76
	}
77
78
	public function testGivenFileWithFiveEntities_fiveEntityAreFound() {
79
		$iterator = $this->newIteratorForFile( ( new \JsonDumpData() )->getFiveEntitiesDumpPath() );
80
81
		$this->assertFindsEntities( [ 'Q1', 'Q8', 'P16', 'P19', 'P22' ], $iterator );
82
	}
83
84
	public function testGivenFileWithInvalidEntity_noEntityIsFound() {
85
		$iterator = $this->newIteratorForFile( __DIR__ . '/../data/invalid-item.json' );
86
		$this->assertFindsEntities( [], $iterator );
87
	}
88
89
	public function testGivenFileWithInvalidEntities_validEntitiesAreFound() {
90
		$iterator = $this->newIteratorForFile( __DIR__ . '/../data/3valid-2invalid.json' );
91
		$this->assertFindsEntities( [ 'Q1', 'P16', 'P22' ], $iterator );
92
	}
93
94
	public function testCanDoMultipleIterations() {
95
		$iterator = $this->newIteratorForFile( ( new \JsonDumpData() )->getFiveEntitiesDumpPath() );
96
97
		$this->assertFindsEntities( [ 'Q1', 'Q8', 'P16', 'P19', 'P22' ], $iterator, 'first iteration' );
98
		$this->assertFindsEntities( [ 'Q1', 'Q8', 'P16', 'P19', 'P22' ], $iterator, 'second iteration' );
99
	}
100
101
	public function testInitialPosition() {
102
		$reader = new ExtractedDumpReader( ( new \JsonDumpData() )->getFiveEntitiesDumpPath() );
103
104
		$iterator = new EntityDumpIterator(
105
			( new JsonDumpFactory() )->newObjectDumpIterator( $reader ),
106
			$this->newCurrentEntityDeserializer()
107
		);
108
109
		$iterator->rewind();
110
		$this->assertSame( 'Q1', $iterator->current()->getId()->getSerialization() );
111
112
		$iterator->next();
113
		$this->assertSame( 'Q8', $iterator->current()->getId()->getSerialization() );
114
115
		$newReader = new ExtractedDumpReader(
116
			( new \JsonDumpData() )->getFiveEntitiesDumpPath(),
117
			$reader->getPosition()
118
		);
119
120
		$newIterator = new EntityDumpIterator(
121
			( new JsonDumpFactory() )->newObjectDumpIterator( $newReader ),
122
			$this->newCurrentEntityDeserializer()
123
		);
124
125
		$this->assertFindsEntities( [ 'P16', 'P19', 'P22' ], $newIterator );
126
	}
127
128
	public function testGivenFileWithInvalidEntities_errorsAreReported() {
129
		$errors = [];
130
131
		$iterator = $this->newIteratorForFile(
132
			__DIR__ . '/../data/3valid-2invalid.json',
133
			function( $errorMessage ) use ( &$errors ) {
134
				$errors[] = $errorMessage;
135
			}
136
		);
137
138
		$iterator->rewind();
139
		while ( $iterator->valid() ) {
140
			$iterator->next();
141
		}
142
143
		$this->assertContainsOnly( 'string', $errors );
144
		$this->assertCount( 2, $errors );
145
	}
146
147
	public function testGivenFileWithInvalidJsonLine_errorIsRecorded() {
148
		$errors = [];
149
150
		$iterator = $this->newIteratorForFile(
151
			__DIR__ . '/../data/invalid-json.json',
152
			function( $errorMessage ) use ( &$errors ) {
153
				$errors[] = $errorMessage;
154
			}
155
		);
156
157
		iterator_to_array( $iterator );
158
159
		$this->assertContainsOnly( 'string', $errors );
160
		$this->assertCount( 1, $errors );
161
	}
162
163
}