r60709 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r60708‎ | r60709 | r60710 >
Date:03:50, 6 January 2010
Author:mah
Status:ok
Tags:
Comment:
New tests for LanguageConverter->getPreferredVariant()
Refactor getPreferredVariant, new function getHeaderVariant()
New function (FauxRequest::setHeader()) to help with testing.
Modified paths:
  • /trunk/phase3/includes/WebRequest.php (modified) (history)
  • /trunk/phase3/languages/LanguageConverter.php (modified) (history)
  • /trunk/phase3/tests/ArticleTest.php (modified) (history)
  • /trunk/phase3/tests/LanguageConverterTest.php (added) (history)
  • /trunk/phase3/tests/bootstrap.php (modified) (history)

Diff [purge]

Index: trunk/phase3/tests/LanguageConverterTest.php
@@ -0,0 +1,121 @@
 2+<?php
 3+
 4+class LanguageConverterTest extends PHPUnit_Framework_TestCase {
 5+ protected $lang = null;
 6+ protected $lc = null;
 7+
 8+ function setUp() {
 9+ $this->lang = new LanguageTest();
 10+ $this->lc = new TestConverter( $this->lang, 'tg',
 11+ array( 'tg', 'tg-latn' ) );
 12+ }
 13+
 14+ function tearDown() {
 15+ unset($this->lc);
 16+ unset($this->lang);
 17+ }
 18+
 19+ function testGetPreferredVariant() {
 20+ global $wgRequest, $wgUsePathInfo, $wgLanguageCode,
 21+ $wgVariantArticlePath, $wgUser, $wgContLang,
 22+ $wgDefaultLanguageVariant;
 23+
 24+ $wgRequest = new FauxRequest(array());
 25+ $wgUser = new User;
 26+ $wgContLang = Language::factory( 'tg-latn' );
 27+
 28+ $this->assertEquals('tg', $this->lc->getPreferredVariant(false, false));
 29+ $this->assertEquals('tg', $this->lc->getPreferredVariant(false, true));
 30+ $this->assertEquals('tg', $this->lc->getPreferredVariant(true, false));
 31+ $this->assertEquals('tg', $this->lc->getPreferredVariant(true, true));
 32+
 33+ $wgRequest->setHeader('Accept-Language', 'tg-latn');
 34+ $this->lc = new TestConverter( $this->lang, 'tg',
 35+ array( 'tg', 'tg-latn' ) );
 36+ $this->assertEquals('tg', $this->lc->getPreferredVariant(false, false));
 37+ $this->assertEquals('tg-latn', $this->lc->getPreferredVariant(false, true));
 38+ $this->assertEquals('tg', $this->lc->getPreferredVariant(true, false));
 39+ $this->assertEquals('tg-latn', $this->lc->getPreferredVariant(true, true));
 40+
 41+ $wgRequest->setHeader('Accept-Language', 'tg;q=1');
 42+ $this->lc = new TestConverter( $this->lang, 'tg',
 43+ array( 'tg', 'tg-latn' ) );
 44+ $this->assertEquals('tg', $this->lc->getPreferredVariant(false, false));
 45+ $this->assertEquals('tg', $this->lc->getPreferredVariant(false, true));
 46+ $this->assertEquals('tg', $this->lc->getPreferredVariant(true, false));
 47+ $this->assertEquals('tg', $this->lc->getPreferredVariant(true, true));
 48+
 49+ $wgRequest->setHeader('Accept-Language', 'tg-latn;q=1');
 50+ $this->lc = new TestConverter( $this->lang, 'tg',
 51+ array( 'tg', 'tg-latn' ) );
 52+ $this->assertEquals('tg', $this->lc->getPreferredVariant(false, false));
 53+ $this->assertEquals('tg-latn', $this->lc->getPreferredVariant(false, true));
 54+ $this->assertEquals('tg', $this->lc->getPreferredVariant(true, false));
 55+ $this->assertEquals('tg-latn', $this->lc->getPreferredVariant(true, true));
 56+
 57+ $wgRequest->setHeader('Accept-Language', 'en, tg-latn;q=1');
 58+ $this->lc = new TestConverter( $this->lang, 'tg',
 59+ array( 'tg', 'tg-latn' ) );
 60+ $this->assertEquals('tg', $this->lc->getPreferredVariant(false, false));
 61+ $this->assertEquals('tg-latn', $this->lc->getPreferredVariant(false, true));
 62+ $this->assertEquals('tg', $this->lc->getPreferredVariant(true, false));
 63+ $this->assertEquals('tg-latn', $this->lc->getPreferredVariant(true, true));
 64+ $wgRequest->setHeader('Accept-Language', '');
 65+
 66+ $wgUser = User::newFromId("admin");
 67+ $wgContLang = Language::factory( 'tg-latn' );
 68+ $wgUser->setId(1);
 69+ $wgUser->setOption('variant', 'tg-latn');
 70+ $this->lc = new TestConverter( $this->lang, 'tg',
 71+ array( 'tg', 'tg-latn' ) );
 72+
 73+ $this->assertEquals('tg', $this->lc->getPreferredVariant(false, false));
 74+ $this->assertEquals('tg', $this->lc->getPreferredVariant(false, true));
 75+ $this->assertEquals('tg-latn', $this->lc->getPreferredVariant(true, false));
 76+ $this->assertEquals('tg-latn', $this->lc->getPreferredVariant(true, true));
 77+
 78+ $wgRequest->setVal('variant', 'tg');
 79+ $this->lc = new TestConverter( $this->lang, 'tg',
 80+ array( 'tg', 'tg-latn' ) );
 81+ $this->assertEquals('tg', $this->lc->getPreferredVariant(true, false));
 82+ $this->assertEquals('tg', $this->lc->getPreferredVariant(true, true));
 83+
 84+ $wgRequest->setVal('variant', null);
 85+ $wgDefaultLanguageVariant = 'tg-latn';
 86+ $this->lc = new TestConverter( $this->lang, 'tg',
 87+ array( 'tg', 'tg-latn' ) );
 88+ $this->assertEquals('tg-latn', $this->lc->getPreferredVariant(false, false));
 89+ $this->assertEquals('tg-latn', $this->lc->getPreferredVariant(false, true));
 90+ $this->assertEquals('tg-latn', $this->lc->getPreferredVariant(true, false));
 91+ $this->assertEquals('tg-latn', $this->lc->getPreferredVariant(true, true));
 92+
 93+
 94+ }
 95+}
 96+
 97+/**
 98+ * Test converter (from Tajiki to latin orthography)
 99+ */
 100+class TestConverter extends LanguageConverter {
 101+ private $table = array(
 102+ 'б' => 'b',
 103+ 'в' => 'v',
 104+ 'г' => 'g',
 105+ );
 106+
 107+ function loadDefaultTables() {
 108+ $this->mTables = array(
 109+ 'tg-latn' => new ReplacementArray( $this->table ),
 110+ 'tg' => new ReplacementArray()
 111+ );
 112+ }
 113+
 114+}
 115+
 116+class LanguageTest extends Language {
 117+ function __construct() {
 118+ parent::__construct();
 119+ $variants = array( 'tg', 'tg-latn' );
 120+ $this->mConverter = new TestConverter( $this, 'tg', $variants );
 121+ }
 122+}
