New tests for LanguageConverter->getPreferredVariant()
authorMark A. Hershberger <mah@users.mediawiki.org>
Wed, 6 Jan 2010 03:50:59 +0000 (03:50 +0000)
committerMark A. Hershberger <mah@users.mediawiki.org>
Wed, 6 Jan 2010 03:50:59 +0000 (03:50 +0000)
Refactor getPreferredVariant, new function getHeaderVariant()
New function (FauxRequest::setHeader()) to help with testing.

includes/WebRequest.php
languages/LanguageConverter.php
tests/ArticleTest.php
tests/LanguageConverterTest.php [new file with mode: 0644]
tests/bootstrap.php

index 15126a3..8b68434 100644 (file)
@@ -762,6 +762,10 @@ class FauxRequest extends WebRequest {
                return isset( $this->headers[$name] ) ? $this->headers[$name] : false;
        }
 
+       public function setHeader( $name, $val ) {
+               $this->headers[$name] = $val;
+       }
+
        public function getSessionData( $key ) {
                if( !isset( $this->session[$key] ) )
                        return null;
index 6b54d99..ad66789 100644 (file)
@@ -16,7 +16,7 @@
  * @maintainers fdcn <fdcn64@gmail.com>, shinjiman <shinjiman@gmail.com>, PhiLiP <philip.npc@gmail.com>
  */
 class LanguageConverter {
-       var $mPreferredVariant = '';
+       var $mPreferredVariant = ''; // The User's preferred variant
        var $mMainLanguageCode;
        var $mVariants, $mVariantFallbacks, $mVariantNames;
        var $mTablesLoaded = false;
@@ -34,6 +34,7 @@ class LanguageConverter {
        var $mUcfirst = false;
        var $mTitleOriginal = '';
        var $mTitleDisplay = '';
+       var $mHeaderVariant = null;
 
        const CACHE_VERSION_KEY = 'VERSION 6';
 
@@ -142,41 +143,45 @@ class LanguageConverter {
                global $wgUser, $wgRequest, $wgVariantArticlePath,
                        $wgDefaultLanguageVariant, $wgOut;
 
-               // bug 21974, don't return $this->mPreferredVariant if $fromUser = false
-               if ( $fromUser && $this->mPreferredVariant ) {
+               // see if the preference is set in the request
+               $req = $wgRequest->getText( 'variant' );
+               if ( in_array( $req, $this->mVariants ) ) {
+                       $this->mPreferredVariant = $req;
                        return $this->mPreferredVariant;
                }
 
-               // figure out user lang without constructing wgLang to avoid
-        // infinite recursion
-               if ( $fromUser ) {
+        if ( $fromUser ) {
+                       // bug 21974, don't return $this->mPreferredVariant if
+                       // $fromUser = false
+                       if ( $this->mPreferredVariant ) {
+                               return $this->mPreferredVariant;
+                       }
+
+            // figure out user lang without constructing wgLang to avoid
+                       // infinite recursion
                        $defaultUserLang = $wgUser->getOption( 'language' );
+
+                       // get language variant preference from logged in users
+                       // Don't call this on stub objects because that causes infinite
+                       // recursion during initialisation
+                       if ( $wgUser->isLoggedIn() )  {
+                               $this->mPreferredVariant = $wgUser->getOption( 'variant' );
+                       }
+
                } else {
                        $defaultUserLang = $this->mMainLanguageCode;
                }
-
                $userLang = $wgRequest->getVal( 'uselang', $defaultUserLang );
+
                // see if interface language is same as content, if not, prevent
                // conversion
-
                if ( ! in_array( $userLang, $this->mVariants ) ) {
                        // no conversion
                        $this->mPreferredVariant = $this->mMainLanguageCode;
                        return $this->mPreferredVariant;
-               }
-
-               // see if the preference is set in the request
-               $req = $wgRequest->getText( 'variant' );
-               if ( in_array( $req, $this->mVariants ) ) {
-                       $this->mPreferredVariant = $req;
-                       return $this->mPreferredVariant;
-               }
-
-               // get language variant preference from logged in users
-               // Don't call this on stub objects because that causes infinite
-               // recursion during initialisation
-               if ( $fromUser && $wgUser->isLoggedIn() )  {
-                       $this->mPreferredVariant = $wgUser->getOption( 'variant' );
+               } elseif ( $this->mPreferredVariant ) {
+                       // if the variant was set above and it iss a variant of
+                       // the content language
                        return $this->mPreferredVariant;
                }
 
@@ -187,60 +192,81 @@ class LanguageConverter {
                        return $this->mPreferredVariant;
                }
 
-               if ( !$this->mPreferredVariant ) {
-                       // see if some supported language variant is set in the
-                       // http header, but we don't set the mPreferredVariant
-                       // variable in case this is called before the user's
-                       // preference is loaded
+               $headerVariant = $this->getHeaderVariant();
+               if ( $fromHeader && $headerVariant ) {
+                       return $headerVariant;
+               }
 
-                       $acceptLanguage = $wgRequest->getHeader( 'Accept-Language' );
-                       if ( $fromHeader && $acceptLanguage ) {
-                               // explode by comma
-                               $result = explode( ',', strtolower( $acceptLanguage ) );
+               return $this->mMainLanguageCode;
+       }
 
-                               $languages = array();
+       /**
+        * Determine the language variant from the Accept-Language header.
+        *
+        * @returns mixed variant if one found, false otherwise.
+        */
+       function getHeaderVariant() {
+               global $wgRequest;
 
-                               foreach ( $result as $elem ) {
-                                       // if $elem likes 'zh-cn;q=0.9'
-                                       if ( ( $posi = strpos( $elem, ';' ) ) !== false ) {
-                                               // get the real language code likes 'zh-cn'
-                                               $languages[] = substr( $elem, 0, $posi );
-                                       } else {
-                                               $languages[] = $elem;
-                                       }
-                               }
+               if ( $this->mHeaderVariant ) {
+                       return $this->mHeaderVariant;
+               }
 
-                               $fallback_languages = array();
-                               foreach ( $languages as $language ) {
-                                       // strip whitespace
-                                       $language = trim( $language );
-                                       if ( in_array( $language, $this->mVariants ) ) {
-                                               return $language;
-                                       } else {
-                                               // To see if there are fallbacks of current language.
-                                               // We record these fallback variants, and process
-                                               // them later.
-                                               $fallbacks = $this->getVariantFallbacks( $language );
-                                               if ( is_string( $fallbacks ) ) {
-                                                       $fallback_languages[] = $fallbacks;
-                                               } elseif ( is_array( $fallbacks ) ) {
-                                                       $fallback_languages =
-                                                               array_merge( $fallback_languages,
-                                                                                        $fallbacks );
-                                               }
-                                       }
-                               }
+               // see if some supported language variant is set in the
+               // http header, but we don't set the mPreferredVariant
+               // variable in case this is called before the user's
+               // preference is loaded
 
-                               // process fallback languages now
-                               $fallback_languages = array_unique( $fallback_languages );
-                               foreach ( $fallback_languages as $language ) {
-                                       if ( in_array( $language, $this->mVariants ) ) {
-                                               return $language;
-                                       }
+               $acceptLanguage = $wgRequest->getHeader( 'Accept-Language' );
+               if ( !$acceptLanguage ) {
+                       return false;
+               }
+
+               // explode by comma
+               $result = explode( ',', strtolower( $acceptLanguage ) );
+
+               $languages = array();
+
+               foreach ( $result as $elem ) {
+                       // if $elem likes 'zh-cn;q=0.9'
+                       if ( ( $posi = strpos( $elem, ';' ) ) !== false ) {
+                               // get the real language code likes 'zh-cn'
+                               $languages[] = substr( $elem, 0, $posi );
+                       } else {
+                               $languages[] = $elem;
+                       }
+               }
+
+               $fallback_languages = array();
+               foreach ( $languages as $language ) {
+                       // strip whitespace
+                       $language = trim( $language );
+                       if ( in_array( $language, $this->mVariants ) ) {
+                               $this->mHeaderVariant = $language;
+                               return $language;
+                       } else {
+                               // To see if there are fallbacks of current language.
+                               // We record these fallback variants, and process
+                               // them later.
+                               $fallbacks = $this->getVariantFallbacks( $language );
+                               if ( is_string( $fallbacks ) ) {
+                                       $fallback_languages[] = $fallbacks;
+                               } elseif ( is_array( $fallbacks ) ) {
+                                       $fallback_languages =
+                                               array_merge( $fallback_languages,
+                                                                        $fallbacks );
                                }
                        }
                }
-               return $this->mMainLanguageCode;
+
+               // process fallback languages now
+               $fallback_languages = array_unique( $fallback_languages );
+               foreach ( $fallback_languages as $language ) {
+                       if ( in_array( $language, $this->mVariants ) ) {
+                               $this->mHeaderVariant = $language;
+                               return $language;
+                       }
+               }
        }
 
        /**
index f36b026..9025b74 100644 (file)
@@ -4,6 +4,8 @@ class ArticleTest extends PHPUnit_Framework_TestCase {
        var $saveGlobals = array();
 
        function setUp() {
+               global $wgContLang;
+               $wgContLang = Language::factory( 'en' );
                $globalSet = array(
                        'wgLegacyEncoding' => false,
                        'wgCompressRevisions' => false,
diff --git a/tests/LanguageConverterTest.php b/tests/LanguageConverterTest.php
new file mode 100644 (file)
index 0000000..bdf43a6
--- /dev/null
@@ -0,0 +1,121 @@
+<?php
+
+class LanguageConverterTest extends PHPUnit_Framework_TestCase {
+       protected $lang = null;
+       protected  $lc = null;
+
+       function setUp() {
+               $this->lang = new LanguageTest();
+               $this->lc = new TestConverter( $this->lang, 'tg',
+                                                                          array( 'tg', 'tg-latn' ) );
+       }
+
+       function tearDown() {
+               unset($this->lc);
+               unset($this->lang);
+       }
+
+       function testGetPreferredVariant() {
+               global $wgRequest, $wgUsePathInfo, $wgLanguageCode,
+                       $wgVariantArticlePath, $wgUser, $wgContLang,
+                       $wgDefaultLanguageVariant;
+
+               $wgRequest = new FauxRequest(array());
+               $wgUser    = new User;
+               $wgContLang = Language::factory( 'tg-latn' );
+
+               $this->assertEquals('tg', $this->lc->getPreferredVariant(false, false));
+               $this->assertEquals('tg', $this->lc->getPreferredVariant(false, true));
+               $this->assertEquals('tg', $this->lc->getPreferredVariant(true, false));
+               $this->assertEquals('tg', $this->lc->getPreferredVariant(true, true));
+
+               $wgRequest->setHeader('Accept-Language', 'tg-latn');
+               $this->lc = new TestConverter( $this->lang, 'tg',
+                                                                          array( 'tg', 'tg-latn' ) );
+               $this->assertEquals('tg', $this->lc->getPreferredVariant(false, false));
+               $this->assertEquals('tg-latn', $this->lc->getPreferredVariant(false, true));
+               $this->assertEquals('tg', $this->lc->getPreferredVariant(true, false));
+               $this->assertEquals('tg-latn', $this->lc->getPreferredVariant(true, true));
+
+               $wgRequest->setHeader('Accept-Language', 'tg;q=1');
+               $this->lc = new TestConverter( $this->lang, 'tg',
+                                                                          array( 'tg', 'tg-latn' ) );
+               $this->assertEquals('tg', $this->lc->getPreferredVariant(false, false));
+               $this->assertEquals('tg', $this->lc->getPreferredVariant(false, true));
+               $this->assertEquals('tg', $this->lc->getPreferredVariant(true, false));
+               $this->assertEquals('tg', $this->lc->getPreferredVariant(true, true));
+
+               $wgRequest->setHeader('Accept-Language', 'tg-latn;q=1');
+               $this->lc = new TestConverter( $this->lang, 'tg',
+                                                                          array( 'tg', 'tg-latn' ) );
+               $this->assertEquals('tg', $this->lc->getPreferredVariant(false, false));
+               $this->assertEquals('tg-latn', $this->lc->getPreferredVariant(false, true));
+               $this->assertEquals('tg', $this->lc->getPreferredVariant(true, false));
+               $this->assertEquals('tg-latn', $this->lc->getPreferredVariant(true, true));
+
+               $wgRequest->setHeader('Accept-Language', 'en, tg-latn;q=1');
+               $this->lc = new TestConverter( $this->lang, 'tg',
+                                                                          array( 'tg', 'tg-latn' ) );
+               $this->assertEquals('tg', $this->lc->getPreferredVariant(false, false));
+               $this->assertEquals('tg-latn', $this->lc->getPreferredVariant(false, true));
+               $this->assertEquals('tg', $this->lc->getPreferredVariant(true, false));
+               $this->assertEquals('tg-latn', $this->lc->getPreferredVariant(true, true));
+               $wgRequest->setHeader('Accept-Language', '');
+
+               $wgUser = User::newFromId("admin");
+               $wgContLang = Language::factory( 'tg-latn' );
+               $wgUser->setId(1);
+               $wgUser->setOption('variant', 'tg-latn');
+               $this->lc = new TestConverter( $this->lang, 'tg',
+                                                                          array( 'tg', 'tg-latn' ) );
+
+               $this->assertEquals('tg', $this->lc->getPreferredVariant(false, false));
+               $this->assertEquals('tg', $this->lc->getPreferredVariant(false, true));
+               $this->assertEquals('tg-latn', $this->lc->getPreferredVariant(true,  false));
+               $this->assertEquals('tg-latn', $this->lc->getPreferredVariant(true,  true));
+
+               $wgRequest->setVal('variant', 'tg');
+               $this->lc = new TestConverter( $this->lang, 'tg',
+                                                                          array( 'tg', 'tg-latn' ) );
+               $this->assertEquals('tg', $this->lc->getPreferredVariant(true,  false));
+               $this->assertEquals('tg', $this->lc->getPreferredVariant(true,  true));
+
+               $wgRequest->setVal('variant', null);
+               $wgDefaultLanguageVariant = 'tg-latn';
+               $this->lc = new TestConverter( $this->lang, 'tg',
+                                                                          array( 'tg', 'tg-latn' ) );
+               $this->assertEquals('tg-latn', $this->lc->getPreferredVariant(false, false));
+               $this->assertEquals('tg-latn', $this->lc->getPreferredVariant(false, true));
+               $this->assertEquals('tg-latn', $this->lc->getPreferredVariant(true, false));
+               $this->assertEquals('tg-latn', $this->lc->getPreferredVariant(true, true));
+
+
+       }
+}
+
+/**
+ * Test converter (from Tajiki to latin orthography)
+ */
+class TestConverter extends LanguageConverter {
+       private $table = array(
+               'б' => 'b',
+               'в' => 'v',
+               'г' => 'g',
+       );
+
+       function loadDefaultTables() {
+               $this->mTables = array(
+                       'tg-latn' => new ReplacementArray( $this->table ),
+                       'tg'      => new ReplacementArray()
+               );
+       }
+
+}
+
+class LanguageTest extends Language {
+       function __construct() {
+               parent::__construct();
+               $variants = array( 'tg', 'tg-latn' );
+               $this->mConverter = new TestConverter( $this, 'tg', $variants );
+       }
+}
index 234d01c..c879d03 100644 (file)
@@ -1,8 +1,18 @@
 <?php
 
-$IP = realpath(dirname( __FILE__ ) . '/..');
+global $wgCommandLineMode, $IP, $wgMemc;
+$wgCommandLineMode = true;
 define('MEDIAWIKI', 1);
-global $optionsWithArgs;
-$optionsWithArgs = array();
 
-require_once( '../maintenance/commandLine.inc' );
+require dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR."LocalSettings.php";
+
+require "Defines.php";
+require "ProfilerStub.php";
+require 'GlobalFunctions.php';
+require 'Hooks.php';
+require "AutoLoader.php";
+require 'ProxyTools.php';
+require 'ObjectCache.php';
+require 'ImageFunctions.php';
+
+$wgMemc =& wfGetMainCache();