starlight-view-modes
Version:
Starlight plugin adding view mode capabilities to your documentation website.
399 lines (354 loc) • 16.2 kB
text/typescript
import { describe, expect, vi, afterEach, test } from "vitest";
function mockStarlightConfig(config: any) {
vi.doMock("virtual:starlight/user-config", () => ({
default: config,
}));
}
function mockAstroConfigBase(base: string = "", trailingSlash: "never" | "always" | "ignore" = "ignore") {
vi.doMock("virtual:starlight-view-modes-context", () => ({
default: { base, trailingSlash: trailingSlash },
}));
}
async function importI18n() {
return await import("../libs/i18n");
}
afterEach(() => {
vi.resetModules();
vi.resetAllMocks();
});
describe("getLocalizedSlug", () => {
test("returns same slug when locale matches", async () => {
mockAstroConfigBase();
mockStarlightConfig({
defaultLocale: { locale: "en", lang: "en" },
locales: { en: {}, de: {}, fr: {} },
});
const { getLocalizedSlug } = await importI18n();
expect(getLocalizedSlug("de/home", "de")).toBe("de/home");
expect(getLocalizedSlug("fr/home", "fr")).toBe("fr/home");
expect(getLocalizedSlug("fr/home", "ru")).toBe("fr/home");
expect(getLocalizedSlug("ru/home", "fr")).toBe("fr/ru/home");
expect(getLocalizedSlug("ru/home", "ru")).toBe("ru/home");
expect(getLocalizedSlug("/de/home", "de")).toBe("/de/home");
expect(getLocalizedSlug("de/home/", "de")).toBe("de/home/");
expect(getLocalizedSlug("/de/home/", "de")).toBe("/de/home/");
expect(getLocalizedSlug("/de/some/long/path/", "de")).toBe("/de/some/long/path/");
});
test("returns same slug when locale matches; with base option", async () => {
mockAstroConfigBase("/docs");
mockStarlightConfig({
defaultLocale: { locale: "en", lang: "en" },
locales: { en: {}, de: {}, fr: {} },
});
const { getLocalizedSlug } = await importI18n();
expect(getLocalizedSlug("de/home", "de")).toBe("de/home");
expect(getLocalizedSlug("fr/home", "fr")).toBe("fr/home");
expect(getLocalizedSlug("fr/home", "ru")).toBe("fr/home");
expect(getLocalizedSlug("ru/home", "fr")).toBe("fr/ru/home");
expect(getLocalizedSlug("ru/home", "ru")).toBe("ru/home");
expect(getLocalizedSlug("/de/home", "de")).toBe("/de/home");
expect(getLocalizedSlug("de/home/", "de")).toBe("de/home/");
expect(getLocalizedSlug("/de/home/", "de")).toBe("/de/home/");
expect(getLocalizedSlug("/de/some/long/path/", "de")).toBe("/de/some/long/path/");
expect(getLocalizedSlug("docs/de/home", "de")).toBe("docs/de/home");
expect(getLocalizedSlug("docs/fr/home", "fr")).toBe("docs/fr/home");
expect(getLocalizedSlug("docs/fr/home", "ru")).toBe("docs/fr/home");
expect(getLocalizedSlug("docs/ru/home", "fr")).toBe("docs/fr/ru/home");
expect(getLocalizedSlug("docs/ru/home", "ru")).toBe("docs/ru/home");
expect(getLocalizedSlug("/docs/de/home", "de")).toBe("/docs/de/home");
expect(getLocalizedSlug("docs/de/home/", "de")).toBe("docs/de/home/");
expect(getLocalizedSlug("/docs/de/home/", "de")).toBe("/docs/de/home/");
expect(getLocalizedSlug("/docs/de/some/long/path/", "de")).toBe("/docs/de/some/long/path/");
});
test("removes old locale and replaces with new one", async () => {
mockAstroConfigBase();
mockStarlightConfig({
defaultLocale: { locale: "en", lang: "en" },
locales: { en: {}, de: {}, fr: {} },
});
const { getLocalizedSlug } = await importI18n();
expect(getLocalizedSlug("de/home", "fr")).toBe("fr/home");
expect(getLocalizedSlug("fr/home", "en")).toBe("en/home");
expect(getLocalizedSlug("fr/home", "ru")).toBe("fr/home");
expect(getLocalizedSlug("ru/home", "fr")).toBe("fr/ru/home");
expect(getLocalizedSlug("ru/home", "ru")).toBe("ru/home");
expect(getLocalizedSlug("de/home/", "fr")).toBe("fr/home/");
expect(getLocalizedSlug("/de/home", "fr")).toBe("/fr/home");
expect(getLocalizedSlug("/de/home/", "fr")).toBe("/fr/home/");
expect(getLocalizedSlug("/de/some/long/path/", "fr")).toBe("/fr/some/long/path/");
});
test("removes old locale and replaces with new one; with base option", async () => {
mockAstroConfigBase("/docs");
mockStarlightConfig({
defaultLocale: { locale: "en", lang: "en" },
locales: { en: {}, de: {}, fr: {} },
});
const { getLocalizedSlug } = await importI18n();
expect(getLocalizedSlug("de/home", "fr")).toBe("fr/home");
expect(getLocalizedSlug("fr/home", "en")).toBe("en/home");
expect(getLocalizedSlug("fr/home", "ru")).toBe("fr/home");
expect(getLocalizedSlug("ru/home", "fr")).toBe("fr/ru/home");
expect(getLocalizedSlug("ru/home", "ru")).toBe("ru/home");
expect(getLocalizedSlug("de/home/", "fr")).toBe("fr/home/");
expect(getLocalizedSlug("/de/home", "fr")).toBe("/fr/home");
expect(getLocalizedSlug("/de/home/", "fr")).toBe("/fr/home/");
expect(getLocalizedSlug("/de/some/long/path/", "fr")).toBe("/fr/some/long/path/");
expect(getLocalizedSlug("docs/de/home", "fr")).toBe("docs/fr/home");
expect(getLocalizedSlug("docs/fr/home", "en")).toBe("docs/en/home");
expect(getLocalizedSlug("docs/fr/home", "ru")).toBe("docs/fr/home");
expect(getLocalizedSlug("docs/ru/home", "fr")).toBe("docs/fr/ru/home");
expect(getLocalizedSlug("docs/ru/home", "ru")).toBe("docs/ru/home");
expect(getLocalizedSlug("docs/de/home/", "fr")).toBe("docs/fr/home/");
expect(getLocalizedSlug("/docs/de/home", "fr")).toBe("/docs/fr/home");
expect(getLocalizedSlug("/docs/de/home/", "fr")).toBe("/docs/fr/home/");
expect(getLocalizedSlug("/docs/de/some/long/path/", "fr")).toBe("/docs/fr/some/long/path/");
});
test("adds locale when slug has none", async () => {
mockAstroConfigBase();
mockStarlightConfig({
defaultLocale: { locale: "en", lang: "en" },
locales: { en: {}, de: {}, fr: {} },
});
const { getLocalizedSlug } = await importI18n();
expect(getLocalizedSlug("home", "de")).toBe("de/home");
expect(getLocalizedSlug("home", "fr")).toBe("fr/home");
expect(getLocalizedSlug("home", "ru")).toBe("home");
expect(getLocalizedSlug("/home", "de")).toBe("/de/home");
expect(getLocalizedSlug("home/", "de")).toBe("de/home/");
expect(getLocalizedSlug("/home/", "de")).toBe("/de/home/");
expect(getLocalizedSlug("/some/long/path/", "de")).toBe("/de/some/long/path/");
});
test("adds locale when slug has none; with base option", async () => {
mockAstroConfigBase("/docs");
mockStarlightConfig({
defaultLocale: { locale: "en", lang: "en" },
locales: { en: {}, de: {}, fr: {} },
});
const { getLocalizedSlug } = await importI18n();
expect(getLocalizedSlug("home", "de")).toBe("de/home");
expect(getLocalizedSlug("home", "fr")).toBe("fr/home");
expect(getLocalizedSlug("home", "ru")).toBe("home");
expect(getLocalizedSlug("/home", "de")).toBe("/de/home");
expect(getLocalizedSlug("home/", "de")).toBe("de/home/");
expect(getLocalizedSlug("/home/", "de")).toBe("/de/home/");
expect(getLocalizedSlug("/some/long/path/", "de")).toBe("/de/some/long/path/");
expect(getLocalizedSlug("docs/home", "de")).toBe("docs/de/home");
expect(getLocalizedSlug("docs/home", "fr")).toBe("docs/fr/home");
expect(getLocalizedSlug("docs/home", "ru")).toBe("docs/home");
expect(getLocalizedSlug("/docs/home", "de")).toBe("/docs/de/home");
expect(getLocalizedSlug("docs/home/", "de")).toBe("docs/de/home/");
expect(getLocalizedSlug("/docs/home/", "de")).toBe("/docs/de/home/");
expect(getLocalizedSlug("/docs/some/long/path/", "de")).toBe("/docs/de/some/long/path/");
});
test("removes locale when set to undefined", async () => {
mockAstroConfigBase();
mockStarlightConfig({
defaultLocale: { locale: "en", lang: "en" },
locales: { en: {}, de: {}, fr: {} },
});
const { getLocalizedSlug } = await importI18n();
expect(getLocalizedSlug("de/home", undefined)).toBe("home");
expect(getLocalizedSlug("fr/home", undefined)).toBe("home");
expect(getLocalizedSlug("ru/home", undefined)).toBe("ru/home");
expect(getLocalizedSlug("de/home/", undefined)).toBe("home/");
expect(getLocalizedSlug("/de/home", undefined)).toBe("/home");
expect(getLocalizedSlug("/de/home/", undefined)).toBe("/home/");
expect(getLocalizedSlug("/de/some/long/path/", undefined)).toBe("/some/long/path/");
});
test("removes locale when set to undefined; with base option", async () => {
mockAstroConfigBase("/docs");
mockStarlightConfig({
defaultLocale: { locale: "en", lang: "en" },
locales: { en: {}, de: {}, fr: {} },
});
const { getLocalizedSlug } = await importI18n();
expect(getLocalizedSlug("de/home", undefined)).toBe("home");
expect(getLocalizedSlug("fr/home", undefined)).toBe("home");
expect(getLocalizedSlug("ru/home", undefined)).toBe("ru/home");
expect(getLocalizedSlug("de/home/", undefined)).toBe("home/");
expect(getLocalizedSlug("/de/home", undefined)).toBe("/home");
expect(getLocalizedSlug("/de/home/", undefined)).toBe("/home/");
expect(getLocalizedSlug("/de/some/long/path/", undefined)).toBe("/some/long/path/");
expect(getLocalizedSlug("docs/de/home", undefined)).toBe("docs/home");
expect(getLocalizedSlug("docs/fr/home", undefined)).toBe("docs/home");
expect(getLocalizedSlug("docs/ru/home", undefined)).toBe("docs/ru/home");
expect(getLocalizedSlug("docs/de/home/", undefined)).toBe("docs/home/");
expect(getLocalizedSlug("/docs/de/home", undefined)).toBe("/docs/home");
expect(getLocalizedSlug("/docs/de/home/", undefined)).toBe("/docs/home/");
expect(getLocalizedSlug("/docs/de/some/long/path/", undefined)).toBe("/docs/some/long/path/");
});
});
describe("getLocaleFromSlug", () => {
test("returns locale if present in config", async () => {
mockAstroConfigBase();
mockStarlightConfig({
defaultLocale: { locale: "en", lang: "en" },
locales: { en: {}, de: {}, fr: {} },
});
const { getLocaleFromSlug } = await importI18n();
expect(getLocaleFromSlug("de/home")).toBe("de");
expect(getLocaleFromSlug("fr/home")).toBe("fr");
expect(getLocaleFromSlug("de/home/")).toBe("de");
expect(getLocaleFromSlug("/de/home")).toBe("de");
expect(getLocaleFromSlug("/de/home/")).toBe("de");
expect(getLocaleFromSlug("/de/some/long/path/")).toBe("de");
});
test("returns locale if present in config; with base option", async () => {
mockAstroConfigBase("/docs");
mockStarlightConfig({
defaultLocale: { locale: "en", lang: "en" },
locales: { en: {}, de: {}, fr: {} },
});
const { getLocaleFromSlug } = await importI18n();
expect(getLocaleFromSlug("de/home")).toBe("de");
expect(getLocaleFromSlug("fr/home")).toBe("fr");
expect(getLocaleFromSlug("de/home/")).toBe("de");
expect(getLocaleFromSlug("/de/home")).toBe("de");
expect(getLocaleFromSlug("/de/home/")).toBe("de");
expect(getLocaleFromSlug("/de/some/long/path/")).toBe("de");
expect(getLocaleFromSlug("docs/de/home")).toBe("de");
expect(getLocaleFromSlug("docs/fr/home")).toBe("fr");
expect(getLocaleFromSlug("docs/de/home/")).toBe("de");
expect(getLocaleFromSlug("/docs/de/home")).toBe("de");
expect(getLocaleFromSlug("/docs/de/home/")).toBe("de");
expect(getLocaleFromSlug("/docs/de/some/long/path/")).toBe("de");
});
test("returns undefined if locale is not present", async () => {
mockAstroConfigBase();
mockStarlightConfig({
defaultLocale: { locale: "en", lang: "en" },
locales: { en: {}, de: {}, fr: {} },
});
const { getLocaleFromSlug } = await importI18n();
expect(getLocaleFromSlug("home")).toBeUndefined();
expect(getLocaleFromSlug("ru/home")).toBeUndefined();
expect(getLocaleFromSlug("home/en")).toBeUndefined();
expect(getLocaleFromSlug("home/fr")).toBeUndefined();
expect(getLocaleFromSlug("home/en/")).toBeUndefined();
expect(getLocaleFromSlug("home/fr/")).toBeUndefined();
});
test("returns undefined if locale is not present; with base option", async () => {
mockAstroConfigBase("/docs");
mockStarlightConfig({
defaultLocale: { locale: "en", lang: "en" },
locales: { en: {}, de: {}, fr: {} },
});
const { getLocaleFromSlug } = await importI18n();
expect(getLocaleFromSlug("home")).toBeUndefined();
expect(getLocaleFromSlug("ru/home")).toBeUndefined();
expect(getLocaleFromSlug("home/en")).toBeUndefined();
expect(getLocaleFromSlug("home/fr")).toBeUndefined();
expect(getLocaleFromSlug("home/en/")).toBeUndefined();
expect(getLocaleFromSlug("home/fr/")).toBeUndefined();
expect(getLocaleFromSlug("docs/home")).toBeUndefined();
expect(getLocaleFromSlug("docs/ru/home")).toBeUndefined();
expect(getLocaleFromSlug("docs/home/en")).toBeUndefined();
expect(getLocaleFromSlug("docs/home/fr")).toBeUndefined();
expect(getLocaleFromSlug("docs/home/en/")).toBeUndefined();
expect(getLocaleFromSlug("docs/home/fr/")).toBeUndefined();
});
});
describe("getLocales", () => {
test("returns default locale when no mode is present", async () => {
mockAstroConfigBase();
mockStarlightConfig({
defaultLocale: { locale: "en", lang: "en" },
locales: { en: {} },
});
const { getLocales } = await importI18n();
expect(getLocales()).toEqual(["en"]);
});
test("returns undefined when default locale is root", async () => {
mockAstroConfigBase();
mockStarlightConfig({
defaultLocale: { locale: "root", lang: "en" },
locales: {root: {}},
});
const { getLocales } = await importI18n();
expect(getLocales()).toEqual([undefined]);
});
test("returns available locales excluding default", async () => {
mockAstroConfigBase();
mockStarlightConfig({
defaultLocale: { locale: "en", lang: "en" },
locales: { en: {}, de: {}, fr: {} },
});
const { getLocales } = await importI18n();
expect(getLocales()).toEqual(["en", "de", "fr"]);
});
});
describe("getLocalizedExclude", () => {
test("returns localized versions of exclude paths", async () => {
mockAstroConfigBase();
mockStarlightConfig({
defaultLocale: { locale: "en", lang: "en" },
locales: { en: {}, de: {}, fr: {} },
});
const { getLocalizedExclude } = await importI18n();
expect(getLocalizedExclude(["home", "about"])).toEqual([
"en/home",
"en/about",
"de/home",
"de/about",
"fr/home",
"fr/about",
]);
});
test("removes existing locale before localizing", async () => {
mockAstroConfigBase();
mockStarlightConfig({
defaultLocale: { locale: "en", lang: "en" },
locales: { en: {}, de: {}, fr: {} },
});
const { getLocalizedExclude } = await importI18n();
expect(getLocalizedExclude(["de/home", "fr/about"])).toEqual([
"en/home",
"en/about",
"de/home",
"de/about",
"fr/home",
"fr/about",
]);
});
test("handles paths with leading slashes correctly", async () => {
mockAstroConfigBase();
mockStarlightConfig({
defaultLocale: { locale: "en", lang: "en" },
locales: { en: {}, de: {}, fr: {} },
});
const { getLocalizedExclude } = await importI18n();
expect(getLocalizedExclude(["/contact", "/info"])).toEqual([
"/en/contact",
"/en/info",
"/de/contact",
"/de/info",
"/fr/contact",
"/fr/info",
]);
});
test("returns empty array when exclude list is empty", async () => {
mockAstroConfigBase();
mockStarlightConfig({
defaultLocale: { locale: "en", lang: "en" },
locales: { en: {}, de: {}, fr: {} },
});
const { getLocalizedExclude } = await importI18n();
expect(getLocalizedExclude([])).toEqual([]);
});
test("handles paths that already include locales", async () => {
mockAstroConfigBase();
mockStarlightConfig({
defaultLocale: { locale: "en", lang: "en" },
locales: { en: {}, de: {}, fr: {} },
});
const { getLocalizedExclude } = await importI18n();
expect(getLocalizedExclude(["en/blog", "de/news"])).toEqual([
"en/blog",
"en/news",
"de/blog",
"de/news",
"fr/blog",
"fr/news",
]);
});
});