Property changes on: trunk/phase3/tests/LanguageConverterTest.php
___________________________________________________________________
Name: svn:eol-syle
1123 + native
Index: trunk/phase3/tests/bootstrap.php
@@ -1,8 +1,18 @@
22 <?php
33
4 -$IP = realpath(dirname( __FILE__ ) . '/..');
 4+global $wgCommandLineMode, $IP, $wgMemc;
 5+$wgCommandLineMode = true;
56 define('MEDIAWIKI', 1);
6 -global $optionsWithArgs;
7 -$optionsWithArgs = array();
87
9 -require_once( '../maintenance/commandLine.inc' );
 8+require dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR."LocalSettings.php";
 9+
 10+require "Defines.php";
 11+require "ProfilerStub.php";
 12+require 'GlobalFunctions.php';
 13+require 'Hooks.php';
 14+require "AutoLoader.php";
 15+require 'ProxyTools.php';
 16+require 'ObjectCache.php';
 17+require 'ImageFunctions.php';
 18+
 19+$wgMemc =& wfGetMainCache();
Index: trunk/phase3/tests/ArticleTest.php
@@ -4,6 +4,8 @@
55 var $saveGlobals = array();
66
77 function setUp() {
 8+ global $wgContLang;
 9+ $wgContLang = Language::factory( 'en' );
810 $globalSet = array(
911 'wgLegacyEncoding' => false,
1012 'wgCompressRevisions' => false,
Index: trunk/phase3/includes/WebRequest.php
@@ -762,6 +762,10 @@
763763 return isset( $this->headers[$name] ) ? $this->headers[$name] : false;
764764 }
765765
 766+ public function setHeader( $name, $val ) {
 767+ $this->headers[$name] = $val;
 768+ }
 769+
766770 public function getSessionData( $key ) {
767771 if( !isset( $this->session[$key] ) )
768772 return null;
Index: trunk/phase3/languages/LanguageConverter.php
@@ -16,7 +16,7 @@
1717 * @maintainers fdcn <fdcn64@gmail.com>, shinjiman <shinjiman@gmail.com>, PhiLiP <philip.npc@gmail.com>
1818 */
1919 class LanguageConverter {
20 - var $mPreferredVariant = '';
 20+ var $mPreferredVariant = ''; // The User's preferred variant
2121 var $mMainLanguageCode;
2222 var $mVariants, $mVariantFallbacks, $mVariantNames;
2323 var $mTablesLoaded = false;
@@ -34,6 +34,7 @@
3535 var $mUcfirst = false;
3636 var $mTitleOriginal = '';
3737 var $mTitleDisplay = '';
 38+ var $mHeaderVariant = null;
3839
3940 const CACHE_VERSION_KEY = 'VERSION 6';
4041
@@ -142,44 +143,48 @@
143144 global $wgUser, $wgRequest, $wgVariantArticlePath,
144145 $wgDefaultLanguageVariant, $wgOut;
145146
146 - // bug 21974, don't return $this->mPreferredVariant if $fromUser = false
147 - if ( $fromUser && $this->mPreferredVariant ) {
 147+ // see if the preference is set in the request
 148+ $req = $wgRequest->getText( 'variant' );
 149+ if ( in_array( $req, $this->mVariants ) ) {
 150+ $this->mPreferredVariant = $req;
148151 return $this->mPreferredVariant;
149152 }
150153
151 - // figure out user lang without constructing wgLang to avoid
152 - // infinite recursion
153 - if ( $fromUser ) {
 154+ if ( $fromUser ) {
 155+ // bug 21974, don't return $this->mPreferredVariant if
 156+ // $fromUser = false
 157+ if ( $this->mPreferredVariant ) {
 158+ return $this->mPreferredVariant;
 159+ }
 160+
 161+ // figure out user lang without constructing wgLang to avoid
 162+ // infinite recursion
154163 $defaultUserLang = $wgUser->getOption( 'language' );
 164+
 165+ // get language variant preference from logged in users
 166+ // Don't call this on stub objects because that causes infinite
 167+ // recursion during initialisation
 168+ if ( $wgUser->isLoggedIn() ) {
 169+ $this->mPreferredVariant = $wgUser->getOption( 'variant' );
 170+ }
 171+
155172 } else {
156173 $defaultUserLang = $this->mMainLanguageCode;
157174 }
 175+ $userLang = $wgRequest->getVal( 'uselang', $defaultUserLang );
158176
159 - $userLang = $wgRequest->getVal( 'uselang', $defaultUserLang );
160177 // see if interface language is same as content, if not, prevent
161178 // conversion
162 -
163179 if ( ! in_array( $userLang, $this->mVariants ) ) {
164180 // no conversion
165181 $this->mPreferredVariant = $this->mMainLanguageCode;
166182 return $this->mPreferredVariant;
167 - }
168 -
169 - // see if the preference is set in the request
170 - $req = $wgRequest->getText( 'variant' );
171 - if ( in_array( $req, $this->mVariants ) ) {
172 - $this->mPreferredVariant = $req;
 183+ } elseif ( $this->mPreferredVariant ) {
 184+ // if the variant was set above and it iss a variant of
 185+ // the content language
173186 return $this->mPreferredVariant;
174187 }
175188
176 - // get language variant preference from logged in users
177 - // Don't call this on stub objects because that causes infinite
178 - // recursion during initialisation
179 - if ( $fromUser && $wgUser->isLoggedIn() ) {
180 - $this->mPreferredVariant = $wgUser->getOption( 'variant' );
181 - return $this->mPreferredVariant;
182 - }
183 -
184189 // see if default variant is globaly set
185190 if ( $wgDefaultLanguageVariant != false
186191 && in_array( $wgDefaultLanguageVariant, $this->mVariants ) ) {
@@ -187,60 +192,81 @@
188193 return $this->mPreferredVariant;
189194 }
190195
191 - if ( !$this->mPreferredVariant ) {
192 - // see if some supported language variant is set in the
193 - // http header, but we don't set the mPreferredVariant
194 - // variable in case this is called before the user's
195 - // preference is loaded
 196+ $headerVariant = $this->getHeaderVariant();
 197+ if ( $fromHeader && $headerVariant ) {
 198+ return $headerVariant;
 199+ }
196200
197 - $acceptLanguage = $wgRequest->getHeader( 'Accept-Language' );
198 - if ( $fromHeader && $acceptLanguage ) {
199 - // explode by comma
200 - $result = explode( ',', strtolower( $acceptLanguage ) );
 201+ return $this->mMainLanguageCode;
 202+ }
201203
202 - $languages = array();
 204+ /**
 205+ * Determine the language variant from the Accept-Language header.
 206+ *
 207+ * @returns mixed variant if one found, false otherwise.
 208+ */
 209+ function getHeaderVariant() {
 210+ global $wgRequest;
203211
204 - foreach ( $result as $elem ) {
205 - // if $elem likes 'zh-cn;q=0.9'
206 - if ( ( $posi = strpos( $elem, ';' ) ) !== false ) {
207 - // get the real language code likes 'zh-cn'
208 - $languages[] = substr( $elem, 0, $posi );
209 - } else {
210 - $languages[] = $elem;
211 - }
212 - }
 212+ if ( $this->mHeaderVariant ) {
 213+ return $this->mHeaderVariant;
 214+ }
213215
214 - $fallback_languages = array();
215 - foreach ( $languages as $language ) {
216 - // strip whitespace
217 - $language = trim( $language );
218 - if ( in_array( $language, $this->mVariants ) ) {
219 - return $language;
220 - } else {
221 - // To see if there are fallbacks of current language.
222 - // We record these fallback variants, and process
223 - // them later.
224 - $fallbacks = $this->getVariantFallbacks( $language );
225 - if ( is_string( $fallbacks ) ) {
226 - $fallback_languages[] = $fallbacks;
227 - } elseif ( is_array( $fallbacks ) ) {
228 - $fallback_languages =
229 - array_merge( $fallback_languages,
230 - $fallbacks );
231 - }
232 - }
233 - }
 216+ // see if some supported language variant is set in the
 217+ // http header, but we don't set the mPreferredVariant
 218+ // variable in case this is called before the user's
 219+ // preference is loaded
234220
235 - // process fallback languages now
236 - $fallback_languages = array_unique( $fallback_languages );
237 - foreach ( $fallback_languages as $language ) {
238 - if ( in_array( $language, $this->mVariants ) ) {
239 - return $language;
240 - }
 221+ $acceptLanguage = $wgRequest->getHeader( 'Accept-Language' );
 222+ if ( !$acceptLanguage ) {
 223+ return false;
 224+ }
 225+
 226+ // explode by comma
 227+ $result = explode( ',', strtolower( $acceptLanguage ) );
 228+
 229+ $languages = array();
 230+
 231+ foreach ( $result as $elem ) {
 232+ // if $elem likes 'zh-cn;q=0.9'
 233+ if ( ( $posi = strpos( $elem, ';' ) ) !== false ) {
 234+ // get the real language code likes 'zh-cn'
 235+ $languages[] = substr( $elem, 0, $posi );
 236+ } else {
 237+ $languages[] = $elem;
 238+ }
 239+ }
 240+
 241+ $fallback_languages = array();
 242+ foreach ( $languages as $language ) {
 243+ // strip whitespace
 244+ $language = trim( $language );
 245+ if ( in_array( $language, $this->mVariants ) ) {
 246+ $this->mHeaderVariant = $language;
 247+ return $language;
 248+ } else {
 249+ // To see if there are fallbacks of current language.
 250+ // We record these fallback variants, and process
 251+ // them later.
 252+ $fallbacks = $this->getVariantFallbacks( $language );
 253+ if ( is_string( $fallbacks ) ) {
 254+ $fallback_languages[] = $fallbacks;
 255+ } elseif ( is_array( $fallbacks ) ) {
 256+ $fallback_languages =
 257+ array_merge( $fallback_languages,
 258+ $fallbacks );
241259 }
242260 }
243261 }
244 - return $this->mMainLanguageCode;
 262+
 263+ // process fallback languages now
 264+ $fallback_languages = array_unique( $fallback_languages );
 265+ foreach ( $fallback_languages as $language ) {
 266+ if ( in_array( $language, $this->mVariants ) ) {
 267+ $this->mHeaderVariant = $language;
 268+ return $language;
 269+ }
 270+ }
245271 }
246272
247273 /**

Status & tagging log