Index: includes/bootstrap.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/bootstrap.inc,v retrieving revision 1.220 diff -u -p -r1.220 bootstrap.inc --- includes/bootstrap.inc 21 Aug 2008 19:36:36 -0000 1.220 +++ includes/bootstrap.inc 3 Sep 2008 08:45:57 -0000 @@ -1135,14 +1135,20 @@ function drupal_init_language() { * Get a list of languages set up indexed by the specified key * * @param $field The field to index the list with. - * @param $reset Boolean to request a reset of the list. + * @param $reset Boolean to request a reset of the list, + * or (internal) an array of languages to feed that function with. */ function language_list($field = 'language', $reset = FALSE) { static $languages = NULL; // Reset language list if ($reset) { - $languages = NULL; + if (is_array($reset)) { + $languages = $reset; + } + else { + $languages = NULL; + } } // Init language list Index: modules/simpletest/tests/language.test =================================================================== RCS file: modules/simpletest/tests/language.test diff -N modules/simpletest/tests/language.test --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ modules/simpletest/tests/language.test 3 Sep 2008 10:19:49 -0000 @@ -0,0 +1,108 @@ + t('Language negotiation test'), + 'description' => t('Test the behavior of the language negotiation subsystem.'), + 'group' => t('System') + ); + } + + /** + * Implementation of setUp(). + */ + function setUp() { + parent::setUp('locale'); + } + + /** + * Unit tests for the language_from_browser() function. + */ + function testLanguageFromBrowser() { + $languages = array( + 'language' => array( + // In our test case, 'en' has priority over 'en-US'. + 'en' => (object) array( + 'language' => 'en', + 'enabled' => 1, + 'weight' => 1, + ), + 'en-US' => (object) array( + 'language' => 'en-US', + 'enabled' => 1, + 'weight' => 0.6, + ), + // But 'fr-CA' has priority over 'fr'. + 'fr-CA' => (object) array( + 'language' => 'fr-CA', + 'enabled' => 1, + 'weight' => 0.5, + ), + 'fr' => (object) array( + 'language' => 'fr', + 'enabled' => 1, + 'weight' => 0.4, + ), + // And 'es-MX' is alone. + 'es-MX' => (object) array( + 'language' => 'es-MX', + 'enabled' => 1, + 'weight' => 0.3, + ), + ) + ); + + drupal_function_exists('language_from_browser'); + + // Initialize the language list. + language_list('language', $languages); + + $test_cases = array( + // Equal qvalue for each language, choose the site prefered one. + 'en,en-US,fr-CA,fr,es-MX' => 'en', + 'fr,en' => 'en', + 'en,fr' => 'en', + 'en-US,fr' => 'en-US', + 'fr,en-US' => 'en-US', + 'fr' => 'fr-CA', + 'fr,es-MX' => 'fr-CA', + 'fr,es' => 'fr-CA', + 'es,fr' => 'fr-CA', + 'es-MX,de' => 'es-MX', + 'de,es-MX' => 'es-MX', + + // Different qvalues. + 'en-US,en;q=0.5,fr;q=0.25' => 'en-US', + 'fr,en;q=0.5' => 'fr-CA', + 'fr,en;q=0.5,fr-CA;q=0.25' => 'fr', + + // Those should be equivalent, because a selector matches all sub-languages + 'es-MX,en;q=0.5' => 'es-MX', + 'es,en;q=0.5' => 'es-MX', + + // Silly wildcards are also valid. + '*,fr-CA;q=0.5' => 'en', + '*,en;q=0.25' => 'fr-CA', + 'en,en-US;q=0.5,fr;q=0.25' => 'en', + 'en-US,en;q=0.5,fr;q=0.25' => 'en-US', + + // Unresolvable cases. + '' => NULL, + 'de,pl' => NULL, + $this->randomName(10) => NULL, + ); + + foreach ($test_cases as $accept_language => $expected_result) { + $_SERVER['HTTP_ACCEPT_LANGUAGE'] = $accept_language; + $result = language_from_browser(); + $this->assertIdentical(isset($result->language) ? $result->language : NULL, $expected_result, t("Language selection '@accept-language' selects '@result', result = '@actual'", array('@accept-language' => $accept_language, '@result' => $expected_result, '@actual' => isset($result->language) ? $result->language : 'none'))); + } + } +} +