UNPKG

starlight-view-modes

Version:

Starlight plugin adding view mode capabilities to your documentation website.

399 lines (354 loc) 16.2 kB
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", ]); }); });