Passed
Push — master ( 750c68...36913a )
by
unknown
02:38
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
27
		$dbTermIdsAcquirer = new DatabaseTermIdsAcquirer(
28
			$this->db,
29
			$this->db,
30
			$typeIdsAcquirer
31
		);
32
33
		$termsArray = [
34
			'label' => [
35
				'en' => 'same',
36
				'de' => 'same',
37
			],
38
			'description' => [ 'en' => 'same' ],
39
			'alias' => [
40
				'en' => [ 'same', 'same', 'another', 'yet another' ]
41
			]
42
		];
43
44
		$acquiredTermIds = $dbTermIdsAcquirer->acquireTermIds( $termsArray );
45
46
		$this->assertInternalType( 'array', $acquiredTermIds );
47
		$this->assertCount( 7, $acquiredTermIds );
48
	}
49
50
	public function testAcquireTermIdsStoresTermsInDatabase() {
51
		$typeIdsAcquirer = new InMemoryTypeIdsAcquirer();
52
		$alreadyAcquiredTypeIds = $typeIdsAcquirer->acquireTypeIds(
53
			[ 'label', 'description', 'alias' ]
54
		);
55
56
		$dbTermIdsAcquirer = new DatabaseTermIdsAcquirer(
57
			$this->db,
58
			$this->db,
59
			$typeIdsAcquirer
60
		);
61
62
		$termsArray = [
63
			'label' => [
64
				'en' => 'same',
65
				'de' => 'same',
66
			],
67
			'description' => [ 'en' => 'same' ],
68
			'alias' => [
69
				'en' => [ 'same', 'same', 'another', 'yet another' ]
70
			]
71
		];
72
73
		$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...
74
75
		$this->assertTermsArrayExistInDb( $termsArray, $alreadyAcquiredTypeIds );
76
	}
77
78
	public function testAcquireTermIdsStoresOnlyUniqueTexts() {
79
		$typeIdsAcquirer = new InMemoryTypeIdsAcquirer();
80
81
		$dbTermIdsAcquirer = new DatabaseTermIdsAcquirer(
82
			$this->db,
83
			$this->db,
84
			$typeIdsAcquirer
85
		);
86
87
		$termsArray = [
88
			'label' => [
89
				'en' => 'same',
90
				'de' => 'same',
91
			],
92
			'description' => [ 'en' => 'same' ],
93
			'alias' => [
94
				'en' => [ 'same', 'same', 'another', 'yet another' ]
95
			]
96
		];
97
98
		$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...
99
100
		$this->assertSame(
101
			3,
102
			$this->db->selectRowCount( 'wbt_text', '*' )
103
		);
104
	}
105
106
	public function testAcquireTermIdsStoresOnlyUniqueTextInLang() {
107
		$typeIdsAcquirer = new InMemoryTypeIdsAcquirer();
108
109
		$dbTermIdsAcquirer = new DatabaseTermIdsAcquirer(
110
			$this->db,
111
			$this->db,
112
			$typeIdsAcquirer
113
		);
114
115
		$termsArray = [
116
			'label' => [
117
				'en' => 'same',
118
				'de' => 'same',
119
			],
120
			'description' => [ 'en' => 'same' ],
121
			'alias' => [
122
				'en' => [ 'same', 'same', 'another', 'yet another' ]
123
			]
124
		];
125
126
		$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...
127
128
		$this->assertSame(
129
			4,
130
			$this->db->selectRowCount( 'wbt_text_in_lang', '*' )
131
		);
132
	}
133
134
	public function testAcquireTermIdsStoresOnlyUniqueTermInLang() {
135
		$typeIdsAcquirer = new InMemoryTypeIdsAcquirer();
136
137
		$dbTermIdsAcquirer = new DatabaseTermIdsAcquirer(
138
			$this->db,
139
			$this->db,
140
			$typeIdsAcquirer
141
		);
142
143
		$termsArray = [
144
			'label' => [
145
				'en' => 'same',
146
				'de' => 'same',
147
			],
148
			'description' => [ 'en' => 'same' ],
149
			'alias' => [
150
				'en' => [ 'same', 'same', 'another', 'yet another' ]
151
			]
152
		];
153
154
		$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...
155
156
		$this->assertSame(
157
			6,
158
			$this->db->selectRowCount( 'wbt_term_in_lang', '*' )
159
		);
160
	}
