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() {
220 '<select id="namespace" name="namespace">' . "\n" .
221 '<option value="0">(Main)</option>' . "\n" .
222 '<option value="1">Talk</option>' . "\n" .
223 '<option value="2">User</option>' . "\n" .
224 '<option value="3">User talk</option>' . "\n" .
225 '<option value="4">MyWiki</option>' . "\n" .
226 '<option value="5">MyWiki Talk</option>' . "\n" .
227 '<option value="6">File</option>' . "\n" .
228 '<option value="7">File talk</option>' . "\n" .
229 '<option value="8">MediaWiki</option>' . "\n" .
230 '<option value="9">MediaWiki talk</option>' . "\n" .
231 '<option value="10">Template</option>' . "\n" .
232 '<option value="11">Template talk</option>' . "\n" .
233 '<option value="14">Category</option>' . "\n" .
234 '<option value="15">Category talk</option>' . "\n" .
235 '<option value="100">Custom</option>' . "\n" .
236 '<option value="101">Custom talk</option>' . "\n" .
238 Html
::namespaceSelector(),
239 'Basic namespace selector without custom options'
242 '<label for="mw-test-namespace">Select a namespace:</label> ' .
243 '<select id="mw-test-namespace" name="wpNamespace">' . "\n" .
244 '<option value="all">all</option>' . "\n" .
245 '<option value="0">(Main)</option>' . "\n" .
246 '<option value="1">Talk</option>' . "\n" .
247 '<option value="2" selected="">User</option>' . "\n" .
248 '<option value="3">User talk</option>' . "\n" .
249 '<option value="4">MyWiki</option>' . "\n" .
250 '<option value="5">MyWiki Talk</option>' . "\n" .
251 '<option value="6">File</option>' . "\n" .
252 '<option value="7">File talk</option>' . "\n" .
253 '<option value="8">MediaWiki</option>' . "\n" .
254 '<option value="9">MediaWiki talk</option>' . "\n" .
255 '<option value="10">Template</option>' . "\n" .
256 '<option value="11">Template talk</option>' . "\n" .
257 '<option value="14">Category</option>' . "\n" .
258 '<option value="15">Category talk</option>' . "\n" .
259 '<option value="100">Custom</option>' . "\n" .
260 '<option value="101">Custom talk</option>' . "\n" .
262 Html
::namespaceSelector(
263 array( 'selected' => '2', 'all' => 'all', 'label' => 'Select a namespace:' ),
264 array( 'name' => 'wpNamespace', 'id' => 'mw-test-namespace' )
266 'Basic namespace selector with custom values'
268 $immovable = array();
269 $namespaces = $wgContLang->getNamespaces();
270 foreach ( $namespaces as $nsId => $nsName ) {
271 if ( !MWNamespace
::isMovable( intval( $nsId ) ) ) {
272 $immovable[] = $nsId;
276 '<select id="namespace" name="namespace">' . "\n" .
277 '<option value="0">(Main)</option>' . "\n" .
278 '<option value="1">Talk</option>' . "\n" .
279 '<option value="2">User</option>' . "\n" .
280 '<option value="3">User talk</option>' . "\n" .
281 '<option value="4">MyWiki</option>' . "\n" .
282 '<option value="5">MyWiki Talk</option>' . "\n" .
283 '<option value="6">File</option>' . "\n" .
284 '<option value="7">File talk</option>' . "\n" .
285 '<option value="8">MediaWiki</option>' . "\n" .
286 '<option value="9">MediaWiki talk</option>' . "\n" .
287 '<option value="10">Template</option>' . "\n" .
288 '<option value="11">Template talk</option>' . "\n" .
289 '<option disabled="" value="14">Category</option>' . "\n" .
290 '<option value="15">Category talk</option>' . "\n" .
292 Html
::namespaceSelector(
293 array( 'exclude' => array( 100, 101 ), 'disable' => $immovable )
295 'Namespace selector without the custom namespace and immovable namespaces disabled.'
299 function testNamespaceSelectorIdAndNameDefaultsAttributes() {
301 $this->assertNsSelectorIdAndName(
302 'namespace', 'namespace',
303 Html
::namespaceSelector( array(), array(
304 # neither 'id' nor 'name' key given
306 "Neither 'id' nor 'name' key given"
309 $this->assertNsSelectorIdAndName(
310 'namespace', 'select_name',
311 Html
::namespaceSelector( array(), array(
312 'name' => 'select_name',
315 "No 'id' key given, 'name' given"
318 $this->assertNsSelectorIdAndName(
319 'select_id', 'namespace',
320 Html
::namespaceSelector( array(), array(
322 # no 'name' key given
324 "'id' given, no 'name' key given"
327 $this->assertNsSelectorIdAndName(
328 'select_id', 'select_name',
329 Html
::namespaceSelector( array(), array(
331 'name' => 'select_name',
333 "Both 'id' and 'name' given"
338 * Helper to verify <select> attributes generated by Html::namespaceSelector()
339 * This helper expect the Html method to use 'namespace' as a default value for
340 * both 'id' and 'name' attributes.
342 * @param String $expectedId <select> id attribute value
343 * @param String $expectedName <select> name attribute value
344 * @param String $html Output of a call to Html::namespaceSelector()
345 * @param String $msg Optional message (default: '')
347 function assertNsSelectorIdAndName( $expectedId, $expectedName, $html, $msg = '' ) {
348 $actualId = 'namespace';
349 if( 1 === preg_match( '/id="(.+?)"/', $html, $m ) ) {
353 $actualName = 'namespace';
354 if( 1 === preg_match( '/name="(.+?)"/', $html, $m ) ) {
360 'name' => $expectedName,
364 'name' => $actualName,
366 'Html::namespaceSelector() got wrong id and/or name attribute(s). ' . $msg