GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

ElementTest   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 465
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 218
c 2
b 0
f 0
dl 0
loc 465
rs 10
wmc 18

14 Methods

Rating   Name   Duplication   Size   Complexity  
A checkTermIsDomElement() 0 24 5
A testGetFormattedDefinitions_4() 0 27 1
A setUp() 0 2 1
A testGetFormattedDefinitions_3() 0 21 1
A testGetFormattedTerm_6() 0 23 1
A testGetFormattedTerm_4() 0 27 1
A testGetFormattedTerm_5() 0 30 1
A testCanConstruct() 0 6 1
A testGetFormattedTerm_7() 0 24 1
A testGetFormattedTerm_1() 0 27 1
A testGetFormattedDefinitions_2() 0 50 1
A testGetFormattedTerm_2() 0 22 1
A testGetFormattedTerm_3() 0 30 1
A testGetFormattedDefinitions_1() 0 51 1
1
<?php
2
/**
3
 * This file is part of the MediaWiki extension Lingo.
4
 *
5
 * @copyright 2011 - 2018, Stephan Gambke
6
 * @license GPL-2.0-or-later
7
 *
8
 * The Lingo extension is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by the Free
10
 * Software Foundation; either version 2 of the License, or (at your option) any
11
 * later version.
12
 *
13
 * The Lingo extension is distributed in the hope that it will be useful, but
14
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16
 * details.
17
 *
18
 * You should have received a copy of the GNU General Public License along
19
 * with this program. If not, see <http://www.gnu.org/licenses/>.
20
 *
21
 * @author Stephan Gambke
22
 * @since 2.0
23
 * @file
24
 * @ingroup Lingo
25
 */
26
27
namespace Lingo\Tests\Unit;
28
29
use Lingo\Element;
30
31
/**
32
 * @group extensions-lingo
33
 * @group extensions-lingo-unit
34
 * @group mediawiki-databaseless
35
 *
36
 * @coversDefaultClass \Lingo\Element
37
 *
38
 * @ingroup Lingo
39
 * @ingroup Test
40
 */
