select.test.ts 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. import { expect, test } from "bun:test"
  2. import {
  3. selectTheme,
  4. selectThemeMode,
  5. supportsThemeMode,
  6. themeModes,
  7. type HueDefinition,
  8. type ThemeDefinition,
  9. type ThemeDocument,
  10. } from "@opencode-ai/theme/tui"
  11. const hue = {} as HueDefinition
  12. const light = { hue, categorical: ["blue"], text: { default: "#111111", subdued: "#222222" } } satisfies ThemeDefinition
  13. const dark = {
  14. hue,
  15. categorical: ["purple"],
  16. text: { default: "#eeeeee", subdued: "#dddddd" },
  17. } satisfies ThemeDefinition
  18. test("requires and selects independent light and dark themes", () => {
  19. const document = { version: 2, light, dark } satisfies ThemeDocument
  20. expect(selectTheme(document)).toBe(light)
  21. expect(selectTheme(document, "light")).toBe(light)
  22. expect(selectTheme(document, "dark")).toBe(dark)
  23. expect(selectThemeMode(document, "dark").mode).toBe("dark")
  24. })
  25. test("merges an expanded mode override over the other mode", () => {
  26. const document = {
  27. version: 2,
  28. light,
  29. dark: { mergeMode: true, text: { default: "#ffffff" } },
  30. } satisfies ThemeDocument
  31. const selected = selectTheme(document, "dark")
  32. expect(selected.hue).toBeDefined()
  33. expect(selected.text?.default).toBe("#ffffff")
  34. expect(selected.text?.subdued).toBe("$text.default")
  35. })
  36. test("replaces categorical order in a merge mode", () => {
  37. const selected = selectTheme(
  38. { version: 2, light, dark: { mergeMode: true, categorical: ["accent", "cyan"] } },
  39. "dark",
  40. )
  41. expect(selected.categorical).toEqual(["accent", "cyan"])
  42. })
  43. test("selects the available mode when the requested mode is missing", () => {
  44. const lightOnly = { version: 2, light } satisfies ThemeDocument
  45. const darkOnly = { version: 2, dark } satisfies ThemeDocument
  46. expect(themeModes(lightOnly)).toEqual(["light"])
  47. expect(themeModes(darkOnly)).toEqual(["dark"])
  48. expect(supportsThemeMode(lightOnly, "light")).toBeTrue()
  49. expect(supportsThemeMode(lightOnly, "dark")).toBeFalse()
  50. expect(selectThemeMode(lightOnly, "dark")).toEqual({ theme: light, mode: "light", expanded: false })
  51. expect(selectThemeMode(darkOnly, "light")).toEqual({ theme: dark, mode: "dark", expanded: false })
  52. })
  53. test("rejects a merge mode without its base mode", () => {
  54. expect(() => selectThemeMode({ version: 2, light: { mergeMode: true } })).toThrow(
  55. "light theme cannot merge without a dark theme",
  56. )
  57. expect(() => selectThemeMode({ version: 2, dark: { mergeMode: true } })).toThrow(
  58. "dark theme cannot merge without a light theme",
  59. )
  60. })
  61. test("rejects mutual mode merging", () => {
  62. const document = {
  63. version: 2,
  64. light: { mergeMode: true },
  65. dark: { mergeMode: true },
  66. } satisfies ThemeDocument
  67. expect(() => selectTheme(document)).toThrow("cannot both merge")
  68. })