diff options
| author | Luke Shumaker <LukeShu@sbcglobal.net> | 2014-01-28 09:50:25 -0500 | 
|---|---|---|
| committer | Luke Shumaker <LukeShu@sbcglobal.net> | 2014-01-28 09:50:25 -0500 | 
| commit | 5744df39e15f85c6cc8a9faf8924d77e76d2b216 (patch) | |
| tree | a8c8dd40a94d1fa0d5377566aa5548ae55a163da /tests/phpunit/languages/LanguageTest.php | |
| parent | 4bb2aeca1d198391ca856aa16c40b8559c68daec (diff) | |
| parent | 224b22a051051f6c2e494c3a2fb4adb42898e2d1 (diff) | |
Merge branch 'archwiki'
Conflicts:
	extensions/FluxBBAuthPlugin.php
	extensions/SyntaxHighlight_GeSHi/README
	extensions/SyntaxHighlight_GeSHi/SyntaxHighlight_GeSHi.class.php
	extensions/SyntaxHighlight_GeSHi/SyntaxHighlight_GeSHi.i18n.php
	extensions/SyntaxHighlight_GeSHi/SyntaxHighlight_GeSHi.php
	extensions/SyntaxHighlight_GeSHi/geshi/docs/CHANGES
	extensions/SyntaxHighlight_GeSHi/geshi/docs/THANKS
	extensions/SyntaxHighlight_GeSHi/geshi/docs/TODO
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/AbstractClass.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/AbstractClass_logo.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/AbstractMethod.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/AbstractPrivateClass.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/AbstractPrivateClass_logo.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/AbstractPrivateMethod.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Class.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Class_logo.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Constant.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Constructor.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Destructor.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Function.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Global.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/I.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Index.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Interface.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Interface_logo.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/L.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Lminus.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Lplus.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Method.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Page.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Page_logo.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/PrivateClass.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/PrivateClass_logo.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/PrivateMethod.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/PrivateVariable.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/StaticMethod.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/StaticVariable.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/T.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Tminus.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Tplus.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Variable.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/blank.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/class_folder.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/file.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/folder.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/function_folder.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/next_button.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/next_button_disabled.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/package.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/package_folder.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/previous_button.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/previous_button_disabled.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/private_class_logo.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/tutorial.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/tutorial_folder.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/up_button.png
	extensions/SyntaxHighlight_GeSHi/geshi/docs/geshi-doc.html
	extensions/SyntaxHighlight_GeSHi/geshi/docs/geshi-doc.txt
	extensions/SyntaxHighlight_GeSHi/geshi/geshi.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/4cs.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/6502acme.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/6502kickass.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/6502tasm.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/68000devpac.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/abap.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/actionscript.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/actionscript3.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/ada.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/algol68.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/apache.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/applescript.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/apt_sources.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/asm.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/asp.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/autoconf.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/autohotkey.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/autoit.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/avisynth.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/awk.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/bascomavr.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/bash.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/basic4gl.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/bf.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/bibtex.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/blitzbasic.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/bnf.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/boo.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/c.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/c_loadrunner.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/c_mac.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/caddcl.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/cadlisp.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/cfdg.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/cfm.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/chaiscript.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/cil.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/clojure.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/cmake.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/cobol.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/coffeescript.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/cpp-qt.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/cpp.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/csharp.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/css.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/cuesheet.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/d.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/dcs.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/delphi.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/diff.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/div.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/dos.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/dot.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/e.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/ecmascript.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/eiffel.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/email.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/epc.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/erlang.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/euphoria.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/f1.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/falcon.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/fo.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/fortran.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/freebasic.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/fsharp.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/gambas.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/gdb.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/genero.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/genie.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/gettext.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/glsl.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/gml.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/gnuplot.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/go.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/groovy.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/gwbasic.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/haskell.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/hicest.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/hq9plus.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/html4strict.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/html5.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/icon.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/idl.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/ini.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/inno.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/intercal.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/io.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/j.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/java.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/java5.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/javascript.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/jquery.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/kixtart.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/klonec.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/klonecpp.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/latex.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/lb.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/lisp.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/llvm.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/locobasic.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/logtalk.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/lolcode.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/lotusformulas.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/lotusscript.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/lscript.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/lsl2.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/lua.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/m68k.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/magiksf.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/make.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/mapbasic.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/matlab.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/mirc.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/mmix.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/modula2.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/modula3.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/mpasm.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/mxml.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/mysql.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/newlisp.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/nsis.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/oberon2.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/objc.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/objeck.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/ocaml-brief.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/ocaml.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/oobas.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/oracle11.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/oracle8.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/oxygene.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/oz.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/pascal.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/pcre.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/per.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/perl.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/perl6.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/pf.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/php-brief.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/php.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/pic16.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/pike.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/pixelbender.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/pli.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/plsql.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/postgresql.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/povray.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/powerbuilder.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/powershell.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/proftpd.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/progress.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/prolog.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/properties.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/providex.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/purebasic.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/pycon.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/python.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/q.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/qbasic.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/rails.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/rebol.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/reg.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/robots.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/rpmspec.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/rsplus.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/ruby.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/sas.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/scala.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/scheme.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/scilab.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/sdlbasic.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/smalltalk.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/smarty.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/sql.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/systemverilog.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/tcl.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/teraterm.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/text.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/thinbasic.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/tsql.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/typoscript.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/unicon.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/uscript.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/vala.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/vb.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/vbnet.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/verilog.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/vhdl.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/vim.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/visualfoxpro.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/visualprolog.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/whitespace.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/whois.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/winbatch.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/xbasic.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/xml.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/xorg_conf.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/xpp.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/yaml.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/z80.php
	extensions/SyntaxHighlight_GeSHi/geshi/geshi/zxbasic.php