41
class ElementTest extends \PHPUnit\Framework\TestCase {
0 ignored issues
show
Bug introduced by Kunal Mehta
The type PHPUnit\Framework\TestCase was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
42
43
	/** @var Element */
44
	protected $element;
45
	protected $doc;
46
47
	protected function setUp() {
48
		$this->doc = new \DOMDocument();
49
	}
50
51
	/**
52
	 * @covers ::__construct
53
	 */
54
	public function testCanConstruct() {
55
		$term = 'someTerm';
56
		$definition = [];
57
		$element = new Element( $term, $definition );
58
59
		$this->assertInstanceOf( '\Lingo\Element', $element );
60
	}
61
62
	/**
63
	 * Tests
64
	 * - if $wgexLingoDisplayOnce = false, the first and second occurrence of a term is correctly marked up as tooltip anchor
65
	 */
66
	public function testGetFormattedTerm_1() {
67
		// Setup
68
		$term = 'someTerm';
69
		$definition = [
70
			Element::ELEMENT_TERM       => $term,
71
			Element::ELEMENT_DEFINITION => 'someDefinition',
72
			Element::ELEMENT_LINK       => uniqid(), // just some fake page name that does not exist on the wiki
73
			Element::ELEMENT_SOURCE     => null,
74
			Element::ELEMENT_STYLE      => null,
75
		];
76
		$element = new Element( $term, $definition );
77
78
		$GLOBALS[ 'wgexLingoDisplayOnce' ] = false;
79
80
		$expectedAttributes = [ 'class' => [ 'mw-lingo-term' ], 'data-lingo-term-id' => '8ade40e10f35a32fbb1e06a4b54751d0' ];
81
82
		// Run
83
		$node = $element->getFormattedTerm( $this->doc );
84
85
		// Check
86
		$this->checkTermIsDomElement( $node, 'span', $term, $expectedAttributes );
0 ignored issues
show
Bug introduced by Stephan
$expectedAttributes of type array<string,array<integer,string>|string> is incompatible with the type string[] expected by parameter $expectedAttributes of Lingo\Tests\Unit\Element...checkTermIsDomElement(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

86
		$this->checkTermIsDomElement( $node, 'span', $term, /** @scrutinizer ignore-type */ $expectedAttributes );
Loading history...
Bug introduced by Stephan
It seems like $node can also be of type DOMText; however, parameter $node of Lingo\Tests\Unit\Element...checkTermIsDomElement() does only seem to accept DOMElement, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

86
		$this->checkTermIsDomElement( /** @scrutinizer ignore-type */ $node, 'span', $term, $expectedAttributes );
Loading history...
87
88
		// Run
89
		$node = $element->getFormattedTerm( $this->doc );
90
91
		// Check
92
		$this->checkTermIsDomElement( $node, 'span', $term, $expectedAttributes );
93
	}
94
95
	/**
96
	 * Tests
97
	 * - if $wgexLingoDisplayOnce = true, the first occurrence of a term is correctly marked up as tooltip anchor
98
	 * - if $wgexLingoDisplayOnce = true, the second occurrence of a term is not marked up
99
	 */
100
	public function testGetFormattedTerm_2() {
101
		// Setup
102
		$term = 'someTerm';
103
		$definition = [];
104
		$element = new Element( $term, $definition );
105
106
		$GLOBALS[ 'wgexLingoDisplayOnce' ] = true;
107
108
		$expectedAttributes = [ 'class' => 'mw-lingo-term', 'data-lingo-term-id' => '8ade40e10f35a32fbb1e06a4b54751d0' ];
109
110
		// Run
111
		$node = $element->getFormattedTerm( $this->doc );
112
113
		// Check
114
		$this->checkTermIsDomElement( $node, 'span', $term, $expectedAttributes );
0 ignored issues
show
Bug introduced by Stephan
It seems like $node can also be of type DOMText; however, parameter $node of Lingo\Tests\Unit\Element...checkTermIsDomElement() does only seem to accept DOMElement, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

114
		$this->checkTermIsDomElement( /** @scrutinizer ignore-type */ $node, 'span', $term, $expectedAttributes );
Loading history...
115
116
		// Run
117
		$node = $element->getFormattedTerm( $this->doc );
118
119
		// Check
120
		$this->assertInstanceOf( 'DOMText', $node );
121
		$this->assertEquals( $term, $node->wholeText );
0 ignored issues
show
Bug introduced by Stephan
The property wholeText does not seem to exist on DOMElement.
Loading history...
122
	}
123
124
	/**
125
	 * Tests
126
	 * - if there is only one definition and its text is empty and it has a link, the term is marked up as link
127
	 * - if the link is not a URL and does not point to an existing page, the term is marked up as "new" link
128
	 * - if $wgexLingoDisplayOnce = false, the first and second occurrence of of term are marked up as link
129
	 */
130
	public function testGetFormattedTerm_3() {
131
		// Setup
132
		$term = 'someTerm';
133
		$title = uniqid();
134
135
		$definition = [
136
			Element::ELEMENT_TERM       => $term,
137
			Element::ELEMENT_DEFINITION => null,
138
			Element::ELEMENT_LINK       => $title, // just some fake page name that does not exist on the wiki
139
			Element::ELEMENT_SOURCE     => null,
140
			Element::ELEMENT_STYLE      => null,
141
		];
142
143
		$element = new Element( $term, $definition );
144
145
		$expectedAttributes = [ 'class' => [ 'mw-lingo-term', 'new' ],  'title' => wfMessage( 'red-link-title', $title )->text() ];
0 ignored issues
show
Bug introduced by Stephan
The function wfMessage was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

145
		$expectedAttributes = [ 'class' => [ 'mw-lingo-term', 'new' ],  'title' => /** @scrutinizer ignore-call */ wfMessage( 'red-link-title', $title )->text() ];
Loading history...
146
147
		$GLOBALS[ 'wgexLingoDisplayOnce' ] = false;
148
149
		// Run
150
		$node = $element->getFormattedTerm( $this->doc );
151
152
		// Check
153
		$this->checkTermIsDomElement( $node, 'a', $term, $expectedAttributes );
0 ignored issues
show
Bug introduced by Stephan
It seems like $node can also be of type DOMText; however, parameter $node of Lingo\Tests\Unit\Element...checkTermIsDomElement() does only seem to accept DOMElement, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

153
		$this->checkTermIsDomElement( /** @scrutinizer ignore-type */ $node, 'a', $term, $expectedAttributes );
Loading history...
154
155
		// Run
156
		$node = $element->getFormattedTerm( $this->doc );
157
158
		// Check
159
		$this->checkTermIsDomElement( $node, 'a', $term, $expectedAttributes );
160
	}
161
162
	/**
163
	 * Tests
164
	 * - if the link is not a URL and points to an existing page, the term is marked up with that title
165
	 */
166
	public function testGetFormattedTerm_4() {
167
		// Setup
168
		$term = 'someTerm';
169
170
		$page = \Title::newFromId( 1 );
0 ignored issues
show
Bug introduced by Antoine Musso
The type Title was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
171
		$this->assertTrue( $page->exists() );
172
		$title = $page->getText();
173
174
		$definition = [
175
			Element::ELEMENT_TERM       => $term,
176
			Element::ELEMENT_DEFINITION => null,
177
			Element::ELEMENT_LINK       => $title,
178
			Element::ELEMENT_SOURCE     => null,
179
			Element::ELEMENT_STYLE      => null,
180
		];
181
182
		$element = new Element( $term, $definition );
183
184
		$expectedAttributes = [ 'class' => [ 'mw-lingo-term' ],  'title' => $title ];
185
186
		$GLOBALS[ 'wgexLingoDisplayOnce' ] = false;
187
188
		// Run
189
		$node = $element->getFormattedTerm( $this->doc );
190
191
		// Check
192
		$this->checkTermIsDomElement( $node, 'a', $term, $expectedAttributes );
0 ignored issues
show
Bug introduced by Stephan
It seems like $node can also be of type DOMText; however, parameter $node of Lingo\Tests\Unit\Element...checkTermIsDomElement() does only seem to accept DOMElement, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

192
		$this->checkTermIsDomElement( /** @scrutinizer ignore-type */ $node, 'a', $term, $expectedAttributes );
Loading history...
193
	}
194
195
	/**
196
	 * Tests
197
	 * - if there is only one definition and its text is empty and it has a link and $wgexLingoDisplayOnce = true, the first occurrence of a term is correctly marked up as link
198
	 * - if there is only one definition and its text is empty and it has a link and $wgexLingoDisplayOnce = true, the second occurrence of a term is not marked up
199
	 * - if a style is set in the definition, the link is marked up with that style
200
	 * - if the link is a valid URL, the term is marked up as external link
201
	 */
202
	public function testGetFormattedTerm_5() {
203
		// Setup
204
		$term = 'someTerm';
205
206
		$definition = [
207
			Element::ELEMENT_TERM       => $term,
208
			Element::ELEMENT_DEFINITION => null,
209
			Element::ELEMENT_LINK       => 'http://foo.com',
210
			Element::ELEMENT_SOURCE     => null,
211
			Element::ELEMENT_STYLE      => 'some-style',
212
		];
213
214
		$element = new Element( $term, $definition );
215
216
		$expectedAttributes = [ 'class' => [ 'mw-lingo-term', 'ext', 'some-style' ], 'title' => $term ];
217
218
		$GLOBALS[ 'wgexLingoDisplayOnce' ] = true;
219
220
		// Run
221
		$node = $element->getFormattedTerm( $this->doc );
222
223
		// Check
224
		$this->checkTermIsDomElement( $node, 'a', $term, $expectedAttributes );
0 ignored issues
show
Bug introduced by Stephan
It seems like $node can also be of type DOMText; however, parameter $node of Lingo\Tests\Unit\Element...checkTermIsDomElement() does only seem to accept DOMElement, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

224
		$this->checkTermIsDomElement( /** @scrutinizer ignore-type */ $node, 'a', $term, $expectedAttributes );
Loading history...
Bug introduced by Stephan
$expectedAttributes of type array<string,array<integer,string>|string> is incompatible with the type string[] expected by parameter $expectedAttributes of Lingo\Tests\Unit\Element...checkTermIsDomElement(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

224
		$this->checkTermIsDomElement( $node, 'a', $term, /** @scrutinizer ignore-type */ $expectedAttributes );
Loading history...
225
226
		// Run
227
		$node = $element->getFormattedTerm( $this->doc );
228
229
		// Check
230
		$this->assertInstanceOf( 'DOMText', $node );
231
		$this->assertEquals( $term, $node->wholeText );
0 ignored issues
show
Bug introduced by Stephan
The property wholeText does not seem to exist on DOMElement.
Loading history...
232
	}
233
234
	/**
235
	 * Tests
236
	 * - if there is only one definition and its text is empty and it has an invalid link, the term is marked up as tooltip
237
	 * - if the term contains HTML-special characters, it is handled without raising an exception
238
	 */
239
	public function testGetFormattedTerm_6() {
240
		// Setup
241
		$term = 'some&Term';
242
243
		$definition = [
244
			Element::ELEMENT_TERM       => $term,
245
			Element::ELEMENT_DEFINITION => null,
246
			Element::ELEMENT_LINK       => 'foo[]bar',
247
			Element::ELEMENT_SOURCE     => null,
248
			Element::ELEMENT_STYLE      => null,
249
		];
250
251
		$element = new Element( $term, $definition );
252
253
		$expectedAttributes = [ 'class' => 'mw-lingo-term', 'data-lingo-term-id' => 'a8057b0494da505d2f7ac2e96e17083f' ];
254
255
		$GLOBALS[ 'wgexLingoDisplayOnce' ] = false;
256
257
		// Run
258
		$node = $element->getFormattedTerm( $this->doc );
259
260
		// Check
261
		$this->checkTermIsDomElement( $node, 'span', $term, $expectedAttributes );
0 ignored issues
show
Bug introduced by Stephan
It seems like $node can also be of type DOMText; however, parameter $node of Lingo\Tests\Unit\Element...checkTermIsDomElement() does only seem to accept DOMElement, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

261
		$this->checkTermIsDomElement( /** @scrutinizer ignore-type */ $node, 'span', $term, $expectedAttributes );
Loading history...
262
	}
263
264
	/**
265
	 * Tests
266
	 * - if there is only one definition and its text is empty and it has an anchor link, the term is marked up as link without title attribute
267
	 */
268
	public function testGetFormattedTerm_7() {
269
		// Setup
270
		$term = 'some&Term';
271
272
		$definition = [
273
			Element::ELEMENT_TERM       => $term,
274
			Element::ELEMENT_DEFINITION => null,
275
			Element::ELEMENT_LINK       => '#someAnchor',
276
			Element::ELEMENT_SOURCE     => null,
277
			Element::ELEMENT_STYLE      => null,
278
		];
279
280
		$element = new Element( $term, $definition );
281
282
		$expectedAttributes = [ 'class' => 'mw-lingo-term' ];
283
		$unexpectedAttributes = [ 'title' ];
284
285
		$GLOBALS[ 'wgexLingoDisplayOnce' ] = false;
286
287
		// Run
288
		$node = $element->getFormattedTerm( $this->doc );
289
290
		// Check
291
		$this->checkTermIsDomElement( $node, 'a', $term, $expectedAttributes, $unexpectedAttributes );
0 ignored issues
show
Bug introduced by Stephan
It seems like $node can also be of type DOMText; however, parameter $node of Lingo\Tests\Unit\Element...checkTermIsDomElement() does only seem to accept DOMElement, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

291
		$this->checkTermIsDomElement( /** @scrutinizer ignore-type */ $node, 'a', $term, $expectedAttributes, $unexpectedAttributes );
Loading history...
292
	}
293
294
	/**
295
	 * Tests
296
	 * - correct html is produced
297
	 * - correct order of definitions
298
	 * - user-defined class is applied to definition
299
	 */
300
	public function testGetFormattedDefinitions_1() {
301
		// Setup
302
		$term = 'some&Term';
303
304
		$definition1 = [
305
			Element::ELEMENT_TERM       => $term,
306
			Element::ELEMENT_DEFINITION => 'someDefinition1',
307
			Element::ELEMENT_LINK       => 'someInternalLink1',
308
			Element::ELEMENT_SOURCE     => null,
309
			Element::ELEMENT_STYLE      => null,
310
		];
311
312
		$url1 = \Title::newFromText( $definition1[ Element::ELEMENT_LINK ] )->getFullURL();
313
314
		$definition2 = [
315
			Element::ELEMENT_TERM       => $term,
316
			Element::ELEMENT_DEFINITION => 'someDefinition2',
317
			Element::ELEMENT_LINK       => 'someInternalLink2',
318
			Element::ELEMENT_SOURCE     => null,
319
			Element::ELEMENT_STYLE      => 'some-style-2',
320
		];
321
322
		$url2 = \Title::newFromText( $definition2[ Element::ELEMENT_LINK ] )->getFullURL();
323
324
		$GLOBALS[ 'wgexLingoDisplayOnce' ] = false;
325
326
		$element = new Element( $term, $definition1 );
327
		$element->addDefinition( $definition2 );
328
		$node = $element->getFormattedTerm( $this->doc );
0 ignored issues
show
Unused Code introduced by Stephan
The assignment to $node is dead and can be removed.
Loading history...
329
330
		// Run
331
		$definitions = $element->getFormattedDefinitions();
332
333
		$this->assertEquals(
334
			"<div class='mw-lingo-tooltip' id='a8057b0494da505d2f7ac2e96e17083f'>" .
335
			"<div class='mw-lingo-definition '>" .
336
			"<div class='mw-lingo-definition-text'>\n" .
337
			"someDefinition1\n" .
338
			"</div>" .
0 ignored issues
show
Coding Style Comprehensibility introduced by Stephan
The string literal </div> does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
339
			"<div class='mw-lingo-definition-link'>" .
340
			"[" . $url1 . " <nowiki/>]" .
0 ignored issues
show
Coding Style Comprehensibility introduced by Stephan
The string literal [ does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
Coding Style Comprehensibility introduced by Stephan
The string literal <nowiki/>] does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
341
			"</div></div>" .
0 ignored issues
show
Coding Style Comprehensibility introduced by Stephan
The string literal </div></div> does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
342
			"<div class='mw-lingo-definition some-style-2'>" .
343
			"<div class='mw-lingo-definition-text'>\n" .
344
			"someDefinition2\n" .
345
			"</div>" .
0 ignored issues
show
Coding Style Comprehensibility introduced by Stephan
The string literal </div> does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
346
			"<div class='mw-lingo-definition-link'>" .
347
			"[" . $url2 . " <nowiki/>]" .
0 ignored issues
show
Coding Style Comprehensibility introduced by Stephan
The string literal [ does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
Coding Style Comprehensibility introduced by Stephan
The string literal <nowiki/>] does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
348
			"</div></div>\n" .
349
			"</div>",
0 ignored issues
show
Coding Style Comprehensibility introduced by Stephan
The string literal </div> does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
350
			$definitions
351
		);
352
	}
353
354
	/**
355
	 * Tests
356
	 * - if there is no link defined, no link is added to the list of definitions
357
	 * - if there is an invalid link, an error message is attached to the list of definitions and the link is omitted
358
	 */
359
	public function testGetFormattedDefinitions_2() {
360
		// Setup
361
		$term = 'some&Term';
362
363
		$definition1 = [
364
			Element::ELEMENT_TERM       => $term,
365
			Element::ELEMENT_DEFINITION => 'someDefinition1',
366
			Element::ELEMENT_LINK       => null,
367
			Element::ELEMENT_SOURCE     => null,
368
			Element::ELEMENT_STYLE      => null,
369
		];
370
371
		// $url1 = \Title::newFromText( $definition1[ Element::ELEMENT_LINK ] )->getFullURL();
372
373
		$definition2 = [
374
			Element::ELEMENT_TERM       => $term,
375
			Element::ELEMENT_DEFINITION => 'someDefinition2',
376
			Element::ELEMENT_LINK       => 'some[]InvalidLink2',
377
			Element::ELEMENT_SOURCE     => null,
378
			Element::ELEMENT_STYLE      => 'some-style-2',
379
		];
380
381
		// $url2 = \Title::newFromText( $definition2[ Element::ELEMENT_LINK ] )->getFullURL();
382
383
		$GLOBALS[ 'wgexLingoDisplayOnce' ] = false;
384
385
		$element = new Element( $term, $definition1 );
386
		$element->addDefinition( $definition2 );
387
		$node = $element->getFormattedTerm( $this->doc );
0 ignored issues
show
Unused Code introduced by Stephan
The assignment to $node is dead and can be removed.
Loading history...
388
389
		// Run
390
		$definitions = $element->getFormattedDefinitions();
391
392
		$this->assertEquals(
393
			"<div class='mw-lingo-tooltip' id='a8057b0494da505d2f7ac2e96e17083f'>" .
394
			"<div class='mw-lingo-definition '>" .
395
			"<div class='mw-lingo-definition-text'>\n" .
396
			"someDefinition1\n" .
397
			"</div>" .
0 ignored issues
show
Coding Style Comprehensibility introduced by Stephan
The string literal </div> does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
398
			"</div>" .
0 ignored issues
show
Coding Style Comprehensibility introduced by Stephan
The string literal </div> does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
399
			"<div class='mw-lingo-definition some-style-2'>" .
400
			"<div class='mw-lingo-definition-text'>\n" .
401
			"someDefinition2\n" .
402
			"</div></div>" .
0 ignored issues
show
Coding Style Comprehensibility introduced by Stephan
The string literal </div></div> does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
403
			"<div class='mw-lingo-definition invalid-link-target'>" .
404
			"<div class='mw-lingo-definition-text'>\n" .
405
			"Invalid link target for term \"some&Term\": some[]InvalidLink2\n" .
406
			"</div></div>\n" .
407
			"</div>",
0 ignored issues
show
Coding Style Comprehensibility introduced by Stephan
The string literal </div> does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
408
			$definitions
409
		);
410
	}
411
412
	/**
413
	 * Tests
414
	 * - if there is only one definition and its text is empty and it has a link, no definitions are produced
415
	 */
416
	public function testGetFormattedDefinitions_3() {
417
		// Setup
418
		$term = 'someTerm';
419
420
		$definition = [
421
			Element::ELEMENT_TERM       => $term,
422
			Element::ELEMENT_DEFINITION => null,
423
			Element::ELEMENT_LINK       => 'someLink',
424
			Element::ELEMENT_SOURCE     => null,
425
			Element::ELEMENT_STYLE      => null,
426
		];
427
428
		$GLOBALS[ 'wgexLingoDisplayOnce' ] = false;
429
430
		$element = new Element( $term, $definition );
431
		$node = $element->getFormattedTerm( $this->doc );
0 ignored issues
show
Unused Code introduced by Stephan
The assignment to $node is dead and can be removed.
Loading history...
432
433
		// Run
434
		$definitions = $element->getFormattedDefinitions();
435
436
		$this->assertEquals( '', $definitions );
437
	}
438
439
	/**
440
	 * Tests
441
	 * - if there is only one definition and its text is empty and it has an invalid link, the error message shows as tooltip
442
	 * - class 'invalid-link-target' is correctly applied to error message
443
	 * - if the term contains HTML-special characters, it is handled without raising an exception
444
	 */
445
	public function testGetFormattedDefinitions_4() {
446
		// Setup
447
		$term = 'some&Term';
448
449
		$definition = [
450
			Element::ELEMENT_TERM       => $term,
451
			Element::ELEMENT_DEFINITION => null,
452
			Element::ELEMENT_LINK       => 'foo[]bar',
453
			Element::ELEMENT_SOURCE     => null,
454
			Element::ELEMENT_STYLE      => null,
455
		];
456
457
		$GLOBALS[ 'wgexLingoDisplayOnce' ] = false;
458
459
		$element = new Element( $term, $definition );
460
		$node = $element->getFormattedTerm( $this->doc );
0 ignored issues
show
Unused Code introduced by Stephan
The assignment to $node is dead and can be removed.
Loading history...
461
462
		// Run
463
		$definitions = $element->getFormattedDefinitions();
464
465
		$this->assertEquals(
466
			"<div class='mw-lingo-tooltip' id='a8057b0494da505d2f7ac2e96e17083f'>" .
467
			"<div class='mw-lingo-definition invalid-link-target'>" .
468
			"<div class='mw-lingo-definition-text'>\n" .
469
			"Invalid link target for term \"some&Term\": foo[]bar\n" .
470
			"</div></div>\n</div>",
471
			$definitions
472
		);
473
	}
474
475
	/**
476
	 * @param \DOMElement $node
477
	 * @param string $tagName
478
	 * @param string $text
479
	 * @param string[] $expectedAttributes
480
	 * @param array $unexpectedAttributes
481
	 */
482
	protected function checkTermIsDomElement( $node, $tagName, $text, $expectedAttributes = [], $unexpectedAttributes = [] ) {
483
		$nodeText = $this->doc->saveHTML( $node );
0 ignored issues
show
Unused Code introduced by Stephan
The assignment to $nodeText is dead and can be removed.
Loading history...
484
485
		$this->assertInstanceOf( 'DOMElement', $node );
486
		$this->assertEquals( $tagName, $node->tagName );
487
		$this->assertEquals( $text, $node->textContent );
488
489
		if ( array_key_exists( 'class', $expectedAttributes ) ) {
490
491
			$classes = array_flip( array_filter( explode( ' ', $node->getAttribute( 'class' ) ) ) );
492
493
			foreach ( (array)$expectedAttributes[ 'class' ] as $expectedClass ) {
494
				$this->assertTrue( array_key_exists( $expectedClass, $classes ) );
495
			}
496
497
			unset( $expectedAttributes[ 'class' ] );
498
		}
499
500
		foreach ( $expectedAttributes as $attribute => $value ) {
501
			$this->assertEquals( $value, $node->getAttribute( $attribute ) );
502
		}
503
504
		foreach ( $unexpectedAttributes as $attribute ) {
505
			$this->assertFalse( $node->hasAttribute( $attribute ) );
506
		}
507
	}
508
}
509