Completed
Pull Request — master (#11)
by Alaa
02:12
created

testAcquireTermIdsReusesExistingTerms()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 81

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 81
rs 8.4145
c 0
b 0
f 0
cc 1
nc 1
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Wikibase\TermStore\MediaWiki\Tests\Unit\PackagePrivate;
4
5
use PHPUnit\Framework\TestCase;
6
use Wikibase\TermStore\MediaWiki\TermStoreSchemaUpdater;
7
use Wikibase\TermStore\MediaWiki\PackagePrivate\DatabaseTermIdsAcquirer;
8
use Wikibase\TermStore\MediaWiki\PackagePrivate\InMemoryTypeIdsAcquirer;
9
use Wikimedia\Rdbms\IDatabase;
10
use Wikimedia\Rdbms\DatabaseSqlite;
11
12
class DatabaseTermIdsAcquirerTest extends TestCase {
13
14
	/**
15
	 * @var IDatabase $db
16
	 */
17
	private $db;
18
19
	public function setUp() {
20
		$this->db = DatabaseSqlite::newStandaloneInstance( ':memory:' );
21
		$this->db->sourceFile( TermStoreSchemaUpdater::getSqlFileAbsolutePath() );
22
	}
23
24
	public function testAcquireTermIdsReturnsArrayOfIdsForAllTerms() {
25
		$typeIdsAcquirer = new InMemoryTypeIdsAcquirer();
26
		$alreadyAcquiredTypeIds = $typeIdsAcquirer->acquireTypeIds(
0 ignored issues
show
Unused Code introduced by
$alreadyAcquiredTypeIds is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
27
			[ 'label', 'description', 'alias' ]
28
		);
29
30
		$dbTermIdsAcquirer = new DatabaseTermIdsAcquirer(
31
			$this->db,
32
			$this->db,
33
			$typeIdsAcquirer
34
		);
35
36
		$termsArray = [
37
			'label' => [
38
				'en' => 'same',
39
				'de' => 'same',
40
			],
41
			'description' => [ 'en' => 'same' ],
42
			'alias' => [
43
				'en' => [ 'same', 'same', 'another', 'yet another' ]
44
			]
45
		];
46
47
		$acquiredTermIds = $dbTermIdsAcquirer->acquireTermIds( $termsArray );
48
49
		$this->assertInternalType( 'array', $acquiredTermIds );
50
		$this->assertCount( 7, $acquiredTermIds );
51
	}
52
53
	public function testAcquireTermIdsStoresTermsInDatabase() {
54
		$typeIdsAcquirer = new InMemoryTypeIdsAcquirer();
55
		$alreadyAcquiredTypeIds = $typeIdsAcquirer->acquireTypeIds(
56
			[ 'label', 'description', 'alias' ]
57
		);
58
59
		$dbTermIdsAcquirer = new DatabaseTermIdsAcquirer(
60
			$this->db,
61
			$this->db,
62
			$typeIdsAcquirer
63
		);
64
65
		$termsArray = [
66
			'label' => [
67
				'en' => 'same',
68
				'de' => 'same',
69
			],
70
			'description' => [ 'en' => 'same' ],
71
			'alias' => [
72
				'en' => [ 'same', 'same', 'another', 'yet another' ]
73
			]
74
		];
75
76
		$acquiredTermIds = $dbTermIdsAcquirer->acquireTermIds( $termsArray );
0 ignored issues
show
Unused Code introduced by
$acquiredTermIds is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
77
78
		$this->assertTermSArrayExistInDb( $termsArray, $alreadyAcquiredTypeIds );
79
	}
80
81
	public function testAcquireTermIdsStoresOnlyUniqueTexts() {
82
		$typeIdsAcquirer = new InMemoryTypeIdsAcquirer();
83
84
		$dbTermIdsAcquirer = new DatabaseTermIdsAcquirer(
85
			$this->db,
86
			$this->db,
87
			$typeIdsAcquirer
88
		);
89
90
		$termsArray = [
91
			'label' => [
92
				'en' => 'same',
93
				'de' => 'same',
94
			],
95
			'description' => [ 'en' => 'same' ],
96
			'alias' => [
97
				'en' => [ 'same', 'same', 'another', 'yet another' ]
98
			]
99
		];
100
101
		$acquiredTermIds = $dbTermIdsAcquirer->acquireTermIds( $termsArray );
0 ignored issues
show
Unused Code introduced by
$acquiredTermIds is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
102
103
		$this->assertSame(
104
			3,
105
			$this->db->selectRowCount( 'wbt_text', '*' )
106
		);
107
	}
108
109
	public function testAcquireTermIdsStoresOnlyUniqueTextInLang() {
110
		$typeIdsAcquirer = new InMemoryTypeIdsAcquirer();
111
112
		$dbTermIdsAcquirer = new DatabaseTermIdsAcquirer(
113
			$this->db,
114
			$this->db,
115
			$typeIdsAcquirer
116
		);
117
118
		$termsArray = [
119
			'label' => [
120
				'en' => 'same',
121
				'de' => 'same',
122
			],
123
			'description' => [ 'en' => 'same' ],
124
			'alias' => [
125
				'en' => [ 'same', 'same', 'another', 'yet another' ]
126
			]
127
		];
128
129
		$acquiredTermIds = $dbTermIdsAcquirer->acquireTermIds( $termsArray );
0 ignored issues
show
Unused Code introduced by
$acquiredTermIds is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
130
131
		$this->assertSame(
132
			4,
133
			$this->db->selectRowCount( 'wbt_text_in_lang', '*' )
134
		);
135
	}
136
137
	public function testAcquireTermIdsStoresOnlyUniqueTermInLang() {
138
		$typeIdsAcquirer = new InMemoryTypeIdsAcquirer();
139
140
		$dbTermIdsAcquirer = new DatabaseTermIdsAcquirer(
141
			$this->db,
142
			$this->db,
143
			$typeIdsAcquirer
144
		);
145
146
		$termsArray = [
147
			'label' => [
148
				'en' => 'same',
149
				'de' => 'same',
150
			],
151
			'description' => [ 'en' => 'same' ],
152
			'alias' => [
153
				'en' => [ 'same', 'same', 'another', 'yet another' ]
154
			]
155
		];
156
157
		$acquiredTermIds = $dbTermIdsAcquirer->acquireTermIds( $termsArray );
0 ignored issues
show
Unused Code introduced by
$acquiredTermIds is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
158
159
		$this->assertSame(
160
			6,
161
			$this->db->selectRowCount( 'wbt_term_in_lang', '*' )
162
		);
163
	}
164
165
	public function testAcquireTermIdsReusesExistingTerms() {
166
		$termsArray = [
167
			'label' => [
168
				'en' => 'same',
169
				'de' => 'same',
170
			],
171
			'description' => [ 'en' => 'same' ],
172
			'alias' => [
173
				'en' => [ 'same', 'same', 'another', 'yet another' ]
174
			]
175
		];
176
177
		// We will populate DB with two terms that both have
178
		// text "same". One is of type "label" in language "en",
179
		// and the other is of type "alias" in language "en.
180
		//
181
		// TermIdsAcquirer should then reuse those terms for the given
182
		// termsArray above, meaning thoese pre-inserted terms will
183
		// appear (their ids) in the returned array from
184
		// TermIdsAcquirer::acquireTermIds( $termsArray )
185
		$typeIdsAcquirer = new InMemoryTypeIdsAcquirer();
186
		$alreadyAcquiredTypeIds = $typeIdsAcquirer->acquireTypeIds(
187
			[ 'label', 'description', 'alias' ]
188
		);
189
190
		$this->db->insert( 'wbt_text', [ 'wbx_text' => 'same' ] );
191
		$sameTextId = $this->db->insertId();
192
193
		$this->db->insert(
194
			'wbt_text_in_lang',
195
			[ 'wbxl_text_id' => $sameTextId, 'wbxl_language' => 'en' ]
196
		);
197
		$enSameTextInLangId = $this->db->insertId();
198
199
		$this->db->insert(
200
			'wbt_term_in_lang',
201
			[ 'wbtl_text_in_lang_id' => $enSameTextInLangId,
202
			  'wbtl_type_id' => $alreadyAcquiredTypeIds['label'] ]
203
		);
204
		$labelEnSameTermInLangId = (string)$this->db->insertId();
205
206
		$this->db->insert(
207
			'wbt_term_in_lang',
208
			[ 'wbtl_text_in_lang_id' => $enSameTextInLangId,
209
			  'wbtl_type_id' => $alreadyAcquiredTypeIds['alias'] ]
210
		);
211
		$aliasEnSameTermInLangId = (string)$this->db->insertId();
212
213
		$dbTermIdsAcquirer = new DatabaseTermIdsAcquirer(
214
			$this->db,
215
			$this->db,
216
			$typeIdsAcquirer
217
		);
218
219
		$acquiredTermIds = $dbTermIdsAcquirer->acquireTermIds( $termsArray );
220
221
		$this->assertCount( 7, $acquiredTermIds );
222
223
		// We will assert that the returned ids of acquired terms contains
224
		// one occurence of the term id for en label "same" that already existed in db,
225
		// and two occurences of the term id for en alias "same" that already existed
226
		// in db.
227
		$this->assertCount(
228
			1,
229
			array_filter(
230
				$acquiredTermIds,
231
				function ( $id ) use ( $labelEnSameTermInLangId ) {
232
					return $id === $labelEnSameTermInLangId;
233
				}
234
			)
235
		);
236
		$this->assertCount(
237
			2,
238
			array_filter(
239
				$acquiredTermIds,
240
				function ( $id ) use ( $aliasEnSameTermInLangId ) {
241
					return $id === $aliasEnSameTermInLangId;
242
				}
243
			)
244
		);
245
	}
246
247
	private function assertTermsArrayExistInDb( $termsArray, $typeIds ) {
248
		foreach ( $termsArray as $type => $textsPerLang ) {
249
			foreach ( $textsPerLang as $lang => $texts ) {
250
				foreach ( (array)$texts as $text ) {
251
					$textId = $this->db->selectField(
252
						'wbt_text',
253
						'wbx_id',
254
						[ 'wbx_text' => $text ]
255
					);
256
257
					$this->assertNotEmpty(
258
						$textId,
259
						"Expected record for text '$text' is not in wbt_text"
260
					);
261
262
					$textInLangId = $this->db->selectField(
263
						'wbt_text_in_lang',
264
						'wbxl_id',
265
						[ 'wbxl_language' => $lang, 'wbxl_text_id' => $textId ]
266
					);
267
268
					$this->assertNotEmpty(
269
						$textInLangId,
270
						"Expected text '$text' in language '$lang' is not in wbt_text_in_lang"
271
					);
272
273
					$this->assertNotEmpty(
274
						$this->db->selectField(
275
							'wbt_term_in_lang',
276
							'wbtl_id',
277
							[ 'wbtl_type_id' => $typeIds[$type], 'wbtl_text_in_lang_id' => $textInLangId ]
278
						),
279
						"Expected $type '$text' in language '$lang' is not in wbt_term_in_lang"
280
					);
281
				}
282
			}
283
		}
284
	}
285
}
286