New tests for LanguageConverter->getPreferredVariant()
Refactor getPreferredVariant, new function getHeaderVariant() New function (FauxRequest::setHeader()) to help with testing.
This commit is contained in:
parent
9ef63ede49
commit
dcdc0f4dc7
5 changed files with 242 additions and 79 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,29 +143,6 @@ class LanguageConverter {
|
|||
global $wgUser, $wgRequest, $wgVariantArticlePath,
|
||||
$wgDefaultLanguageVariant, $wgOut;
|
||||
|
||||
// bug 21974, don't return $this->mPreferredVariant if $fromUser = false
|
||||
if ( $fromUser && $this->mPreferredVariant ) {
|
||||
return $this->mPreferredVariant;
|
||||
}
|
||||
|
||||
// figure out user lang without constructing wgLang to avoid
|
||||
// infinite recursion
|
||||
if ( $fromUser ) {
|
||||
$defaultUserLang = $wgUser->getOption( 'language' );
|
||||
} 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 ) ) {
|
||||
|
|
@ -172,11 +150,38 @@ class LanguageConverter {
|
|||
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' );
|
||||
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;
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
121
tests/LanguageConverterTest.php
Normal file
121
tests/LanguageConverterTest.php
Normal file
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
|
|
|
|||
Loading…
Reference in a new issue