prompt.test.ts 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. import { describe, it, expect } from "vitest";
  2. import { defineSchema, defineCatalog } from "@json-render/core";
  3. import { z } from "zod";
  4. import { yamlPrompt } from "./prompt";
  5. const testSchema = defineSchema(
  6. (s) => ({
  7. spec: s.object({
  8. root: s.string(),
  9. elements: s.record(
  10. s.object({
  11. type: s.ref("catalog.components"),
  12. props: s.propsOf("catalog.components"),
  13. children: s.array(s.string()),
  14. }),
  15. ),
  16. }),
  17. catalog: s.object({
  18. components: s.map({
  19. props: s.zod(),
  20. description: s.string(),
  21. }),
  22. actions: s.map({
  23. description: s.string(),
  24. }),
  25. }),
  26. }),
  27. {
  28. builtInActions: [{ name: "setState", description: "Set a state value" }],
  29. },
  30. );
  31. const testCatalog = defineCatalog(testSchema, {
  32. components: {
  33. Card: {
  34. props: z.object({ title: z.string() }),
  35. description: "A card container",
  36. },
  37. Text: {
  38. props: z.object({ content: z.string() }),
  39. description: "Display text",
  40. },
  41. },
  42. actions: {
  43. refresh: { description: "Refresh data" },
  44. },
  45. });
  46. describe("yamlPrompt", () => {
  47. it("generates a prompt string", () => {
  48. const prompt = yamlPrompt(testCatalog);
  49. expect(typeof prompt).toBe("string");
  50. expect(prompt.length).toBeGreaterThan(0);
  51. });
  52. it("includes YAML format instructions", () => {
  53. const prompt = yamlPrompt(testCatalog);
  54. expect(prompt).toContain("YAML");
  55. expect(prompt).toContain("yaml-spec");
  56. });
  57. it("includes component names from the catalog", () => {
  58. const prompt = yamlPrompt(testCatalog);
  59. expect(prompt).toContain("Card");
  60. expect(prompt).toContain("Text");
  61. });
  62. it("includes action names", () => {
  63. const prompt = yamlPrompt(testCatalog);
  64. expect(prompt).toContain("refresh");
  65. expect(prompt).toContain("setState");
  66. });
  67. it("includes yaml-edit instructions", () => {
  68. const prompt = yamlPrompt(testCatalog);
  69. expect(prompt).toContain("yaml-edit");
  70. expect(prompt).toContain("deep merge");
  71. });
  72. it("includes a YAML example", () => {
  73. const prompt = yamlPrompt(testCatalog);
  74. expect(prompt).toContain("root: main");
  75. expect(prompt).toContain("elements:");
  76. expect(prompt).toContain("type: Card");
  77. });
  78. it("respects mode: inline", () => {
  79. const prompt = yamlPrompt(testCatalog, { mode: "inline" });
  80. expect(prompt).toContain("respond conversationally");
  81. });
  82. it("respects mode: standalone", () => {
  83. const prompt = yamlPrompt(testCatalog, { mode: "standalone" });
  84. expect(prompt).toContain("Output ONLY");
  85. });
  86. it("appends custom rules", () => {
  87. const prompt = yamlPrompt(testCatalog, {
  88. customRules: ["Always use dark theme colors"],
  89. });
  90. expect(prompt).toContain("Always use dark theme colors");
  91. });
  92. it("uses custom system message", () => {
  93. const prompt = yamlPrompt(testCatalog, {
  94. system: "You are a dashboard builder.",
  95. });
  96. expect(prompt).toContain("You are a dashboard builder.");
  97. });
  98. });