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

537 lines
13 KiB
PHP
Raw Normal View History

<?php
/**
* @group Xml
*/
class XmlTest extends MediaWikiTestCase {
Clean and repair many phpunit tests (+ fix implied configuration) This commit depends on the introduction of MediaWikiTestCase::setMwGlobals in change Iccf6ea81f4. Various tests already set their globals, but forgot to restore them afterwards, or forgot to call the parent setUp, tearDown... Either way they won't have to anymore with setMwGlobals. Consistent use of function characteristics: * protected function setUp * protected function tearDown * public static function (provide..) (Matching the function signature with PHPUnit/Framework/TestCase.php) Replaces: * public function (setUp|tearDown)\( * protected function $1( * \tfunction (setUp|tearDown)\( * \tprotected function $1( * \tfunction (data|provide)\( * \tpublic static function $1\( Also renamed a few "data#", "provider#" and "provides#" functions to "provide#" for consistency. This also removes confusion where the /media tests had a few private methods called dataFile(), which were sometimes expected to be data providers. Fixes: TimestampTest often failed due to a previous test setting a different language (it tests "1 hour ago" so need to make sure it is set to English). MWNamespaceTest became a lot cleaner now that it executes with a known context. Though the now-redundant code that was removed didn't work anyway because wgContentNamespaces isn't keyed by namespace id, it had them was values... FileBackendTest: * Fixed: "PHP Fatal: Using $this when not in object context" HttpTest * Added comment about: "PHP Fatal: Call to protected MWHttpRequest::__construct()" (too much unrelated code to fix in this commit) ExternalStoreTest * Add an assertTrue as well, without it the test is useless because regardless of whether wgExternalStores is true or false it only uses it if it is an array. Change-Id: I9d2b148e57bada64afeb7d5a99bec0e58f8e1561
2012-10-08 10:56:20 +00:00
protected function setUp() {
parent::setUp();
$langObj = Language::factory( 'en' );
$langObj->setNamespaces( [
-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',
100 => 'Custom',
101 => 'Custom_talk',
] );
$this->setMwGlobals( [
'wgLang' => $langObj,
'wgUseMediaWikiUIEverywhere' => false,
] );
}
protected function tearDown() {
Language::factory( 'en' )->resetNamespaces();
parent::tearDown();
}
/**
* @covers Xml::expandAttributes
*/
public function testExpandAttributes() {
$this->assertNull( Xml::expandAttributes( null ),
'Converting a null list of attributes'
);
$this->assertEquals( '', Xml::expandAttributes( [] ),
'Converting an empty list of attributes'
);
}
/**
* @covers Xml::expandAttributes
*/
public function testExpandAttributesException() {
$this->setExpectedException( 'MWException' );
Xml::expandAttributes( 'string' );
}
/**
* @covers Xml::element
*/
public function testElementOpen() {
$this->assertEquals(
'<element>',
Xml::element( 'element', null, null ),
'Opening element with no attributes'
);
}
/**
* @covers Xml::element
*/
public function testElementEmpty() {
$this->assertEquals(
'<element />',
Xml::element( 'element', null, '' ),
'Terminated empty element'
);
}
/**
* @covers Xml::input
*/
public function testElementInputCanHaveAValueOfZero() {
$this->assertEquals(
'<input name="name" value="0" />',
Xml::input( 'name', false, 0 ),
'Input with a value of 0 (T25797)'
);
}
/**
* @covers Xml::element
*/
public function testElementEscaping() {
$this->assertEquals(
'<element>hello &lt;there&gt; you &amp; you</element>',
Xml::element( 'element', null, 'hello <there> you & you' ),
'Element with no attributes and content that needs escaping'
);
}
/**
* @covers Xml::escapeTagsOnly
*/
public function testEscapeTagsOnly() {
$this->assertEquals( '&quot;&gt;&lt;', Xml::escapeTagsOnly( '"><' ),
'replace " > and < with their HTML entitites'
);
}
/**
* @covers Xml::element
*/
public function testElementAttributes() {
$this->assertEquals(
'<element key="value" <>="&lt;&gt;">',
Xml::element( 'element', [ 'key' => 'value', '<>' => '<>' ], null ),
'Element attributes, keys are not escaped'
);
}
/**
* @covers Xml::openElement
*/
public function testOpenElement() {
$this->assertEquals(
'<element k="v">',
Xml::openElement( 'element', [ 'k' => 'v' ] ),
'openElement() shortcut'
);
}
/**
* @covers Xml::closeElement
*/
public function testCloseElement() {
$this->assertEquals( '</element>', Xml::closeElement( 'element' ), 'closeElement() shortcut' );
}
/**
* @covers Xml::dateMenu
*/
public function testDateMenu() {
$curYear = intval( gmdate( 'Y' ) );
$prevYear = $curYear - 1;
$curMonth = intval( gmdate( 'n' ) );
$nextMonth = $curMonth + 1;
if ( $nextMonth == 13 ) {
$nextMonth = 1;
}
2011-02-06 21:23:12 +00:00
$this->assertEquals(
'<label for="year">From year (and earlier):</label> ' .
'<input id="year" maxlength="4" size="7" type="number" value="2011" name="year"/> ' .
'<label for="month">From month (and earlier):</label> ' .
'<select name="month" id="month" class="mw-month-selector">' .
'<option value="-1">all</option>' . "\n" .
'<option value="1">January</option>' . "\n" .
'<option value="2" selected="">February</option>' . "\n" .
'<option value="3">March</option>' . "\n" .
'<option value="4">April</option>' . "\n" .
'<option value="5">May</option>' . "\n" .
'<option value="6">June</option>' . "\n" .
'<option value="7">July</option>' . "\n" .
'<option value="8">August</option>' . "\n" .
'<option value="9">September</option>' . "\n" .
'<option value="10">October</option>' . "\n" .
'<option value="11">November</option>' . "\n" .
'<option value="12">December</option></select>',
2011-02-06 21:23:12 +00:00
Xml::dateMenu( 2011, 02 ),
"Date menu for february 2011"
);
$this->assertEquals(
'<label for="year">From year (and earlier):</label> ' .
'<input id="year" maxlength="4" size="7" type="number" value="2011" name="year"/> ' .
'<label for="month">From month (and earlier):</label> ' .
'<select name="month" id="month" class="mw-month-selector">' .
'<option value="-1">all</option>' . "\n" .
'<option value="1">January</option>' . "\n" .
'<option value="2">February</option>' . "\n" .
'<option value="3">March</option>' . "\n" .
'<option value="4">April</option>' . "\n" .
'<option value="5">May</option>' . "\n" .
'<option value="6">June</option>' . "\n" .
'<option value="7">July</option>' . "\n" .
'<option value="8">August</option>' . "\n" .
'<option value="9">September</option>' . "\n" .
'<option value="10">October</option>' . "\n" .
'<option value="11">November</option>' . "\n" .
'<option value="12">December</option></select>',
Xml::dateMenu( 2011, -1 ),
2011-02-06 21:23:12 +00:00
"Date menu with negative month for 'All'"
);
$this->assertEquals(
Xml::dateMenu( $curYear, $curMonth ),
Xml::dateMenu( '', $curMonth ),
"Date menu year is the current one when not specified"
);
$wantedYear = $nextMonth == 1 ? $curYear : $prevYear;
$this->assertEquals(
Xml::dateMenu( $wantedYear, $nextMonth ),
Xml::dateMenu( '', $nextMonth ),
"Date menu next month is 11 months ago"
);
$this->assertEquals(
'<label for="year">From year (and earlier):</label> ' .
'<input id="year" maxlength="4" size="7" type="number" name="year"/> ' .
'<label for="month">From month (and earlier):</label> ' .
'<select name="month" id="month" class="mw-month-selector">' .
'<option value="-1">all</option>' . "\n" .
'<option value="1">January</option>' . "\n" .
'<option value="2">February</option>' . "\n" .
'<option value="3">March</option>' . "\n" .
'<option value="4">April</option>' . "\n" .
'<option value="5">May</option>' . "\n" .
'<option value="6">June</option>' . "\n" .
'<option value="7">July</option>' . "\n" .
'<option value="8">August</option>' . "\n" .
'<option value="9">September</option>' . "\n" .
'<option value="10">October</option>' . "\n" .
'<option value="11">November</option>' . "\n" .
'<option value="12">December</option></select>',
Xml::dateMenu( '', '' ),
"Date menu with neither year or month"
);
2011-02-06 21:23:12 +00:00
}
/**
* @covers Xml::textarea
*/
public function testTextareaNoContent() {
$this->assertEquals(
'<textarea name="name" id="name" cols="40" rows="5"></textarea>',
Xml::textarea( 'name', '' ),
'textarea() with not content'
);
}
/**
* @covers Xml::textarea
*/
public function testTextareaAttribs() {
$this->assertEquals(
'<textarea name="name" id="name" cols="20" rows="10">&lt;txt&gt;</textarea>',
Xml::textarea( 'name', '<txt>', 20, 10 ),
'textarea() with custom attribs'
);
}
/**
* @covers Xml::label
*/
public function testLabelCreation() {
$this->assertEquals(
'<label for="id">name</label>',
Xml::label( 'name', 'id' ),
'label() with no attribs'
);
}
/**
* @covers Xml::label
*/
public function testLabelAttributeCanOnlyBeClassOrTitle() {
$this->assertEquals(
'<label for="id">name</label>',
Xml::label( 'name', 'id', [ 'generated' => true ] ),
'label() can not be given a generated attribute'
);
$this->assertEquals(
'<label for="id" class="nice">name</label>',
Xml::label( 'name', 'id', [ 'class' => 'nice' ] ),
'label() can get a class attribute'
);
$this->assertEquals(
'<label for="id" title="nice tooltip">name</label>',
Xml::label( 'name', 'id', [ 'title' => 'nice tooltip' ] ),
'label() can get a title attribute'
);
$this->assertEquals(
'<label for="id" class="nice" title="nice tooltip">name</label>',
Xml::label( 'name', 'id', [
'generated' => true,
'class' => 'nice',
'title' => 'nice tooltip',
'anotherattr' => 'value',
]
),
'label() skip all attributes but "class" and "title"'
);
}
/**
* @covers Xml::languageSelector
*/
public function testLanguageSelector() {
$select = Xml::languageSelector( 'en', true, null,
[ 'id' => 'testlang' ], wfMessage( 'yourlanguage' ) );
$this->assertEquals(
'<label for="testlang">Language:</label>',
$select[0]
);
}
/**
* @covers Xml::encodeJsVar
*/
public function testEncodeJsVarBoolean() {
$this->assertEquals(
'true',
Xml::encodeJsVar( true ),
'encodeJsVar() with boolean'
);
}
/**
* @covers Xml::encodeJsVar
*/
public function testEncodeJsVarNull() {
$this->assertEquals(
'null',
Xml::encodeJsVar( null ),
'encodeJsVar() with null'
);
}
/**
* @covers Xml::encodeJsVar
*/
public function testEncodeJsVarArray() {
$this->assertEquals(
'["a",1]',
Xml::encodeJsVar( [ 'a', 1 ] ),
'encodeJsVar() with array'
);
$this->assertEquals(
'{"a":"a","b":1}',
Xml::encodeJsVar( [ 'a' => 'a', 'b' => 1 ] ),
'encodeJsVar() with associative array'
);
}
/**
* @covers Xml::encodeJsVar
*/
public function testEncodeJsVarObject() {
$this->assertEquals(
'{"a":"a","b":1}',
Xml::encodeJsVar( (object)[ 'a' => 'a', 'b' => 1 ] ),
'encodeJsVar() with object'
);
}
/**
* @covers Xml::encodeJsVar
*/
public function testEncodeJsVarInt() {
$this->assertEquals(
'123456',
Xml::encodeJsVar( 123456 ),
'encodeJsVar() with int'
);
}
/**
* @covers Xml::encodeJsVar
*/
public function testEncodeJsVarFloat() {
$this->assertEquals(
'1.23456',
Xml::encodeJsVar( 1.23456 ),
'encodeJsVar() with float'
);
}
/**
* @covers Xml::encodeJsVar
*/
public function testEncodeJsVarIntString() {
$this->assertEquals(
'"123456"',
Xml::encodeJsVar( '123456' ),
'encodeJsVar() with int-like string'
);
}
/**
* @covers Xml::encodeJsVar
*/
public function testEncodeJsVarFloatString() {
$this->assertEquals(
'"1.23456"',
Xml::encodeJsVar( '1.23456' ),
'encodeJsVar() with float-like string'
);
}
/**
* @covers Xml::listDropDown
*/
public function testListDropDown() {
$this->assertEquals(
'<select name="test-name" id="test-name" class="test-css" tabindex="2">' .
'<option value="other">other reasons</option>' . "\n" .
'<optgroup label="Foo">' .
'<option value="Foo 1">Foo 1</option>' . "\n" .
'<option value="Example" selected="">Example</option>' . "\n" .
'</optgroup>' . "\n" .
'<optgroup label="Bar">' .
'<option value="Bar 1">Bar 1</option>' . "\n" .
'</optgroup>' .
'</select>',
Xml::listDropDown(
// name
'test-name',
// source list
"* Foo\n** Foo 1\n** Example\n* Bar\n** Bar 1",
// other
'other reasons',
// selected
'Example',
// class
'test-css',
// tabindex
2
)
);
}
/**
* @covers Xml::listDropDownOptions
*/
public function testListDropDownOptions() {
$this->assertEquals(
[
'other reasons' => 'other',
'Foo' => [
'Foo 1' => 'Foo 1',
'Example' => 'Example',
],
'Bar' => [
'Bar 1' => 'Bar 1',
],
],
Xml::listDropDownOptions(
"* Foo\n** Foo 1\n** Example\n* Bar\n** Bar 1",
[ 'other' => 'other reasons' ]
)
);
}
/**
* @covers Xml::listDropDownOptionsOoui
*/
public function testListDropDownOptionsOoui() {
$this->assertEquals(
[
[ 'data' => 'other', 'label' => 'other reasons' ],
[ 'optgroup' => 'Foo' ],
[ 'data' => 'Foo 1', 'label' => 'Foo 1' ],
[ 'data' => 'Example', 'label' => 'Example' ],
[ 'optgroup' => 'Bar' ],
[ 'data' => 'Bar 1', 'label' => 'Bar 1' ],
],
Xml::listDropDownOptionsOoui( [
'other reasons' => 'other',
'Foo' => [
'Foo 1' => 'Foo 1',
'Example' => 'Example',
],
'Bar' => [
'Bar 1' => 'Bar 1',
],
] )
);
}
/**
* @covers Xml::fieldset
*/
public function testFieldset() {
$this->assertEquals(
"<fieldset>\n",
Xml::fieldset(),
'Opening tag'
);
$this->assertEquals(
"<fieldset>\n",
Xml::fieldset( false ),
'Opening tag (false means no legend)'
);
$this->assertEquals(
"<fieldset>\n",
Xml::fieldset( '' ),
'Opening tag (empty string also means no legend)'
);
$this->assertEquals(
"<fieldset>\n<legend>Foo</legend>\n",
Xml::fieldset( 'Foo' ),
'Opening tag with legend'
);
$this->assertEquals(
"<fieldset>\n<legend>Foo</legend>\nBar\n</fieldset>\n",
Xml::fieldset( 'Foo', 'Bar' ),
'Entire element with legend'
);
$this->assertEquals(
"<fieldset>\n<legend>Foo</legend>\n",
Xml::fieldset( 'Foo', false ),
'Opening tag with legend (false means no content and no closing tag)'
);
$this->assertEquals(
"<fieldset>\n<legend>Foo</legend>\n\n</fieldset>\n",
Xml::fieldset( 'Foo', '' ),
'Entire element with legend but no content (empty string generates a closing tag)'
);
$this->assertEquals(
"<fieldset class=\"bar\">\n<legend>Foo</legend>\nBar\n</fieldset>\n",
Xml::fieldset( 'Foo', 'Bar', [ 'class' => 'bar' ] ),
'Opening tag with legend and attributes'
);
$this->assertEquals(
"<fieldset class=\"bar\">\n<legend>Foo</legend>\n",
Xml::fieldset( 'Foo', false, [ 'class' => 'bar' ] ),
'Entire element with legend and attributes'
);
}
}