wiki.techinc.nl/tests/phpunit/includes/HtmlTest.php

369 lines
11 KiB
PHP
Raw Normal View History

<?php
/** tests for includes/Html.php */
class HtmlTest extends MediaWikiTestCase {
private static $oldLang;
private static $oldContLang;
private static $oldLanguageCode;
private static $oldNamespaces;
private static $oldHTML5;
public function setUp() {
global $wgLang, $wgContLang, $wgLanguageCode, $wgHTML5;
// Save globals
self::$oldLang = $wgLang;
self::$oldContLang = $wgContLang;
self::$oldNamespaces = $wgContLang->getNamespaces();
self::$oldLanguageCode = $wgLanguageCode;
self::$oldHTML5 = $wgHTML5;
$wgLanguageCode = 'en';
$wgContLang = $wgLang = Language::factory( $wgLanguageCode );
// Hardcode namespaces during test runs,
// so that html output based on existing namespaces
// can be properly evaluated.
$wgContLang->setNamespaces( array(
-2 => 'Media',
-1 => 'Special',
0 => '',
1 => 'Talk',
2 => 'User',
3 => 'User_talk',
4 => 'MyWiki',
5 => 'MyWiki_Talk',
6 => 'File',
7 => 'File_talk',
8 => 'MediaWiki',
9 => 'MediaWiki_talk',
10 => 'Template',
11 => 'Template_talk',
14 => 'Category',
15 => 'Category_talk',
100 => 'Custom',
101 => 'Custom_talk',
) );
}
public function tearDown() {
global $wgLang, $wgContLang, $wgLanguageCode, $wgHTML5;
// Restore globals
$wgContLang->setNamespaces( self::$oldNamespaces );
$wgLang = self::$oldLang;
$wgContLang = self::$oldContLang;
$wgLanguageCode = self::$oldLanguageCode;
$wgHTML5 = self::$oldHTML5;
}
/**
* Wrapper to easily set $wgHTML5 = true.
* Original value will be restored after test completion.
* @todo Move to MediaWikiTestCase
*/
public function enableHTML5() {
global $wgHTML5;
$wgHTML5 = true;
}
/**
* Wrapper to easily set $wgHTML5 = false
* Original value will be restored after test completion.
* @todo Move to MediaWikiTestCase
*/
public function disableHTML5() {
global $wgHTML5;
$wgHTML5 = false;
}
public function testExpandAttributesSkipsNullAndFalse() {
### EMPTY ########
$this->AssertEmpty(
2011-09-03 01:42:43 +00:00
Html::expandAttributes( array( 'foo' => null ) ),
'skip keys with null value'
);
$this->AssertEmpty(
2011-09-03 01:42:43 +00:00
Html::expandAttributes( array( 'foo' => false ) ),
'skip keys with false value'
);
$this->AssertNotEmpty(
2011-09-03 01:42:43 +00:00
Html::expandAttributes( array( 'foo' => '' ) ),
'keep keys with an empty string'
);
}
public function testExpandAttributesForBooleans() {
global $wgHtml5;
$this->AssertEquals(
'',
2011-09-03 01:42:43 +00:00
Html::expandAttributes( array( 'selected' => false ) ),
'Boolean attributes do not generates output when value is false'
);
$this->AssertEquals(
'',
2011-09-03 01:42:43 +00:00
Html::expandAttributes( array( 'selected' => null ) ),
'Boolean attributes do not generates output when value is null'
);
$this->AssertEquals(
$wgHtml5 ? ' selected=""' : ' selected="selected"',
2011-09-03 01:42:43 +00:00
Html::expandAttributes( array( 'selected' => true ) ),
'Boolean attributes skip value output'
);
$this->AssertEquals(
$wgHtml5 ? ' selected=""' : ' selected="selected"',
Html::expandAttributes( array( 'selected' ) ),
'Boolean attributes (ex: selected) do not need a value'
);
}
/**
* Test for Html::expandAttributes()
* Please note it output a string prefixed with a space!
*/
public function testExpandAttributesVariousExpansions() {
### NOT EMPTY ####
$this->AssertEquals(
' empty_string=""',
2011-09-03 01:42:43 +00:00
Html::expandAttributes( array( 'empty_string' => '' ) ),
'Value with an empty string'
);
$this->AssertEquals(
' key="value"',
2011-09-03 01:42:43 +00:00
Html::expandAttributes( array( 'key' => 'value' ) ),
'Value is a string'
);
$this->AssertEquals(
' one="1"',
2011-09-03 01:42:43 +00:00
Html::expandAttributes( array( 'one' => 1 ) ),
'Value is a numeric one'
);
$this->AssertEquals(
' zero="0"',
2011-09-03 01:42:43 +00:00
Html::expandAttributes( array( 'zero' => 0 ) ),
'Value is a numeric zero'
);
}
Html.php: The "future"[1] is here. Add features for space-separated value attributes of html elements. * Has been suggested since August 2009 in r54767 (doc-comment from rawElement/element function) * Implements normalization for these attributes (removal of duplicates and redundant space) * Adds support for arrays (instead of just string) for these attributes. * String are still supported, and are converted to arrays to get the same normalization. * Wrote unit tests (which pass locally: $ php phpunit.php includes/HtmlTest.php) * Not trigger for the media-attribute. Reason: Although some people think it's space-separated, it's actually comma-separated. Treating them as space separated might even destroy the value. [2] [3]. Neither the html4 or html5 spec documents media-attribute as space-separated, and as of HTML5/CSS3 the media attribute may contain "media queries". [1] "In the future, other HTML-specific features might be added, like allowing arrays for the values of attributes like class= and media=" in r54767 by Simetrical. [2] http://www.w3.org/TR/1999/REC-html401-19991224/types.html#h-6.13 [3] http://dev.w3.org/csswg/css3-mediaqueries/#background Implementation note: I choose to have a single list of attributes that trigger this feature. Some of these attributes only support multiple values and/or are documented as space-separated as of html5 (such as accesskey), but since those attributes in general have existed in html4 as well (just different w3c spec), they are not stripped if wgHtml5 is not true. So if this feature would (eg. for accesskey) would only be done if wgHtml5=true, then people could get output like <a accesskey=Array /> depending on a configuration variable, which will get messy and make developers' life hard.
2011-09-03 03:55:23 +00:00
/**
* Html::expandAttributes has special features for HTML
* attributes that use space separated lists and also
* allows arrays to be used as values.
*/
public function testExpandAttributesListValueAttributes() {
### STRING VALUES
$this->AssertEquals(
' class="redundant spaces here"',
Html::expandAttributes( array( 'class' => ' redundant spaces here ' ) ),
'Normalization should strip redundant spaces'
);
$this->AssertEquals(
' class="foo bar"',
Html::expandAttributes( array( 'class' => 'foo bar foo bar bar' ) ),
'Normalization should remove duplicates in string-lists'
);
### "EMPTY" ARRAY VALUES
$this->AssertEquals(
' class=""',
Html::expandAttributes( array( 'class' => array() ) ),
'Value with an empty array'
);
$this->AssertEquals(
' class=""',
Html::expandAttributes( array( 'class' => array( null, '', ' ', ' ' ) ) ),
'Array with null, empty string and spaces'
);
### NON-EMPTY ARRAY VALUES
$this->AssertEquals(
' class="foo bar"',
Html::expandAttributes( array( 'class' => array(
'foo',
'bar',
'foo',
'bar',
'bar',
) ) ),
'Normalization should remove duplicates in the array'
);
$this->AssertEquals(
' class="foo bar"',
Html::expandAttributes( array( 'class' => array(
'foo bar',
'bar foo',
'foo',
'bar bar',
) ) ),
'Normalization should remove duplicates in string-lists in the array'
);
}
/**
* Test feature added by r96188, let pass attributes values as
* a PHP array. Restricted to class,rel, accesskey.
*/
function testExpandAttributesSpaceSeparatedAttributesWithBoolean() {
$this->assertEquals(
' class="booltrue one"',
Html::expandAttributes( array( 'class' => array(
'booltrue' => true,
'one' => 1,
# Method use isset() internally, make sure we do discard
# attributes values which have been assigned well known values
'emptystring' => '',
'boolfalse' => false,
'zero' => 0,
'null' => null,
)))
);
}
/**
* How do we handle duplicate keys in HTML attributes expansion?
* We could pass a "class" the values: 'GREEN' and array( 'GREEN' => false )
* The later will take precedence.
*
* Feature added by r96188
*/
function testValueIsAuthoritativeInSpaceSeparatedAttributesArrays() {
$this->assertEquals(
' class=""',
2011-10-27 15:54:49 +00:00
Html::expandAttributes( array( 'class' => array(
'GREEN',
'GREEN' => false,
'GREEN',
)))
);
}
function testNamespaceSelector() {
$this->assertEquals(
'<select>' . "\n" .
'<option value="0">(Main)</option>' . "\n" .
'<option value="1">Talk</option>' . "\n" .
'<option value="2">User</option>' . "\n" .
'<option value="3">User talk</option>' . "\n" .
'<option value="4">MyWiki</option>' . "\n" .
'<option value="5">MyWiki Talk</option>' . "\n" .
'<option value="6">File</option>' . "\n" .
'<option value="7">File talk</option>' . "\n" .
'<option value="8">MediaWiki</option>' . "\n" .
'<option value="9">MediaWiki talk</option>' . "\n" .
'<option value="10">Template</option>' . "\n" .
'<option value="11">Template talk</option>' . "\n" .
'<option value="14">Category</option>' . "\n" .
'<option value="15">Category talk</option>' . "\n" .
'<option value="100">Custom</option>' . "\n" .
'<option value="101">Custom talk</option>' . "\n" .
'</select>',
Html::namespaceSelector(),
'Basic namespace selector without custom options'
);
$this->assertEquals(
'<label for="mw-test-namespace">Select a namespace:</label>&#160;' .
'<select id="mw-test-namespace" name="wpNamespace">' . "\n" .
'<option value="all">all</option>' . "\n" .
'<option value="0">(Main)</option>' . "\n" .
'<option value="1">Talk</option>' . "\n" .
'<option value="2" selected="">User</option>' . "\n" .
'<option value="3">User talk</option>' . "\n" .
'<option value="4">MyWiki</option>' . "\n" .
'<option value="5">MyWiki Talk</option>' . "\n" .
'<option value="6">File</option>' . "\n" .
'<option value="7">File talk</option>' . "\n" .
'<option value="8">MediaWiki</option>' . "\n" .
'<option value="9">MediaWiki talk</option>' . "\n" .
'<option value="10">Template</option>' . "\n" .
'<option value="11">Template talk</option>' . "\n" .
'<option value="14">Category</option>' . "\n" .
'<option value="15">Category talk</option>' . "\n" .
'<option value="100">Custom</option>' . "\n" .
'<option value="101">Custom talk</option>' . "\n" .
'</select>',
Html::namespaceSelector(
array( 'selected' => '2', 'all' => 'all', 'label' => 'Select a namespace:' ),
array( 'name' => 'wpNamespace', 'id' => 'mw-test-namespace' )
),
'Basic namespace selector with custom values'
);
$this->assertEquals(
'<label>Select a namespace:</label>&#160;' .
'<select>' . "\n" .
'<option value="0">(Main)</option>' . "\n" .
'<option value="1">Talk</option>' . "\n" .
'<option value="2">User</option>' . "\n" .
'<option value="3">User talk</option>' . "\n" .
'<option value="4">MyWiki</option>' . "\n" .
'<option value="5">MyWiki Talk</option>' . "\n" .
'<option value="6">File</option>' . "\n" .
'<option value="7">File talk</option>' . "\n" .
'<option value="8">MediaWiki</option>' . "\n" .
'<option value="9">MediaWiki talk</option>' . "\n" .
'<option value="10">Template</option>' . "\n" .
'<option value="11">Template talk</option>' . "\n" .
'<option value="14">Category</option>' . "\n" .
'<option value="15">Category talk</option>' . "\n" .
'<option value="100">Custom</option>' . "\n" .
'<option value="101">Custom talk</option>' . "\n" .
'</select>',
Html::namespaceSelector(
array( 'label' => 'Select a namespace:' )
),
'Basic namespace selector with a custom label but no id attribtue for the <select>'
);
}
function testCanFilterOutNamespaces() {
$this->assertEquals(
'<select>' . "\n" .
'<option value="2">User</option>' . "\n" .
'<option value="4">MyWiki</option>' . "\n" .
'<option value="5">MyWiki Talk</option>' . "\n" .
'<option value="6">File</option>' . "\n" .
'<option value="7">File talk</option>' . "\n" .
'<option value="8">MediaWiki</option>' . "\n" .
'<option value="9">MediaWiki talk</option>' . "\n" .
'<option value="10">Template</option>' . "\n" .
'<option value="11">Template talk</option>' . "\n" .
'<option value="14">Category</option>' . "\n" .
'<option value="15">Category talk</option>' . "\n" .
'</select>',
Html::namespaceSelector(
array( 'exclude' => array( 0, 1, 3, 100, 101 ) )
),
'Namespace selector namespace filtering.'
);
}
function testCanDisableANamespaces() {
$this->assertEquals(
'<select>' . "\n" .
'<option disabled="" value="0">(Main)</option>' . "\n" .
'<option disabled="" value="1">Talk</option>' . "\n" .
'<option disabled="" value="2">User</option>' . "\n" .
'<option disabled="" value="3">User talk</option>' . "\n" .
'<option disabled="" value="4">MyWiki</option>' . "\n" .
'<option value="5">MyWiki Talk</option>' . "\n" .
'<option value="6">File</option>' . "\n" .
'<option value="7">File talk</option>' . "\n" .
'<option value="8">MediaWiki</option>' . "\n" .
'<option value="9">MediaWiki talk</option>' . "\n" .
'<option value="10">Template</option>' . "\n" .
'<option value="11">Template talk</option>' . "\n" .
'<option value="14">Category</option>' . "\n" .
'<option value="15">Category talk</option>' . "\n" .
'<option value="100">Custom</option>' . "\n" .
'<option value="101">Custom talk</option>' . "\n" .
'</select>',
Html::namespaceSelector( array(
'disable' => array( 0, 1, 2, 3, 4 )
) ),
'Namespace selector namespace disabling'
);
}
}