Diffstat (limited to 'tests/phpunit/languages/LanguageTest.php')
| -rw-r--r-- | tests/phpunit/languages/LanguageTest.php | 648 | 
1 files changed, 573 insertions, 75 deletions
| diff --git a/tests/phpunit/languages/LanguageTest.php b/tests/phpunit/languages/LanguageTest.php index 2fa3e292..78929e23 100644 --- a/tests/phpunit/languages/LanguageTest.php +++ b/tests/phpunit/languages/LanguageTest.php @@ -1,23 +1,14 @@  <?php -class LanguageTest extends MediaWikiTestCase { - +class LanguageTest extends LanguageClassesTestCase {  	/** -	 * @var Language +	 * @covers Language::convertDoubleWidth +	 * @covers Language::normalizeForSearch  	 */ -	private $lang; - -	function setUp() { -		$this->lang = Language::factory( 'en' ); -	} -	function tearDown() { -		unset( $this->lang ); -	} - -	function testLanguageConvertDoubleWidthToSingleWidth() { +	public function testLanguageConvertDoubleWidthToSingleWidth() {  		$this->assertEquals(  			"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", -			$this->lang->normalizeForSearch( +			$this->getLang()->normalizeForSearch(  				"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"  			),  			'convertDoubleWidth() with the full alphabet and digits' @@ -25,13 +16,14 @@ class LanguageTest extends MediaWikiTestCase {  	}  	/** -	 * @dataProvider provideFormattableTimes +	 * @dataProvider provideFormattableTimes# +	 * @covers Language::formatTimePeriod  	 */ -	function testFormatTimePeriod( $seconds, $format, $expected, $desc ) { -		$this->assertEquals( $expected, $this->lang->formatTimePeriod( $seconds, $format ), $desc ); +	public function testFormatTimePeriod( $seconds, $format, $expected, $desc ) { +		$this->assertEquals( $expected, $this->getLang()->formatTimePeriod( $seconds, $format ), $desc );  	} -	function provideFormattableTimes() { +	public static function provideFormattableTimes() {  		return array(  			array(  				9.45, @@ -214,56 +206,59 @@ class LanguageTest extends MediaWikiTestCase {  				'formatTimePeriod() rounding, recursion, (>48h)'  			),  		); -  	} -	function testTruncate() { +	/** +	 * @covers Language::truncate +	 */ +	public function testTruncate() {  		$this->assertEquals(  			"XXX", -			$this->lang->truncate( "1234567890", 0, 'XXX' ), +			$this->getLang()->truncate( "1234567890", 0, 'XXX' ),  			'truncate prefix, len 0, small ellipsis'  		);  		$this->assertEquals(  			"12345XXX", -			$this->lang->truncate( "1234567890", 8, 'XXX' ), +			$this->getLang()->truncate( "1234567890", 8, 'XXX' ),  			'truncate prefix, small ellipsis'  		);  		$this->assertEquals(  			"123456789", -			$this->lang->truncate( "123456789", 5, 'XXXXXXXXXXXXXXX' ), +			$this->getLang()->truncate( "123456789", 5, 'XXXXXXXXXXXXXXX' ),  			'truncate prefix, large ellipsis'  		);  		$this->assertEquals(  			"XXX67890", -			$this->lang->truncate( "1234567890", -8, 'XXX' ), +			$this->getLang()->truncate( "1234567890", -8, 'XXX' ),  			'truncate suffix, small ellipsis'  		);  		$this->assertEquals(  			"123456789", -			$this->lang->truncate( "123456789", -5, 'XXXXXXXXXXXXXXX' ), +			$this->getLang()->truncate( "123456789", -5, 'XXXXXXXXXXXXXXX' ),  			'truncate suffix, large ellipsis'  		);  	}  	/** -	 * @dataProvider provideHTMLTruncateData() +	 * @dataProvider provideHTMLTruncateData +	 * @covers Language::truncateHTML  	 */ -	function testTruncateHtml( $len, $ellipsis, $input, $expected ) { +	public function testTruncateHtml( $len, $ellipsis, $input, $expected ) {  		// Actual HTML...  		$this->assertEquals(  			$expected, -			$this->lang->truncateHTML( $input, $len, $ellipsis ) +			$this->getLang()->truncateHTML( $input, $len, $ellipsis )  		);  	}  	/** -	 * Array format is ($len, $ellipsis, $input, $expected) +	 * @return array format is ($len, $ellipsis, $input, $expected)  	 */ -	function provideHTMLTruncateData() { +	public static function provideHTMLTruncateData() {  		return array(  			array( 0, 'XXX', "1234567890", "XXX" ),  			array( 8, 'XXX', "1234567890", "12345XXX" ), @@ -320,29 +315,148 @@ class LanguageTest extends MediaWikiTestCase {  	}  	/** +	 * Test Language::isWellFormedLanguageTag() +	 * @dataProvider provideWellFormedLanguageTags +	 * @covers Language::isWellFormedLanguageTag +	 */ +	public function testWellFormedLanguageTag( $code, $message = '' ) { +		$this->assertTrue( +			Language::isWellFormedLanguageTag( $code ), +			"validating code $code $message" +		); +	} + +	/** +	 * The test cases are based on the tests in the GaBuZoMeu parser +	 * written by Stéphane Bortzmeyer <bortzmeyer@nic.fr> +	 * and distributed as free software, under the GNU General Public Licence. +	 * http://www.bortzmeyer.org/gabuzomeu-parsing-language-tags.html +	 */ +	public static function provideWellFormedLanguageTags() { +		return array( +			array( 'fr', 'two-letter code' ), +			array( 'fr-latn', 'two-letter code with lower case script code' ), +			array( 'fr-Latn-FR', 'two-letter code with title case script code and uppercase country code' ), +			array( 'fr-Latn-419', 'two-letter code with title case script code and region number' ), +			array( 'fr-FR', 'two-letter code with uppercase' ), +			array( 'ax-TZ', 'Not in the registry, but well-formed' ), +			array( 'fr-shadok', 'two-letter code with variant' ), +			array( 'fr-y-myext-myext2', 'non-x singleton' ), +			array( 'fra-Latn', 'ISO 639 can be 3-letters' ), +			array( 'fra', 'three-letter language code' ), +			array( 'fra-FX', 'three-letter language code with country code' ), +			array( 'i-klingon', 'grandfathered with singleton' ), +			array( 'I-kLINgon', 'tags are case-insensitive...' ), +			array( 'no-bok', 'grandfathered without singleton' ), +			array( 'i-enochian', 'Grandfathered' ), +			array( 'x-fr-CH', 'private use' ), +			array( 'es-419', 'two-letter code with region number' ), +			array( 'en-Latn-GB-boont-r-extended-sequence-x-private', 'weird, but well-formed' ), +			array( 'ab-x-abc-x-abc', 'anything goes after x' ), +			array( 'ab-x-abc-a-a', 'anything goes after x, including several non-x singletons' ), +			array( 'i-default', 'grandfathered' ), +			array( 'abcd-Latn', 'Language of 4 chars reserved for future use' ), +			array( 'AaBbCcDd-x-y-any-x', 'Language of 5-8 chars, registered' ), +			array( 'de-CH-1901', 'with country and year' ), +			array( 'en-US-x-twain', 'with country and singleton' ), +			array( 'zh-cmn', 'three-letter variant' ), +			array( 'zh-cmn-Hant', 'three-letter variant and script' ), +			array( 'zh-cmn-Hant-HK', 'three-letter variant, script and country' ), +			array( 'xr-p-lze', 'Extension' ), +		); +	} + +	/** +	 * Negative test for Language::isWellFormedLanguageTag() +	 * @dataProvider provideMalformedLanguageTags +	 * @covers Language::isWellFormedLanguageTag +	 */ +	public function testMalformedLanguageTag( $code, $message = '' ) { +		$this->assertFalse( +			Language::isWellFormedLanguageTag( $code ), +			"validating that code $code is a malformed language tag - $message" +		); +	} + +	/** +	 * The test cases are based on the tests in the GaBuZoMeu parser +	 * written by Stéphane Bortzmeyer <bortzmeyer@nic.fr> +	 * and distributed as free software, under the GNU General Public Licence. +	 * http://www.bortzmeyer.org/gabuzomeu-parsing-language-tags.html +	 */ +	public static function provideMalformedLanguageTags() { +		return array( +			array( 'f', 'language too short' ), +			array( 'f-Latn', 'language too short with script' ), +			array( 'xr-lxs-qut', 'variants too short' ), # extlangS +			array( 'fr-Latn-F', 'region too short' ), +			array( 'a-value', 'language too short with region' ), +			array( 'tlh-a-b-foo', 'valid three-letter with wrong variant' ), +			array( 'i-notexist', 'grandfathered but not registered: invalid, even if we only test well-formedness' ), +			array( 'abcdefghi-012345678', 'numbers too long' ), +			array( 'ab-abc-abc-abc-abc', 'invalid extensions' ), +			array( 'ab-abcd-abc', 'invalid extensions' ), +			array( 'ab-ab-abc', 'invalid extensions' ), +			array( 'ab-123-abc', 'invalid extensions' ), +			array( 'a-Hant-ZH', 'short language with valid extensions' ), +			array( 'a1-Hant-ZH', 'invalid character in language' ), +			array( 'ab-abcde-abc', 'invalid extensions' ), +			array( 'ab-1abc-abc', 'invalid characters in extensions' ), +			array( 'ab-ab-abcd', 'invalid order of extensions' ), +			array( 'ab-123-abcd', 'invalid order of extensions' ), +			array( 'ab-abcde-abcd', 'invalid extensions' ), +			array( 'ab-1abc-abcd', 'invalid characters in extensions' ), +			array( 'ab-a-b', 'extensions too short' ), +			array( 'ab-a-x', 'extensions too short, even with singleton' ), +			array( 'ab--ab', 'two separators' ), +			array( 'ab-abc-', 'separator in the end' ), +			array( '-ab-abc', 'separator in the beginning' ), +			array( 'abcd-efg', 'language too long' ), +			array( 'aabbccddE', 'tag too long' ), +			array( 'pa_guru', 'A tag with underscore is invalid in strict mode' ), +			array( 'de-f', 'subtag too short' ), +		); +	} + +	/** +	 * Negative test for Language::isWellFormedLanguageTag() +	 * @covers Language::isWellFormedLanguageTag +	 */ +	public function testLenientLanguageTag() { +		$this->assertTrue( +			Language::isWellFormedLanguageTag( 'pa_guru', true ), +			'pa_guru is a well-formed language tag in lenient mode' +		); +	} + +	/**  	 * Test Language::isValidBuiltInCode()  	 * @dataProvider provideLanguageCodes +	 * @covers Language::isValidBuiltInCode  	 */ -	function testBuiltInCodeValidation( $code, $message = '' ) { +	public function testBuiltInCodeValidation( $code, $message = '' ) {  		$this->assertTrue( -			(bool) Language::isValidBuiltInCode( $code ), +			(bool)Language::isValidBuiltInCode( $code ),  			"validating code $code $message"  		);  	} -	function testBuiltInCodeValidationRejectUnderscore() { +	/** +	 * @covers Language::isValidBuiltInCode +	 */ +	public function testBuiltInCodeValidationRejectUnderscore() {  		$this->assertFalse( -			(bool) Language::isValidBuiltInCode( 'be_tarask' ), +			(bool)Language::isValidBuiltInCode( 'be_tarask' ),  			"reject underscore in language code"  		);  	} -	function provideLanguageCodes() { +	public static function provideLanguageCodes() {  		return array( -			array( 'fr'       , 'Two letters, minor case' ), -			array( 'EN'       , 'Two letters, upper case' ), -			array( 'tyv'      , 'Three letters' ), -			array( 'tokipona'   , 'long language code' ), +			array( 'fr', 'Two letters, minor case' ), +			array( 'EN', 'Two letters, upper case' ), +			array( 'tyv', 'Three letters' ), +			array( 'tokipona', 'long language code' ),  			array( 'be-tarask', 'With dash' ),  			array( 'Zh-classical', 'Begin with upper case, dash' ),  			array( 'Be-x-old', 'With extension (two dashes)' ), @@ -350,20 +464,103 @@ class LanguageTest extends MediaWikiTestCase {  	}  	/** +	 * Test Language::isKnownLanguageTag() +	 * @dataProvider provideKnownLanguageTags +	 * @covers Language::isKnownLanguageTag +	 */ +	public function testKnownLanguageTag( $code, $message = '' ) { +		$this->assertTrue( +			(bool)Language::isKnownLanguageTag( $code ), +			"validating code $code - $message" +		); +	} + +	public static function provideKnownLanguageTags() { +		return array( +			array( 'fr', 'simple code' ), +			array( 'bat-smg', 'an MW legacy tag' ), +			array( 'sgs', 'an internal standard MW name, for which a legacy tag is used externally' ), +		); +	} + +	/** +	 * @covers Language::isKnownLanguageTag +	 */ +	public function testKnownCldrLanguageTag() { +		if ( !class_exists( 'LanguageNames' ) ) { +			$this->markTestSkipped( 'The LanguageNames class is not available. The cldr extension is probably not installed.' ); +		} + +		$this->assertTrue( +			(bool)Language::isKnownLanguageTag( 'pal' ), +			'validating code "pal" an ancient language, which probably will not appear in Names.php, but appears in CLDR in English' +		); +	} + +	/** +	 * Negative tests for Language::isKnownLanguageTag() +	 * @dataProvider provideUnKnownLanguageTags +	 * @covers Language::isKnownLanguageTag +	 */ +	public function testUnknownLanguageTag( $code, $message = '' ) { +		$this->assertFalse( +			(bool)Language::isKnownLanguageTag( $code ), +			"checking that code $code is invalid - $message" +		); +	} + +	public static function provideUnknownLanguageTags() { +		return array( +			array( 'mw', 'non-existent two-letter code' ), +			array( 'foo"<bar', 'very invalid language code' ), +		); +	} + +	/** +	 * Test too short timestamp +	 * @expectedException MWException +	 * @covers Language::sprintfDate +	 */ +	public function testSprintfDateTooShortTimestamp() { +		$this->getLang()->sprintfDate( 'xiY', '1234567890123' ); +	} + +	/** +	 * Test too long timestamp +	 * @expectedException MWException +	 * @covers Language::sprintfDate +	 */ +	public function testSprintfDateTooLongTimestamp() { +		$this->getLang()->sprintfDate( 'xiY', '123456789012345' ); +	} + +	/** +	 * Test too short timestamp +	 * @expectedException MWException +	 * @covers Language::sprintfDate +	 */ +	public function testSprintfDateNotAllDigitTimestamp() { +		$this->getLang()->sprintfDate( 'xiY', '-1234567890123' ); +	} + +	/**  	 * @dataProvider provideSprintfDateSamples +	 * @covers Language::sprintfDate  	 */ -	function testSprintfDate( $format, $ts, $expected, $msg ) { +	public function testSprintfDate( $format, $ts, $expected, $msg ) {  		$this->assertEquals(  			$expected, -			$this->lang->sprintfDate( $format, $ts ), +			$this->getLang()->sprintfDate( $format, $ts ),  			"sprintfDate('$format', '$ts'): $msg"  		);  	} +  	/** -	 * bug 33454. sprintfDate should always use UTC. +	 * sprintfDate should always use UTC when no zone is given.  	 * @dataProvider provideSprintfDateSamples +	 * @covers Language::sprintfDate  	 */ -	function testSprintfDateTZ( $format, $ts, $expected, $msg ) { +	public function testSprintfDateNoZone( $format, $ts, $expected, $ignore, $msg ) {  		$oldTZ = date_default_timezone_get();  		$res = date_default_timezone_set( 'Asia/Seoul' );  		if ( !$res ) { @@ -372,49 +569,73 @@ class LanguageTest extends MediaWikiTestCase {  		$this->assertEquals(  			$expected, -			$this->lang->sprintfDate( $format, $ts ), +			$this->getLang()->sprintfDate( $format, $ts ),  			"sprintfDate('$format', '$ts'): $msg"  		);  		date_default_timezone_set( $oldTZ );  	} -	function provideSprintfDateSamples() { +	/** +	 * sprintfDate should use passed timezone +	 * @dataProvider provideSprintfDateSamples +	 * @covers Language::sprintfDate +	 */ +	public function testSprintfDateTZ( $format, $ts, $ignore, $expected, $msg ) { +		$tz = new DateTimeZone( 'Asia/Seoul' ); +		if ( !$tz ) { +			$this->markTestSkipped( "Error getting Timezone" ); +		} + +		$this->assertEquals( +			$expected, +			$this->getLang()->sprintfDate( $format, $ts, $tz ), +			"sprintfDate('$format', '$ts', 'Asia/Seoul'): $msg" +		); +	} + +	public static function provideSprintfDateSamples() {  		return array(  			array(  				'xiY',  				'20111212000000',  				'1390', // note because we're testing English locale we get Latin-standard digits +				'1390',  				'Iranian calendar full year'  			),  			array(  				'xiy',  				'20111212000000',  				'90', +				'90',  				'Iranian calendar short year'  			),  			array(  				'o',  				'20120101235000',  				'2011', +				'2011',  				'ISO 8601 (week) year'  			),  			array(  				'W',  				'20120101235000',  				'52', +				'52',  				'Week number'  			),  			array(  				'W',  				'20120102235000',  				'1', +				'1',  				'Week number'  			),  			array(  				'o-\\WW-N',  				'20091231235000',  				'2009-W53-4', +				'2009-W53-4',  				'leap week'  			),  			// What follows is mostly copied from http://www.mediawiki.org/wiki/Help:Extension:ParserFunctions#.23time @@ -422,252 +643,336 @@ class LanguageTest extends MediaWikiTestCase {  				'Y',  				'20120102090705',  				'2012', +				'2012',  				'Full year'  			),  			array(  				'y',  				'20120102090705',  				'12', +				'12',  				'2 digit year'  			),  			array(  				'L',  				'20120102090705',  				'1', +				'1',  				'Leap year'  			),  			array(  				'n',  				'20120102090705',  				'1', +				'1',  				'Month index, not zero pad'  			),  			array(  				'N',  				'20120102090705',  				'01', +				'01',  				'Month index. Zero pad'  			),  			array(  				'M',  				'20120102090705',  				'Jan', +				'Jan',  				'Month abbrev'  			),  			array(  				'F',  				'20120102090705',  				'January', +				'January',  				'Full month'  			),  			array(  				'xg',  				'20120102090705',  				'January', +				'January',  				'Genitive month name (same in EN)'  			),  			array(  				'j',  				'20120102090705',  				'2', +				'2',  				'Day of month (not zero pad)'  			),  			array(  				'd',  				'20120102090705',  				'02', +				'02',  				'Day of month (zero-pad)'  			),  			array(  				'z',  				'20120102090705',  				'1', +				'1',  				'Day of year (zero-indexed)'  			),  			array(  				'D',  				'20120102090705',  				'Mon', +				'Mon',  				'Day of week (abbrev)'  			),  			array(  				'l',  				'20120102090705',  				'Monday', +				'Monday',  				'Full day of week'  			),  			array(  				'N',  				'20120101090705',  				'7', +				'7',  				'Day of week (Mon=1, Sun=7)'  			),  			array(  				'w',  				'20120101090705',  				'0', +				'0',  				'Day of week (Sun=0, Sat=6)'  			),  			array(  				'N',  				'20120102090705',  				'1', +				'1',  				'Day of week'  			),  			array(  				'a',  				'20120102090705',  				'am', +				'am',  				'am vs pm'  			),  			array(  				'A',  				'20120102120000',  				'PM', +				'PM',  				'AM vs PM'  			),  			array(  				'a',  				'20120102000000',  				'am', +				'am',  				'AM vs PM'  			),  			array(  				'g',  				'20120102090705',  				'9', +				'9',  				'12 hour, not Zero'  			),  			array(  				'h',  				'20120102090705',  				'09', +				'09',  				'12 hour, zero padded'  			),  			array(  				'G',  				'20120102090705',  				'9', +				'9',  				'24 hour, not zero'  			),  			array(  				'H',  				'20120102090705',  				'09', +				'09',  				'24 hour, zero'  			),  			array(  				'H',  				'20120102110705',  				'11', +				'11',  				'24 hour, zero'  			),  			array(  				'i',  				'20120102090705',  				'07', +				'07',  				'Minutes'  			),  			array(  				's',  				'20120102090705',  				'05', +				'05',  				'seconds'  			),  			array(  				'U',  				'20120102090705',  				'1325495225', +				'1325462825',  				'unix time'  			),  			array(  				't',  				'20120102090705',  				'31', +				'31',  				'Days in current month'  			),  			array(  				'c',  				'20120102090705',  				'2012-01-02T09:07:05+00:00', +				'2012-01-02T09:07:05+09:00',  				'ISO 8601 timestamp'  			),  			array(  				'r',  				'20120102090705',  				'Mon, 02 Jan 2012 09:07:05 +0000', +				'Mon, 02 Jan 2012 09:07:05 +0900',  				'RFC 5322'  			),  			array( +				'e', +				'20120102090705', +				'UTC', +				'Asia/Seoul', +				'Timezone identifier' +			), +			array( +				'I', +				'19880602090705', +				'0', +				'1', +				'DST indicator' +			), +			array( +				'O', +				'20120102090705', +				'+0000', +				'+0900', +				'Timezone offset' +			), +			array( +				'P', +				'20120102090705', +				'+00:00', +				'+09:00', +				'Timezone offset with colon' +			), +			array( +				'T', +				'20120102090705', +				'UTC', +				'KST', +				'Timezone abbreviation' +			), +			array( +				'Z', +				'20120102090705', +				'0', +				'32400', +				'Timezone offset in seconds' +			), +			array(  				'xmj xmF xmn xmY',  				'20120102090705',  				'7 Safar 2 1433', +				'7 Safar 2 1433',  				'Islamic'  			),  			array(  				'xij xiF xin xiY',  				'20120102090705',  				'12 Dey 10 1390', +				'12 Dey 10 1390',  				'Iranian'  			),  			array(  				'xjj xjF xjn xjY',  				'20120102090705',  				'7 Tevet 4 5772', +				'7 Tevet 4 5772',  				'Hebrew'  			),  			array(  				'xjt',  				'20120102090705',  				'29', +				'29',  				'Hebrew number of days in month'  			),  			array(  				'xjx',  				'20120102090705',  				'Tevet', +				'Tevet',  				'Hebrew genitive month name (No difference in EN)'  			),  			array(  				'xkY',  				'20120102090705',  				'2555', +				'2555',  				'Thai year'  			),  			array(  				'xoY',  				'20120102090705',  				'101', +				'101',  				'Minguo'  			),  			array(  				'xtY',  				'20120102090705',  				'平成24', +				'平成24',  				'nengo'  			),  			array(  				'xrxkYY',  				'20120102090705',  				'MMDLV2012', +				'MMDLV2012',  				'Roman numerals'  			),  			array(  				'xhxjYY',  				'20120102090705',  				'ה\'תשע"ב2012', +				'ה\'תשע"ב2012',  				'Hebrew numberals'  			),  			array(  				'xnY',  				'20120102090705',  				'2012', +				'2012',  				'Raw numerals (doesn\'t mean much in EN)'  			),  			array(  				'[[Y "(yea"\\r)]] \\"xx\\"',  				'20120102090705',  				'[[2012 (year)]] "x"', +				'[[2012 (year)]] "x"',  				'Various escaping'  			), @@ -676,16 +981,17 @@ class LanguageTest extends MediaWikiTestCase {  	/**  	 * @dataProvider provideFormatSizes +	 * @covers Language::formatSize  	 */ -	function testFormatSize( $size, $expected, $msg ) { +	public function testFormatSize( $size, $expected, $msg ) {  		$this->assertEquals(  			$expected, -			$this->lang->formatSize( $size ), +			$this->getLang()->formatSize( $size ),  			"formatSize('$size'): $msg"  		);  	} -	function provideFormatSizes() { +	public static function provideFormatSizes() {  		return array(  			array(  				0, @@ -738,16 +1044,17 @@ class LanguageTest extends MediaWikiTestCase {  	/**  	 * @dataProvider provideFormatBitrate +	 * @covers Language::formatBitrate  	 */ -	function testFormatBitrate( $bps, $expected, $msg ) { +	public function testFormatBitrate( $bps, $expected, $msg ) {  		$this->assertEquals(  			$expected, -			$this->lang->formatBitrate( $bps ), +			$this->getLang()->formatBitrate( $bps ),  			"formatBitrate('$bps'): $msg"  		);  	} -	function provideFormatBitrate() { +	public static function provideFormatBitrate() {  		return array(  			array(  				0, @@ -808,19 +1115,19 @@ class LanguageTest extends MediaWikiTestCase {  	} -  	/**  	 * @dataProvider provideFormatDuration +	 * @covers Language::formatDuration  	 */ -	function testFormatDuration( $duration, $expected, $intervals = array() ) { +	public function testFormatDuration( $duration, $expected, $intervals = array() ) {  		$this->assertEquals(  			$expected, -			$this->lang->formatDuration( $duration, $intervals ), +			$this->getLang()->formatDuration( $duration, $intervals ),  			"formatDuration('$duration'): $expected"  		);  	} -	function provideFormatDuration() { +	public static function provideFormatDuration() {  		return array(  			array(  				0, @@ -859,35 +1166,36 @@ class LanguageTest extends MediaWikiTestCase {  				'2 days',  			),  			array( -				365.25 * 86400, // 365.25 * 86400 = 31557600 +				// ( 365 + ( 24 * 3 + 25 ) / 400 ) * 86400 = 31556952 +				( 365 + ( 24 * 3 + 25 ) / 400.0 ) * 86400,  				'1 year',  			),  			array( -				2 * 31557600, +				2 * 31556952,  				'2 years',  			),  			array( -				10 * 31557600, +				10 * 31556952,  				'1 decade',  			),  			array( -				20 * 31557600, +				20 * 31556952,  				'2 decades',  			),  			array( -				100 * 31557600, +				100 * 31556952,  				'1 century',  			),  			array( -				200 * 31557600, +				200 * 31556952,  				'2 centuries',  			),  			array( -				1000 * 31557600, +				1000 * 31556952,  				'1 millennium',  			),  			array( -				2000 * 31557600, +				2000 * 31556952,  				'2 millennia',  			),  			array( @@ -899,11 +1207,11 @@ class LanguageTest extends MediaWikiTestCase {  				'1 hour and 1 second'  			),  			array( -				31557600 + 2 * 86400 + 9000, +				31556952 + 2 * 86400 + 9000,  				'1 year, 2 days, 2 hours and 30 minutes'  			),  			array( -				42 * 1000 * 31557600 + 42, +				42 * 1000 * 31556952 + 42,  				'42 millennia and 42 seconds'  			),  			array( @@ -922,7 +1230,7 @@ class LanguageTest extends MediaWikiTestCase {  				array( 'seconds' ),  			),  			array( -				31557600 + 2 * 86400 + 9000, +				31556952 + 2 * 86400 + 9000,  				'1 year, 2 days and 150 minutes',  				array( 'years', 'days', 'minutes' ),  			), @@ -932,7 +1240,7 @@ class LanguageTest extends MediaWikiTestCase {  				array( 'years', 'days' ),  			),  			array( -				31557600 + 2 * 86400 + 9000, +				31556952 + 2 * 86400 + 9000,  				'1 year, 2 days and 150 minutes',  				array( 'minutes', 'days', 'years' ),  			), @@ -946,17 +1254,18 @@ class LanguageTest extends MediaWikiTestCase {  	/**  	 * @dataProvider provideCheckTitleEncodingData +	 * @covers Language::checkTitleEncoding  	 */ -	function testCheckTitleEncoding( $s ) { +	public function testCheckTitleEncoding( $s ) {  		$this->assertEquals(  			$s, -			$this->lang->checkTitleEncoding($s), +			$this->getLang()->checkTitleEncoding( $s ),  			"checkTitleEncoding('$s')"  		);  	} -	function provideCheckTitleEncodingData() { -		return array ( +	public static function provideCheckTitleEncodingData() { +		return array(  			array( "" ),  			array( "United States of America" ), // 7bit ASCII  			array( rawurldecode( "S%C3%A9rie%20t%C3%A9l%C3%A9vis%C3%A9e" ) ), @@ -1010,8 +1319,9 @@ class LanguageTest extends MediaWikiTestCase {  	/**  	 * @dataProvider provideRomanNumeralsData +	 * @covers Language::romanNumeral  	 */ -	function testRomanNumerals( $num, $numerals ) { +	public function testRomanNumerals( $num, $numerals ) {  		$this->assertEquals(  			$numerals,  			Language::romanNumeral( $num ), @@ -1019,7 +1329,7 @@ class LanguageTest extends MediaWikiTestCase {  		);  	} -	function provideRomanNumeralsData() { +	public static function provideRomanNumeralsData() {  		return array(  			array( 1, 'I' ),  			array( 2, 'II' ), @@ -1061,9 +1371,197 @@ class LanguageTest extends MediaWikiTestCase {  			array( 7000, 'MMMMMMM' ),  			array( 8000, 'MMMMMMMM' ),  			array( 9000, 'MMMMMMMMM' ), -			array( 9999, 'MMMMMMMMMCMXCIX'), +			array( 9999, 'MMMMMMMMMCMXCIX' ),  			array( 10000, 'MMMMMMMMMM' ),  		);  	} -} +	/** +	 * @dataProvider providePluralData +	 * @covers Language::convertPlural +	 */ +	public function testConvertPlural( $expected, $number, $forms ) { +		$chosen = $this->getLang()->convertPlural( $number, $forms ); +		$this->assertEquals( $expected, $chosen ); +	} + +	public static function providePluralData() { +		// Params are: [expected text, number given, [the plural forms]] +		return array( +			array( 'plural', 0, array( +				'singular', 'plural' +			) ), +			array( 'explicit zero', 0, array( +				'0=explicit zero', 'singular', 'plural' +			) ), +			array( 'explicit one', 1, array( +				'singular', 'plural', '1=explicit one', +			) ), +			array( 'singular', 1, array( +				'singular', 'plural', '0=explicit zero', +			) ), +			array( 'plural', 3, array( +				'0=explicit zero', '1=explicit one', 'singular', 'plural' +			) ), +			array( 'explicit eleven', 11, array( +				'singular', 'plural', '11=explicit eleven', +			) ), +			array( 'plural', 12, array( +				'singular', 'plural', '11=explicit twelve', +			) ), +			array( 'plural', 12, array( +				'singular', 'plural', '=explicit form', +			) ), +			array( 'other', 2, array( +				'kissa=kala', '1=2=3', 'other', +			) ), +			array( '', 2, array( +				'0=explicit zero', '1=explicit one', +			) ), +		); +	} + +	/** +	 * @covers Language::translateBlockExpiry() +	 * @dataProvider provideTranslateBlockExpiry +	 */ +	public function testTranslateBlockExpiry( $expectedData, $str, $desc ) { +		$lang = $this->getLang(); +		if ( is_array( $expectedData ) ) { +			list( $func, $arg ) = $expectedData; +			$expected = $lang->$func( $arg ); +		} else { +			$expected = $expectedData; +		} +		$this->assertEquals( $expected, $lang->translateBlockExpiry( $str ), $desc ); +	} + +	public static function provideTranslateBlockExpiry() { +		return array( +			array( '2 hours', '2 hours', 'simple data from ipboptions' ), +			array( 'indefinite', 'infinite', 'infinite from ipboptions' ), +			array( 'indefinite', 'infinity', 'alternative infinite from ipboptions' ), +			array( 'indefinite', 'indefinite', 'another alternative infinite from ipboptions' ), +			array( array( 'formatDuration', 1023 * 60 * 60 ), '1023 hours', 'relative' ), +			array( array( 'formatDuration', -1023 ), '-1023 seconds', 'negative relative' ), +			array( array( 'formatDuration', 0 ), 'now', 'now' ), +			array( array( 'timeanddate', '20120102070000' ), '2012-1-1 7:00 +1 day', 'mixed, handled as absolute' ), +			array( array( 'timeanddate', '19910203040506' ), '1991-2-3 4:05:06', 'absolute' ), +			array( array( 'timeanddate', '19700101000000' ), '1970-1-1 0:00:00', 'absolute at epoch' ), +			array( array( 'timeanddate', '19691231235959' ), '1969-12-31 23:59:59', 'time before epoch' ), +			array( 'dummy', 'dummy', 'return garbage as is' ), +		); +	} + +	/** +	 * @covers Language::commafy() +	 * @dataProvider provideCommafyData +	 */ +	public function testCommafy( $number, $numbersWithCommas ) { +		$this->assertEquals( +			$numbersWithCommas, +			$this->getLang()->commafy( $number ), +			"commafy('$number')" +		); +	} + +	public static function provideCommafyData() { +		return array( +			array( 1, '1' ), +			array( 10, '10' ), +			array( 100, '100' ), +			array( 1000, '1,000' ), +			array( 10000, '10,000' ), +			array( 100000, '100,000' ), +			array( 1000000, '1,000,000' ), +			array( 1.0001, '1.0001' ), +			array( 10.0001, '10.0001' ), +			array( 100.0001, '100.0001' ), +			array( 1000.0001, '1,000.0001' ), +			array( 10000.0001, '10,000.0001' ), +			array( 100000.0001, '100,000.0001' ), +			array( 1000000.0001, '1,000,000.0001' ), +		); +	} + +	/** +	 * @covers Language::listToText +	 */ +	public function testListToText() { +		$lang = $this->getLang(); +		$and = $lang->getMessageFromDB( 'and' ); +		$s = $lang->getMessageFromDB( 'word-separator' ); +		$c = $lang->getMessageFromDB( 'comma-separator' ); + +		$this->assertEquals( '', $lang->listToText( array() ) ); +		$this->assertEquals( 'a', $lang->listToText( array( 'a' ) ) ); +		$this->assertEquals( "a{$and}{$s}b", $lang->listToText( array( 'a', 'b' ) ) ); +		$this->assertEquals( "a{$c}b{$and}{$s}c", $lang->listToText( array( 'a', 'b', 'c' ) ) ); +		$this->assertEquals( "a{$c}b{$c}c{$and}{$s}d", $lang->listToText( array( 'a', 'b', 'c', 'd' ) ) ); +	} + +	/** +	 * @dataProvider provideIsSupportedLanguage +	 * @covers Language::isSupportedLanguage +	 */ +	public function testIsSupportedLanguage( $code, $expected, $comment ) { +		$this->assertEquals( $expected, Language::isSupportedLanguage( $code ), $comment ); +	} + +	public static function provideIsSupportedLanguage() { +		return array( +			array( 'en', true, 'is supported language' ), +			array( 'fi', true, 'is supported language' ), +			array( 'bunny', false, 'is not supported language' ), +			array( 'FI', false, 'is not supported language, input should be in lower case' ), +		); +	} + +	/** +	 * @dataProvider provideGetParentLanguage +	 * @covers Language::getParentLanguage +	 */ +	public function testGetParentLanguage( $code, $expected, $comment ) { +		$lang = Language::factory( $code ); +		if ( is_null( $expected ) ) { +			$this->assertNull( $lang->getParentLanguage(), $comment ); +		} else { +			$this->assertEquals( $expected, $lang->getParentLanguage()->getCode(), $comment ); +		} +	} + +	public static function provideGetParentLanguage() { +		return array( +			array( 'zh-cn', 'zh', 'zh is the parent language of zh-cn' ), +			array( 'zh', 'zh', 'zh is defined as the parent language of zh, because zh converter can convert zh-cn to zh' ), +			array( 'zh-invalid', null, 'do not be fooled by arbitrarily composed language codes' ), +			array( 'en-gb', null, 'en does not have converter' ), +			array( 'en', null, 'en does not have converter. Although FakeConverter handles en -> en conversion but it is useless' ), +		); +	} + +	/** +	 * @dataProvider provideGetNamespaceAliases +	 * @covers Language::getNamespaceAliases +	 */ +	public function testGetNamespaceAliases( $languageCode, $subset ) { +		$language = Language::factory( $languageCode ); +		$aliases = $language->getNamespaceAliases(); +		foreach ( $subset as $alias => $nsId ) { +			$this->assertEquals( $nsId, $aliases[$alias] ); +		} +	} + +	public static function provideGetNamespaceAliases() { +		// TODO: Add tests for NS_PROJECT_TALK and GenderNamespaces +		return array( +			array( +				'zh', +				array( +					'文件' => NS_FILE, +					'檔案' => NS_FILE, +				), +			), +		); +	} +} | 
