1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 const { getPreferedLocales, findClosestLocale } = require("sdk/l10n/locale");
6 const prefs = require("sdk/preferences/service");
7 const { Cc, Ci, Cu } = require("chrome");
8 const { Services } = Cu.import("resource://gre/modules/Services.jsm");
9 const BundleService = Cc["@mozilla.org/intl/stringbundle;1"].getService(Ci.nsIStringBundleService);
11 const PREF_MATCH_OS_LOCALE = "intl.locale.matchOS";
12 const PREF_SELECTED_LOCALE = "general.useragent.locale";
13 const PREF_ACCEPT_LANGUAGES = "intl.accept_languages";
15 function assertPrefered(assert, expected, msg) {
16 assert.equal(JSON.stringify(getPreferedLocales()), JSON.stringify(expected),
20 exports.testGetPreferedLocales = function(assert) {
21 prefs.set(PREF_MATCH_OS_LOCALE, false);
22 prefs.set(PREF_SELECTED_LOCALE, "");
23 prefs.set(PREF_ACCEPT_LANGUAGES, "");
24 assertPrefered(assert, ["en-us"],
25 "When all preferences are empty, we only have en-us");
27 prefs.set(PREF_SELECTED_LOCALE, "fr");
28 prefs.set(PREF_ACCEPT_LANGUAGES, "jp");
29 assertPrefered(assert, ["fr", "jp", "en-us"],
30 "We first have useragent locale, then web one and finally en-US");
32 prefs.set(PREF_SELECTED_LOCALE, "en-US");
33 prefs.set(PREF_ACCEPT_LANGUAGES, "en-US");
34 assertPrefered(assert, ["en-us"],
35 "We do not have duplicates");
37 prefs.set(PREF_SELECTED_LOCALE, "en-US");
38 prefs.set(PREF_ACCEPT_LANGUAGES, "fr");
39 assertPrefered(assert, ["en-us", "fr"],
40 "en-US can be first if specified by higher priority preference");
42 // Reset what we changed
43 prefs.reset(PREF_MATCH_OS_LOCALE);
44 prefs.reset(PREF_SELECTED_LOCALE);
45 prefs.reset(PREF_ACCEPT_LANGUAGES);
48 // In some cases, mainly on Fennec and on Linux version,
49 // `general.useragent.locale` is a special 'localized' value, like:
50 // "chrome://global/locale/intl.properties"
51 exports.testPreferedLocalizedLocale = function(assert) {
52 prefs.set(PREF_MATCH_OS_LOCALE, false);
53 let bundleURL = "chrome://global/locale/intl.properties";
54 prefs.setLocalized(PREF_SELECTED_LOCALE, bundleURL);
55 let contentLocale = "ja";
56 prefs.set(PREF_ACCEPT_LANGUAGES, contentLocale);
58 // Read manually the expected locale value from the property file
59 let expectedLocale = BundleService.createBundle(bundleURL).
60 GetStringFromName(PREF_SELECTED_LOCALE).
63 // First add the useragent locale
64 let expectedLocaleList = [expectedLocale];
66 // Then the content locale
67 if (expectedLocaleList.indexOf(contentLocale) == -1)
68 expectedLocaleList.push(contentLocale);
70 // Add default "en-us" fallback if the main language is not already en-us
71 if (expectedLocaleList.indexOf("en-us") == -1)
72 expectedLocaleList.push("en-us");
74 assertPrefered(assert, expectedLocaleList, "test localized pref value");
76 // Reset what we have changed
77 prefs.reset(PREF_MATCH_OS_LOCALE);
78 prefs.reset(PREF_SELECTED_LOCALE);
79 prefs.reset(PREF_ACCEPT_LANGUAGES);
82 exports.testPreferedOsLocale = function(assert) {
83 prefs.set(PREF_MATCH_OS_LOCALE, true);
84 prefs.set(PREF_SELECTED_LOCALE, "");
85 prefs.set(PREF_ACCEPT_LANGUAGES, "");
87 let expectedLocale = Services.locale.getLocaleComponentForUserAgent().
89 let expectedLocaleList = [expectedLocale];
91 // Add default "en-us" fallback if the main language is not already en-us
92 if (expectedLocale != "en-us")
93 expectedLocaleList.push("en-us");
95 assertPrefered(assert, expectedLocaleList, "Ensure that we select OS locale when related preference is set");
97 // Reset what we have changed
98 prefs.reset(PREF_MATCH_OS_LOCALE);
99 prefs.reset(PREF_SELECTED_LOCALE);
100 prefs.reset(PREF_ACCEPT_LANGUAGES);
103 exports.testFindClosestLocale = function(assert) {
104 // Second param of findClosestLocale (aMatchLocales) have to be in lowercase
105 assert.equal(findClosestLocale([], []), null,
106 "When everything is empty we get null");
108 assert.equal(findClosestLocale(["en", "en-US"], ["en"]),
109 "en", "We always accept exact match first 1/5");
110 assert.equal(findClosestLocale(["en-US", "en"], ["en"]),
111 "en", "We always accept exact match first 2/5");
112 assert.equal(findClosestLocale(["en", "en-US"], ["en-us"]),
113 "en-US", "We always accept exact match first 3/5");
114 assert.equal(findClosestLocale(["ja-JP-mac", "ja", "ja-JP"], ["ja-jp"]),
115 "ja-JP", "We always accept exact match first 4/5");
116 assert.equal(findClosestLocale(["ja-JP-mac", "ja", "ja-JP"], ["ja-jp-mac"]),
117 "ja-JP-mac", "We always accept exact match first 5/5");
119 assert.equal(findClosestLocale(["en", "en-GB"], ["en-us"]),
120 "en", "We accept more generic locale, when there is no exact match 1/2");
121 assert.equal(findClosestLocale(["en-ZA", "en"], ["en-gb"]),
122 "en", "We accept more generic locale, when there is no exact match 2/2");
124 assert.equal(findClosestLocale(["ja-JP"], ["ja"]),
125 "ja-JP", "We accept more specialized locale, when there is no exact match 1/2");
126 // Better to select "ja" in this case but behave same as current AddonManager
127 assert.equal(findClosestLocale(["ja-JP-mac", "ja"], ["ja-jp"]),
128 "ja-JP-mac", "We accept more specialized locale, when there is no exact match 2/2");
130 assert.equal(findClosestLocale(["en-US"], ["en-us"]),
131 "en-US", "We keep the original one as result 1/2");
132 assert.equal(findClosestLocale(["en-us"], ["en-us"]),
133 "en-us", "We keep the original one as result 2/2");
135 assert.equal(findClosestLocale(["ja-JP-mac"], ["ja-jp-mac"]),
136 "ja-JP-mac", "We accept locale with 3 parts");
137 assert.equal(findClosestLocale(["ja-JP"], ["ja-jp-mac"]),
138 "ja-JP", "We accept locale with 2 parts from locale with 3 parts");
139 assert.equal(findClosestLocale(["ja"], ["ja-jp-mac"]),
140 "ja", "We accept locale with 1 part from locale with 3 parts");
143 require('sdk/test').run(exports);