sync-settings-keys-script.test.ts 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import fs from "node:fs";
  2. import path from "node:path";
  3. import { describe, expect, test } from "vitest";
  4. import sync from "../../../scripts/sync-settings-keys.js";
  5. describe("scripts/sync-settings-keys.js", () => {
  6. test("flatten() flattens nested objects into dot-keys", () => {
  7. const input = { a: { b: 1, c: { d: "x" } }, e: true };
  8. const out = sync.flatten(input);
  9. expect(out).toEqual({ "a.b": 1, "a.c.d": "x", e: true });
  10. });
  11. test("mergeWithCanonical() keeps canonical shape and preserves existing leaves", () => {
  12. const canonical = {
  13. a: { b: "cn", c: { d: "cn" } },
  14. x: "cn",
  15. };
  16. const target = {
  17. a: { b: "t", c: "wrong-type" },
  18. x: { y: "wrong-type" },
  19. extra: "should-drop",
  20. };
  21. const merged = sync.mergeWithCanonical(canonical, target);
  22. expect(merged).toEqual({
  23. a: { b: "t", c: { d: "cn" } },
  24. x: "cn",
  25. });
  26. });
  27. test("loadSplitSettings() reads split settings layout for zh-CN", () => {
  28. const settings = sync.loadSplitSettings("zh-CN");
  29. expect(settings).toBeTruthy();
  30. expect(settings).toHaveProperty("providers");
  31. expect(settings).toHaveProperty("mcpPassthroughConfig");
  32. });
  33. test("ensureSettings() can generate split files from canonical", () => {
  34. const tmpRoot = path.join(
  35. process.cwd(),
  36. "tests",
  37. ".tmp-sync-settings-keys",
  38. String(Date.now())
  39. );
  40. const messagesDir = path.join(tmpRoot, "messages");
  41. const writeJson = (p: string, data: unknown) => {
  42. fs.mkdirSync(path.dirname(p), { recursive: true });
  43. fs.writeFileSync(p, `${JSON.stringify(data, null, 2)}\n`, "utf8");
  44. };
  45. try {
  46. // canonical (zh-CN)
  47. writeJson(path.join(messagesDir, "zh-CN", "settings", "a.json"), { k: "cn" });
  48. writeJson(path.join(messagesDir, "zh-CN", "settings", "strings.json"), { s: "cn" });
  49. writeJson(path.join(messagesDir, "zh-CN", "settings", "providers", "strings.json"), {
  50. title: "cn",
  51. });
  52. writeJson(path.join(messagesDir, "zh-CN", "settings", "providers", "form", "apiTest.json"), {
  53. enabled: "cn",
  54. });
  55. writeJson(path.join(messagesDir, "zh-CN", "settings", "providers", "form", "strings.json"), {
  56. x: "cn",
  57. });
  58. const report = sync.ensureSettings("en", messagesDir);
  59. expect(report.after.missing).toBe(0);
  60. expect(report.after.extra).toBe(0);
  61. const enA = JSON.parse(
  62. fs.readFileSync(path.join(messagesDir, "en", "settings", "a.json"), "utf8")
  63. );
  64. expect(enA).toEqual({ k: "cn" });
  65. const enStrings = JSON.parse(
  66. fs.readFileSync(path.join(messagesDir, "en", "settings", "strings.json"), "utf8")
  67. );
  68. expect(enStrings).toEqual({ s: "cn" });
  69. const enFormApiTest = JSON.parse(
  70. fs.readFileSync(
  71. path.join(messagesDir, "en", "settings", "providers", "form", "apiTest.json"),
  72. "utf8"
  73. )
  74. );
  75. expect(enFormApiTest).toEqual({ enabled: "cn" });
  76. } finally {
  77. fs.rmSync(tmpRoot, { recursive: true, force: true });
  78. }
  79. });
  80. test("ensureSettings() supports legacy settings.json layout", () => {
  81. const tmpRoot = path.join(
  82. process.cwd(),
  83. "tests",
  84. ".tmp-sync-settings-keys",
  85. `legacy-${Date.now()}`
  86. );
  87. const messagesDir = path.join(tmpRoot, "messages");
  88. const writeJson = (p: string, data: unknown) => {
  89. fs.mkdirSync(path.dirname(p), { recursive: true });
  90. fs.writeFileSync(p, `${JSON.stringify(data, null, 2)}\n`, "utf8");
  91. };
  92. try {
  93. writeJson(path.join(messagesDir, "zh-CN", "settings.json"), {
  94. a: { b: "cn" },
  95. x: "cn",
  96. });
  97. writeJson(path.join(messagesDir, "en", "settings.json"), {
  98. a: { b: "en" },
  99. x: { y: "wrong-type" },
  100. extra: "drop",
  101. });
  102. const report = sync.ensureSettings("en", messagesDir);
  103. expect(report.after.missing).toBe(0);
  104. expect(report.after.extra).toBe(0);
  105. const out = JSON.parse(
  106. fs.readFileSync(path.join(messagesDir, "en", "settings.json"), "utf8")
  107. );
  108. expect(out).toEqual({ a: { b: "en" }, x: "cn" });
  109. } finally {
  110. fs.rmSync(tmpRoot, { recursive: true, force: true });
  111. }
  112. });
  113. });