161
162
	public function testAcquireTermIdsReusesExistingTerms() {
163
		$termsArray = [
164
			'label' => [
165
				'en' => 'same',
166
				'de' => 'same',
167
			],
168
			'description' => [ 'en' => 'same' ],
169
			'alias' => [
170
				'en' => [ 'same', 'same', 'another', 'yet another' ]
171
			]
172
		];
173
174
		// We will populate DB with two terms that both have
175
		// text "same". One is of type "label" in language "en",
176
		// and the other is of type "alias" in language "en.
177
		//
178
		// TermIdsAcquirer should then reuse those terms for the given
179
		// termsArray above, meaning thoese pre-inserted terms will
180
		// appear (their ids) in the returned array from
181
		// TermIdsAcquirer::acquireTermIds( $termsArray )
182
		$typeIdsAcquirer = new InMemoryTypeIdsAcquirer();
183
		$alreadyAcquiredTypeIds = $typeIdsAcquirer->acquireTypeIds(
184
			[ 'label', 'description', 'alias' ]
185
		);
186
187
		$this->db->insert( 'wbt_text', [ 'wbx_text' => 'same' ] );
188
		$sameTextId = $this->db->insertId();
189
190
		$this->db->insert(
191
			'wbt_text_in_lang',
192
			[ 'wbxl_text_id' => $sameTextId, 'wbxl_language' => 'en' ]
193
		);
194
		$enSameTextInLangId = $this->db->insertId();
195
196
		$this->db->insert(
197
			'wbt_term_in_lang',
198
			[ 'wbtl_text_in_lang_id' => $enSameTextInLangId,
199
			  'wbtl_type_id' => $alreadyAcquiredTypeIds['label'] ]
200
		);
201
		$labelEnSameTermInLangId = (string)$this->db->insertId();
202
203
		$this->db->insert(
204
			'wbt_term_in_lang',
205
			[ 'wbtl_text_in_lang_id' => $enSameTextInLangId,
206
			  'wbtl_type_id' => $alreadyAcquiredTypeIds['alias'] ]
207
		);
208
		$aliasEnSameTermInLangId = (string)$this->db->insertId();
209
210
		$dbTermIdsAcquirer = new DatabaseTermIdsAcquirer(
211
			$this->db,
212
			$this->db,
213
			$typeIdsAcquirer
214
		);
215
216
		$acquiredTermIds = $dbTermIdsAcquirer->acquireTermIds( $termsArray );
217
218
		$this->assertCount( 7, $acquiredTermIds );
219
220
		// We will assert that the returned ids of acquired terms contains
221
		// one occurence of the term id for en label "same" that already existed in db,
222
		// and two occurences of the term id for en alias "same" that already existed
223
		// in db.
224
		$this->assertCount(
225
			1,
226
			array_filter(
227
				$acquiredTermIds,
228
				function ( $id ) use ( $labelEnSameTermInLangId ) {
229
					return $id === $labelEnSameTermInLangId;
230
				}
231
			)
232
		);
233
		$this->assertCount(
234
			2,
235
			array_filter(
236
				$acquiredTermIds,
237
				function ( $id ) use ( $aliasEnSameTermInLangId ) {
238
					return $id === $aliasEnSameTermInLangId;
239
				}
240
			)
241
		);
242
	}
243
244
	private function assertTermsArrayExistInDb( $termsArray, $typeIds ) {
245
		foreach ( $termsArray as $type => $textsPerLang ) {
246
			foreach ( $textsPerLang as $lang => $texts ) {
247
				foreach ( (array)$texts as $text ) {
248
					$textId = $this->db->selectField(
249
						'wbt_text',
250
						'wbx_id',
251
						[ 'wbx_text' => $text ]
252
					);
253
254
					$this->assertNotEmpty(
255
						$textId,
256
						"Expected record for text '$text' is not in wbt_text"
257
					);
258
259
					$textInLangId = $this->db->selectField(
260
						'wbt_text_in_lang',
261
						'wbxl_id',
262
						[ 'wbxl_language' => $lang, 'wbxl_text_id' => $textId ]
263
					);
264
265
					$this->assertNotEmpty(
266
						$textInLangId,
267
						"Expected text '$text' in language '$lang' is not in wbt_text_in_lang"
268
					);
269
270
					$this->assertNotEmpty(
271
						$this->db->selectField(
272
							'wbt_term_in_lang',
273
							'wbtl_id',
274
							[ 'wbtl_type_id' => $typeIds[$type], 'wbtl_text_in_lang_id' => $textInLangId ]
275
						),
276
						"Expected $type '$text' in language '$lang' is not in wbt_term_in_lang"
277
					);
278
				}
279
			}
280
		}
281
	}
282
}
283