Revision control
Copy as Markdown
Other Tools
/* -*- Mode: JavaScript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
/*
* Test various things about the font chooser window, including
* - whether if the font defined in font.name.<style>.<language> is not present
* on the computer, we fall back to displaying what's in
* font.name-list.<style>.<language>.
*/
var gFontEnumerator;
const kLanguage = "x-western";
// A list of fonts present on the computer for each font type.
var gRealFontLists = {};
// A list of font types to consider
const kFontTypes = ["serif", "sans-serif", "monospace"];
add_setup(async function () {
if (AppConstants.platform == "win") {
Services.prefs.setStringPref(
"font.name-list.serif.x-western",
"bc7e8c62-0634-467f-a029-fe6abcdf1582, Times New Roman"
);
Services.prefs.setStringPref(
"font.name-list.sans-serif.x-western",
"419129aa-43b7-40c4-b554-83d99b504b89, Arial"
);
Services.prefs.setStringPref(
"font.name-list.monospace.x-western",
"348df6e5-e874-4d21-ad4b-359b530a33b7, Courier New"
);
} else if (AppConstants.platform == "macosx") {
Services.prefs.setStringPref(
"font.name-list.serif.x-western",
"bc7e8c62-0634-467f-a029-fe6abcdf1582, Times"
);
Services.prefs.setStringPref(
"font.name-list.sans-serif.x-western",
"419129aa-43b7-40c4-b554-83d99b504b89, Helvetica"
);
Services.prefs.setStringPref(
"font.name-list.monospace.x-western",
"348df6e5-e874-4d21-ad4b-359b530a33b7, Courier"
);
} else {
Services.prefs.setStringPref(
"font.name-list.serif.x-western",
"bc7e8c62-0634-467f-a029-fe6abcdf1582, serif"
);
Services.prefs.setStringPref(
"font.name-list.sans-serif.x-western",
"419129aa-43b7-40c4-b554-83d99b504b89, sans-serif"
);
Services.prefs.setStringPref(
"font.name-list.monospace.x-western",
"348df6e5-e874-4d21-ad4b-359b530a33b7, monospace"
);
}
let finished = false;
buildFontList().then(() => (finished = true), console.error);
await TestUtils.waitForCondition(
() => finished,
"Timeout waiting for font enumeration to complete."
);
});
async function buildFontList() {
gFontEnumerator = Cc["@mozilla.org/gfx/fontenumerator;1"].createInstance(
Ci.nsIFontEnumerator
);
for (const fontType of kFontTypes) {
gRealFontLists[fontType] = await gFontEnumerator.EnumerateFontsAsync(
kLanguage,
fontType
);
Assert.greater(
gRealFontLists[fontType].length,
0,
`there should be fonts for language ${kLanguage} and font type ${fontType}`
);
}
}
function assert_fonts_equal(aDescription, aExpected, aActual, aPrefix = false) {
if (aPrefix) {
Assert.ok(
aActual.startsWith(aExpected),
`the ${aDescription} font should be '${aExpected}', but is actually '${aActual}'`
);
} else {
Assert.equal(
aExpected,
aActual,
`the ${aDescription} font should be '${aExpected}'`
);
}
}
/**
* Verify that the given fonts are displayed in the font chooser. This opens the
* pref window to the display pane and checks that, then opens the font chooser
* and checks that too.
*/
async function _verify_fonts_displayed(
aDefaults,
aSerif,
aSansSerif,
aMonospace
) {
// Bring up the preferences window.
const { prefsDocument } = await openNewPrefsTab(
"paneGeneral",
"languageAndFontsCategory"
);
const isSansDefault =
Services.prefs.getCharPref("font.default." + kLanguage) == "sans-serif";
const displayPaneExpected = isSansDefault ? aSansSerif : aSerif;
const displayPaneActual = prefsDocument.getElementById("defaultFont");
await TestUtils.waitForCondition(
() => displayPaneActual.itemCount > 0,
"No font names were populated in the font picker."
);
assert_fonts_equal(
"display pane",
displayPaneExpected,
displayPaneActual.value
);
// Now open the advanced dialog.
await promiseSubDialog(
prefsDocument.getElementById("advancedFonts"),
async function (fontc) {
// The font pickers are populated async so we need to wait for it.
for (const fontElemId of ["serif", "sans-serif", "monospace"]) {
await TestUtils.waitForCondition(
() => fontc.document.getElementById(fontElemId).label != "",
"Timeout waiting for font picker '" + fontElemId + "' to populate."
);
}
if (!aDefaults) {
assert_fonts_equal(
"serif",
aSerif,
fontc.document.getElementById("serif").value
);
assert_fonts_equal(
"sans-serif",
aSansSerif,
fontc.document.getElementById("sans-serif").value
);
assert_fonts_equal(
"monospace",
aMonospace,
fontc.document.getElementById("monospace").value
);
} else if (AppConstants.platform == "linux") {
// When default fonts are displayed in the menulist, there is no value set,
// only the label, in the form "Default (font name)".
// On Linux the prefs we set contained only the generic font names,
// like 'serif', but here a specific font name will be shown, but it is
// system-dependent what it will be. So we just check for the 'Default'
// prefix.
assert_fonts_equal(
"serif",
`Default (`,
fontc.document.getElementById("serif").label,
true
);
assert_fonts_equal(
"sans-serif",
`Default (`,
fontc.document.getElementById("sans-serif").label,
true
);
assert_fonts_equal(
"monospace",
`Default (`,
fontc.document.getElementById("monospace").label,
true
);
} else {
assert_fonts_equal(
"serif",
`Default (${aSerif})`,
fontc.document.getElementById("serif").label
);
assert_fonts_equal(
"sans-serif",
`Default (${aSansSerif})`,
fontc.document.getElementById("sans-serif").label
);
assert_fonts_equal(
"monospace",
`Default (${aMonospace})`,
fontc.document.getElementById("monospace").label
);
}
},
"cancel"
);
await closePrefsTab();
}
/**
* Test that for a particular language, whatever's in
* font.name.<type>.<language> is displayed in the font chooser (if it is
* present on the computer).
*/
add_task(async function test_font_name_displayed() {
Services.prefs.setStringPref("font.language.group", kLanguage);
// Pick the first font for each font type and set it.
const expected = {};
for (const [fontType, fontList] of Object.entries(gRealFontLists)) {
// substituted with Courier New) by getting the standard (substituted) family
// name for each font.
const standardFamily = gFontEnumerator.getStandardFamilyName(fontList[0]);
Services.prefs.setCharPref(
"font.name." + fontType + "." + kLanguage,
standardFamily
);
expected[fontType] = standardFamily;
}
const fontTypes = kFontTypes.map(fontType => expected[fontType]);
await _verify_fonts_displayed(false, ...fontTypes);
teardownTest();
});
// Fonts definitely not present on a computer -- we simply use UUIDs. These
// should be kept in sync with the ones in *-prefs.js.
const kFakeFonts = {
serif: "bc7e8c62-0634-467f-a029-fe6abcdf1582",
"sans-serif": "419129aa-43b7-40c4-b554-83d99b504b89",
monospace: "348df6e5-e874-4d21-ad4b-359b530a33b7",
};
/**
* Test that for a particular language, if font.name.<type>.<language> is not
* present on the computer, we fall back to displaying what's in
* font.name-list.<type>.<language>.
*/
add_task(async function test_font_name_not_present() {
Services.prefs.setStringPref("font.language.group", kLanguage);
// The fonts we're expecting to see selected in the font chooser for
// test_font_name_not_present.
const expected = {};
for (const [fontType, fakeFont] of Object.entries(kFakeFonts)) {
// Look at the font.name-list. We need to verify that the first font is the
// fake one, and that the second one is present on the user's computer.
const listPref = "font.name-list." + fontType + "." + kLanguage;
const fontList = Services.prefs.getCharPref(listPref);
const fonts = fontList.split(",").map(font => font.trim());
Assert.equal(fonts.length, 2, `${listPref} should have exactly two fonts`);
Assert.equal(
fonts[0],
fakeFont,
`the first font in ${listPref} should be '${fakeFont}'`
);
Assert.ok(
gRealFontLists[fontType].includes(fonts[1]),
`the second font in ${listPref} (${fonts[1]}) should be present on this computer`
);
expected[fontType] = fonts[1];
// Set font.name to be a nonsense name that shouldn't exist.
// font.name-list is handled by wrapper.py.
Services.prefs.setCharPref(
"font.name." + fontType + "." + kLanguage,
fakeFont
);
}
const fontTypes = kFontTypes.map(fontType => expected[fontType]);
await _verify_fonts_displayed(true, ...fontTypes);
teardownTest();
});
function teardownTest() {
for (const pref of Services.prefs.getChildList("font.name.")) {
Services.prefs.clearUserPref(pref);
}
}
registerCleanupFunction(function () {
Services.prefs.clearUserPref("font.language.group");
});