2 /** tests for includes/Html.php */
4 class HtmlTest
extends MediaWikiTestCase
{
5 private static $oldLang;
6 private static $oldContLang;
7 private static $oldLanguageCode;
8 private static $oldNamespaces;
10 public function setUp() {
11 global $wgLang, $wgContLang, $wgLanguageCode;
13 self
::$oldLang = $wgLang;
14 self
::$oldContLang = $wgContLang;
15 self
::$oldNamespaces = $wgContLang->getNamespaces();
16 self
::$oldLanguageCode = $wgLanguageCode;
18 $wgLanguageCode = 'en';
19 $wgContLang = $wgLang = Language
::factory( $wgLanguageCode );
21 // Hardcode namespaces during test runs,
22 // so that html output based on existing namespaces
23 // can be properly evaluated.
24 $wgContLang->setNamespaces( array(
36 9 => 'MediaWiki_talk',
38 11 => 'Template_talk',
40 15 => 'Category_talk',
46 public function tearDown() {
47 global $wgLang, $wgContLang, $wgLanguageCode;
49 $wgContLang->setNamespaces( self
::$oldNamespaces );
50 $wgLang = self
::$oldLang;
51 $wgContLang = self
::$oldContLang;
52 $wgLanguageCode = self
::$oldLanguageCode;
55 public function testExpandAttributesSkipsNullAndFalse() {
59 Html
::expandAttributes( array( 'foo' => null ) ),
60 'skip keys with null value'
63 Html
::expandAttributes( array( 'foo' => false ) ),
64 'skip keys with false value'
66 $this->AssertNotEmpty(
67 Html
::expandAttributes( array( 'foo' => '' ) ),
68 'keep keys with an empty string'
72 public function testExpandAttributesForBooleans() {
76 Html
::expandAttributes( array( 'selected' => false ) ),
77 'Boolean attributes do not generates output when value is false'
81 Html
::expandAttributes( array( 'selected' => null ) ),
82 'Boolean attributes do not generates output when value is null'
86 $wgHtml5 ?
' selected=""' : ' selected="selected"',
87 Html
::expandAttributes( array( 'selected' => true ) ),
88 'Boolean attributes skip value output'
91 $wgHtml5 ?
' selected=""' : ' selected="selected"',
92 Html
::expandAttributes( array( 'selected' ) ),
93 'Boolean attributes (ex: selected) do not need a value'
98 * Test for Html::expandAttributes()
99 * Please note it output a string prefixed with a space!
101 public function testExpandAttributesVariousExpansions() {
105 Html
::expandAttributes( array( 'empty_string' => '' ) ),
106 'Value with an empty string'
110 Html
::expandAttributes( array( 'key' => 'value' ) ),
115 Html
::expandAttributes( array( 'one' => 1 ) ),
116 'Value is a numeric one'
120 Html
::expandAttributes( array( 'zero' => 0 ) ),
121 'Value is a numeric zero'
126 * Html::expandAttributes has special features for HTML
127 * attributes that use space separated lists and also
128 * allows arrays to be used as values.
130 public function testExpandAttributesListValueAttributes() {
133 ' class="redundant spaces here"',
134 Html
::expandAttributes( array( 'class' => ' redundant spaces here ' ) ),
135 'Normalization should strip redundant spaces'
139 Html
::expandAttributes( array( 'class' => 'foo bar foo bar bar' ) ),
140 'Normalization should remove duplicates in string-lists'
142 ### "EMPTY" ARRAY VALUES
145 Html
::expandAttributes( array( 'class' => array() ) ),
146 'Value with an empty array'
150 Html
::expandAttributes( array( 'class' => array( null, '', ' ', ' ' ) ) ),
151 'Array with null, empty string and spaces'
153 ### NON-EMPTY ARRAY VALUES
156 Html
::expandAttributes( array( 'class' => array(
163 'Normalization should remove duplicates in the array'
167 Html
::expandAttributes( array( 'class' => array(
173 'Normalization should remove duplicates in string-lists in the array'
178 * Test feature added by r96188, let pass attributes values as
179 * a PHP array. Restricted to class,rel, accesskey.
181 function testExpandAttributesSpaceSeparatedAttributesWithBoolean() {
183 ' class="booltrue one"',
184 Html
::expandAttributes( array( 'class' => array(
188 # Method use isset() internally, make sure we do discard
189 # attributes values which have been assigned well known values
191 'boolfalse' => false,
199 * How do we handle duplicate keys in HTML attributes expansion?
200 * We could pass a "class" the values: 'GREEN' and array( 'GREEN' => false )
201 * The later will take precedence.
203 * Feature added by r96188
205 function testValueIsAuthoritativeInSpaceSeparatedAttributesArrays() {
208 Html
::expandAttributes( array( 'class' => array(
216 function testNamespaceSelector() {
218 '<select id="namespace" name="namespace">' . "\n" .
219 '<option value="0">(Main)</option>' . "\n" .
220 '<option value="1">Talk</option>' . "\n" .
221 '<option value="2">User</option>' . "\n" .
222 '<option value="3">User talk</option>' . "\n" .
223 '<option value="4">MyWiki</option>' . "\n" .
224 '<option value="5">MyWiki Talk</option>' . "\n" .
225 '<option value="6">File</option>' . "\n" .
226 '<option value="7">File talk</option>' . "\n" .
227 '<option value="8">MediaWiki</option>' . "\n" .
228 '<option value="9">MediaWiki talk</option>' . "\n" .
229 '<option value="10">Template</option>' . "\n" .
230 '<option value="11">Template talk</option>' . "\n" .
231 '<option value="14">Category</option>' . "\n" .
232 '<option value="15">Category talk</option>' . "\n" .
233 '<option value="100">Custom</option>' . "\n" .
234 '<option value="101">Custom talk</option>' . "\n" .
236 Html
::namespaceSelector(),
237 'Basic namespace selector without custom options'
240 '<label for="mw-test-namespace">Select a namespace:</label> ' .
241 '<select id="mw-test-namespace" name="wpNamespace">' . "\n" .
242 '<option value="all">all</option>' . "\n" .
243 '<option value="0">(Main)</option>' . "\n" .
244 '<option value="1">Talk</option>' . "\n" .
245 '<option value="2" selected="">User</option>' . "\n" .
246 '<option value="3">User talk</option>' . "\n" .
247 '<option value="4">MyWiki</option>' . "\n" .
248 '<option value="5">MyWiki Talk</option>' . "\n" .
249 '<option value="6">File</option>' . "\n" .
250 '<option value="7">File talk</option>' . "\n" .
251 '<option value="8">MediaWiki</option>' . "\n" .
252 '<option value="9">MediaWiki talk</option>' . "\n" .
253 '<option value="10">Template</option>' . "\n" .
254 '<option value="11">Template talk</option>' . "\n" .
255 '<option value="14">Category</option>' . "\n" .
256 '<option value="15">Category talk</option>' . "\n" .
257 '<option value="100">Custom</option>' . "\n" .
258 '<option value="101">Custom talk</option>' . "\n" .
260 Html
::namespaceSelector(
261 array( 'selected' => '2', 'all' => 'all', 'label' => 'Select a namespace:' ),
262 array( 'name' => 'wpNamespace', 'id' => 'mw-test-namespace' )
264 'Basic namespace selector with custom values'
268 function testCanFilterOutNamespaces() {
270 '<select id="namespace" name="namespace">' . "\n" .
271 '<option value="2">User</option>' . "\n" .
272 '<option value="4">MyWiki</option>' . "\n" .
273 '<option value="5">MyWiki Talk</option>' . "\n" .
274 '<option value="6">File</option>' . "\n" .
275 '<option value="7">File talk</option>' . "\n" .
276 '<option value="8">MediaWiki</option>' . "\n" .
277 '<option value="9">MediaWiki talk</option>' . "\n" .
278 '<option value="10">Template</option>' . "\n" .
279 '<option value="11">Template talk</option>' . "\n" .
280 '<option value="14">Category</option>' . "\n" .
281 '<option value="15">Category talk</option>' . "\n" .
283 Html
::namespaceSelector(
284 array( 'exclude' => array( 0, 1, 3, 100, 101 ) )
286 'Namespace selector namespace filtering.'
290 function testCanDisableANamespaces() {
292 '<select id="namespace" name="namespace">' . "\n" .
293 '<option disabled="" value="0">(Main)</option>' . "\n" .
294 '<option disabled="" value="1">Talk</option>' . "\n" .
295 '<option disabled="" value="2">User</option>' . "\n" .
296 '<option disabled="" value="3">User talk</option>' . "\n" .
297 '<option disabled="" value="4">MyWiki</option>' . "\n" .
298 '<option value="5">MyWiki Talk</option>' . "\n" .
299 '<option value="6">File</option>' . "\n" .
300 '<option value="7">File talk</option>' . "\n" .
301 '<option value="8">MediaWiki</option>' . "\n" .
302 '<option value="9">MediaWiki talk</option>' . "\n" .
303 '<option value="10">Template</option>' . "\n" .
304 '<option value="11">Template talk</option>' . "\n" .
305 '<option value="14">Category</option>' . "\n" .
306 '<option value="15">Category talk</option>' . "\n" .
307 '<option value="100">Custom</option>' . "\n" .
308 '<option value="101">Custom talk</option>' . "\n" .
310 Html
::namespaceSelector( array(
311 'disable' => array( 0, 1, 2, 3, 4 )
313 'Namespace selector namespace disabling'
317 function testNamespaceSelectorIdAndNameDefaultsAttributes() {
319 $this->assertNsSelectorIdAndName(
320 'namespace', 'namespace',
321 Html
::namespaceSelector( array(), array(
322 # neither 'id' nor 'name' key given
324 "Neither 'id' nor 'name' key given"
327 $this->assertNsSelectorIdAndName(
328 'namespace', 'select_name',
329 Html
::namespaceSelector( array(), array(
330 'name' => 'select_name',
333 "No 'id' key given, 'name' given"
336 $this->assertNsSelectorIdAndName(
337 'select_id', 'namespace',
338 Html
::namespaceSelector( array(), array(
340 # no 'name' key given
342 "'id' given, no 'name' key given"
345 $this->assertNsSelectorIdAndName(
346 'select_id', 'select_name',
347 Html
::namespaceSelector( array(), array(
349 'name' => 'select_name',
351 "Both 'id' and 'name' given"
356 * Helper to verify <select> attributes generated by Html::namespaceSelector()
357 * This helper expect the Html method to use 'namespace' as a default value for
358 * both 'id' and 'name' attributes.
360 * @param String $expectedId <select> id attribute value
361 * @param String $expectedName <select> name attribute value
362 * @param String $html Output of a call to Html::namespaceSelector()
363 * @param String $msg Optional message (default: '')
365 function assertNsSelectorIdAndName( $expectedId, $expectedName, $html, $msg = '' ) {
366 $actualId = 'namespace';
367 if( 1 === preg_match( '/id="(.+?)"/', $html, $m ) ) {
371 $actualName = 'namespace';
372 if( 1 === preg_match( '/name="(.+?)"/', $html, $m ) ) {
378 'name' => $expectedName,
382 'name' => $actualName,
384 'Html::namespaceSelector() got wrong id and/or name attribute(s). ' . $msg