Files
automaker/libs/prompts/tests/enhancement.test.ts
Kacper 0ce6b6d4b1 feat: Introduce @automaker/prompts package for AI prompt templates
Changes:
- Added a new package, @automaker/prompts, containing AI prompt templates for enhancing user-written task descriptions.
- Implemented four enhancement modes: improve, technical, simplify, and acceptance, each with corresponding system prompts and examples.
- Updated relevant packages to utilize the new prompts package, ensuring backward compatibility with existing imports.
- Enhanced documentation to include usage examples and integration details for the new prompts.

Benefits:
 Streamlined AI prompt management across the codebase
 Improved clarity and usability for AI-powered features
 Comprehensive documentation for developers

All tests passing.
2025-12-21 02:11:23 +01:00

527 lines
18 KiB
TypeScript

import { describe, it, expect } from "vitest";
import {
getEnhancementPrompt,
getSystemPrompt,
getExamples,
buildUserPrompt,
isValidEnhancementMode,
getAvailableEnhancementModes,
IMPROVE_SYSTEM_PROMPT,
TECHNICAL_SYSTEM_PROMPT,
SIMPLIFY_SYSTEM_PROMPT,
ACCEPTANCE_SYSTEM_PROMPT,
IMPROVE_EXAMPLES,
TECHNICAL_EXAMPLES,
SIMPLIFY_EXAMPLES,
ACCEPTANCE_EXAMPLES,
} from "../src/enhancement.js";
describe("enhancement.ts", () => {
describe("System Prompt Constants", () => {
it("should export IMPROVE_SYSTEM_PROMPT", () => {
expect(IMPROVE_SYSTEM_PROMPT).toBeDefined();
expect(typeof IMPROVE_SYSTEM_PROMPT).toBe("string");
expect(IMPROVE_SYSTEM_PROMPT).toContain("vague, unclear");
expect(IMPROVE_SYSTEM_PROMPT).toContain("actionable");
});
it("should export TECHNICAL_SYSTEM_PROMPT", () => {
expect(TECHNICAL_SYSTEM_PROMPT).toBeDefined();
expect(typeof TECHNICAL_SYSTEM_PROMPT).toBe("string");
expect(TECHNICAL_SYSTEM_PROMPT).toContain("technical");
expect(TECHNICAL_SYSTEM_PROMPT).toContain("implementation");
});
it("should export SIMPLIFY_SYSTEM_PROMPT", () => {
expect(SIMPLIFY_SYSTEM_PROMPT).toBeDefined();
expect(typeof SIMPLIFY_SYSTEM_PROMPT).toBe("string");
expect(SIMPLIFY_SYSTEM_PROMPT).toContain("verbose");
expect(SIMPLIFY_SYSTEM_PROMPT).toContain("concise");
});
it("should export ACCEPTANCE_SYSTEM_PROMPT", () => {
expect(ACCEPTANCE_SYSTEM_PROMPT).toBeDefined();
expect(typeof ACCEPTANCE_SYSTEM_PROMPT).toBe("string");
expect(ACCEPTANCE_SYSTEM_PROMPT).toContain("acceptance criteria");
expect(ACCEPTANCE_SYSTEM_PROMPT).toContain("testable");
});
});
describe("Examples Constants", () => {
it("should export IMPROVE_EXAMPLES with valid structure", () => {
expect(IMPROVE_EXAMPLES).toBeDefined();
expect(Array.isArray(IMPROVE_EXAMPLES)).toBe(true);
expect(IMPROVE_EXAMPLES.length).toBeGreaterThan(0);
IMPROVE_EXAMPLES.forEach((example) => {
expect(example).toHaveProperty("input");
expect(example).toHaveProperty("output");
expect(typeof example.input).toBe("string");
expect(typeof example.output).toBe("string");
});
});
it("should export TECHNICAL_EXAMPLES with valid structure", () => {
expect(TECHNICAL_EXAMPLES).toBeDefined();
expect(Array.isArray(TECHNICAL_EXAMPLES)).toBe(true);
expect(TECHNICAL_EXAMPLES.length).toBeGreaterThan(0);
TECHNICAL_EXAMPLES.forEach((example) => {
expect(example).toHaveProperty("input");
expect(example).toHaveProperty("output");
expect(typeof example.input).toBe("string");
expect(typeof example.output).toBe("string");
});
});
it("should export SIMPLIFY_EXAMPLES with valid structure", () => {
expect(SIMPLIFY_EXAMPLES).toBeDefined();
expect(Array.isArray(SIMPLIFY_EXAMPLES)).toBe(true);
expect(SIMPLIFY_EXAMPLES.length).toBeGreaterThan(0);
SIMPLIFY_EXAMPLES.forEach((example) => {
expect(example).toHaveProperty("input");
expect(example).toHaveProperty("output");
expect(typeof example.input).toBe("string");
expect(typeof example.output).toBe("string");
});
});
it("should export ACCEPTANCE_EXAMPLES with valid structure", () => {
expect(ACCEPTANCE_EXAMPLES).toBeDefined();
expect(Array.isArray(ACCEPTANCE_EXAMPLES)).toBe(true);
expect(ACCEPTANCE_EXAMPLES.length).toBeGreaterThan(0);
ACCEPTANCE_EXAMPLES.forEach((example) => {
expect(example).toHaveProperty("input");
expect(example).toHaveProperty("output");
expect(typeof example.input).toBe("string");
expect(typeof example.output).toBe("string");
});
});
it("should have shorter outputs in SIMPLIFY_EXAMPLES", () => {
SIMPLIFY_EXAMPLES.forEach((example) => {
// Simplify examples should have shorter output than input
// (though not always strictly enforced, it's the general pattern)
expect(example.output).toBeDefined();
expect(example.output.length).toBeGreaterThan(0);
});
});
});
describe("getEnhancementPrompt", () => {
it("should return prompt config for 'improve' mode", () => {
const result = getEnhancementPrompt("improve");
expect(result).toHaveProperty("systemPrompt");
expect(result).toHaveProperty("description");
expect(result.systemPrompt).toBe(IMPROVE_SYSTEM_PROMPT);
expect(result.description).toContain("vague");
expect(result.description).toContain("actionable");
});
it("should return prompt config for 'technical' mode", () => {
const result = getEnhancementPrompt("technical");
expect(result).toHaveProperty("systemPrompt");
expect(result).toHaveProperty("description");
expect(result.systemPrompt).toBe(TECHNICAL_SYSTEM_PROMPT);
expect(result.description).toContain("implementation");
});
it("should return prompt config for 'simplify' mode", () => {
const result = getEnhancementPrompt("simplify");
expect(result).toHaveProperty("systemPrompt");
expect(result).toHaveProperty("description");
expect(result.systemPrompt).toBe(SIMPLIFY_SYSTEM_PROMPT);
expect(result.description).toContain("verbose");
});
it("should return prompt config for 'acceptance' mode", () => {
const result = getEnhancementPrompt("acceptance");
expect(result).toHaveProperty("systemPrompt");
expect(result).toHaveProperty("description");
expect(result.systemPrompt).toBe(ACCEPTANCE_SYSTEM_PROMPT);
expect(result.description).toContain("acceptance");
});
it("should handle uppercase mode", () => {
const result = getEnhancementPrompt("IMPROVE");
expect(result.systemPrompt).toBe(IMPROVE_SYSTEM_PROMPT);
});
it("should handle mixed case mode", () => {
const result = getEnhancementPrompt("TeChnIcaL");
expect(result.systemPrompt).toBe(TECHNICAL_SYSTEM_PROMPT);
});
it("should fall back to 'improve' for invalid mode", () => {
const result = getEnhancementPrompt("invalid-mode");
expect(result.systemPrompt).toBe(IMPROVE_SYSTEM_PROMPT);
expect(result.description).toContain("vague");
});
it("should fall back to 'improve' for empty string", () => {
const result = getEnhancementPrompt("");
expect(result.systemPrompt).toBe(IMPROVE_SYSTEM_PROMPT);
});
});
describe("getSystemPrompt", () => {
it("should return IMPROVE_SYSTEM_PROMPT for 'improve'", () => {
const result = getSystemPrompt("improve");
expect(result).toBe(IMPROVE_SYSTEM_PROMPT);
});
it("should return TECHNICAL_SYSTEM_PROMPT for 'technical'", () => {
const result = getSystemPrompt("technical");
expect(result).toBe(TECHNICAL_SYSTEM_PROMPT);
});
it("should return SIMPLIFY_SYSTEM_PROMPT for 'simplify'", () => {
const result = getSystemPrompt("simplify");
expect(result).toBe(SIMPLIFY_SYSTEM_PROMPT);
});
it("should return ACCEPTANCE_SYSTEM_PROMPT for 'acceptance'", () => {
const result = getSystemPrompt("acceptance");
expect(result).toBe(ACCEPTANCE_SYSTEM_PROMPT);
});
});
describe("getExamples", () => {
it("should return IMPROVE_EXAMPLES for 'improve'", () => {
const result = getExamples("improve");
expect(result).toBe(IMPROVE_EXAMPLES);
expect(result.length).toBeGreaterThan(0);
});
it("should return TECHNICAL_EXAMPLES for 'technical'", () => {
const result = getExamples("technical");
expect(result).toBe(TECHNICAL_EXAMPLES);
expect(result.length).toBeGreaterThan(0);
});
it("should return SIMPLIFY_EXAMPLES for 'simplify'", () => {
const result = getExamples("simplify");
expect(result).toBe(SIMPLIFY_EXAMPLES);
expect(result.length).toBeGreaterThan(0);
});
it("should return ACCEPTANCE_EXAMPLES for 'acceptance'", () => {
const result = getExamples("acceptance");
expect(result).toBe(ACCEPTANCE_EXAMPLES);
expect(result.length).toBeGreaterThan(0);
});
});
describe("buildUserPrompt", () => {
const testText = "Add a login feature";
describe("with examples (default)", () => {
it("should include examples by default for 'improve' mode", () => {
const result = buildUserPrompt("improve", testText);
expect(result).toContain("Here are some examples");
expect(result).toContain("Example 1:");
expect(result).toContain(IMPROVE_EXAMPLES[0].input);
expect(result).toContain(IMPROVE_EXAMPLES[0].output);
expect(result).toContain(testText);
});
it("should include examples by default for 'technical' mode", () => {
const result = buildUserPrompt("technical", testText);
expect(result).toContain("Here are some examples");
expect(result).toContain("Example 1:");
expect(result).toContain(TECHNICAL_EXAMPLES[0].input);
expect(result).toContain(testText);
});
it("should include examples when explicitly set to true", () => {
const result = buildUserPrompt("improve", testText, true);
expect(result).toContain("Here are some examples");
expect(result).toContain(testText);
});
it("should format all examples with numbered labels", () => {
const result = buildUserPrompt("improve", testText);
IMPROVE_EXAMPLES.forEach((_, index) => {
expect(result).toContain(`Example ${index + 1}:`);
});
});
it("should separate examples with dividers", () => {
const result = buildUserPrompt("improve", testText);
// Count dividers (---) - should be (examples.length) + 1
const dividerCount = (result.match(/---/g) || []).length;
expect(dividerCount).toBe(IMPROVE_EXAMPLES.length);
});
it("should include 'Now, please enhance' before user text", () => {
const result = buildUserPrompt("improve", testText);
expect(result).toContain("Now, please enhance the following");
expect(result).toContain(testText);
});
});
describe("without examples", () => {
it("should not include examples when includeExamples is false", () => {
const result = buildUserPrompt("improve", testText, false);
expect(result).not.toContain("Here are some examples");
expect(result).not.toContain("Example 1:");
expect(result).not.toContain(IMPROVE_EXAMPLES[0].input);
});
it("should have simple prompt without examples", () => {
const result = buildUserPrompt("improve", testText, false);
expect(result).toBe(
`Please enhance the following task description:\n\n${testText}`
);
});
it("should preserve user text without examples", () => {
const result = buildUserPrompt("technical", testText, false);
expect(result).toContain(testText);
expect(result).toContain("Please enhance");
});
});
describe("text formatting", () => {
it("should preserve multiline text", () => {
const multilineText = "Line 1\nLine 2\nLine 3";
const result = buildUserPrompt("improve", multilineText);
expect(result).toContain(multilineText);
});
it("should handle empty text", () => {
const result = buildUserPrompt("improve", "");
// With examples by default, it should contain "Now, please enhance"
expect(result).toContain("Now, please enhance");
expect(result).toContain("Here are some examples");
});
it("should handle whitespace-only text", () => {
const result = buildUserPrompt("improve", " ");
expect(result).toContain(" ");
});
it("should handle special characters in text", () => {
const specialText = "Test <html> & \"quotes\" 'apostrophes'";
const result = buildUserPrompt("improve", specialText);
expect(result).toContain(specialText);
});
});
describe("all modes", () => {
it("should work for all valid enhancement modes", () => {
const modes: Array<"improve" | "technical" | "simplify" | "acceptance"> =
["improve", "technical", "simplify", "acceptance"];
modes.forEach((mode) => {
const result = buildUserPrompt(mode, testText);
expect(result).toBeDefined();
expect(result).toContain(testText);
expect(result.length).toBeGreaterThan(testText.length);
});
});
});
});
describe("isValidEnhancementMode", () => {
it("should return true for 'improve'", () => {
expect(isValidEnhancementMode("improve")).toBe(true);
});
it("should return true for 'technical'", () => {
expect(isValidEnhancementMode("technical")).toBe(true);
});
it("should return true for 'simplify'", () => {
expect(isValidEnhancementMode("simplify")).toBe(true);
});
it("should return true for 'acceptance'", () => {
expect(isValidEnhancementMode("acceptance")).toBe(true);
});
it("should return false for invalid mode", () => {
expect(isValidEnhancementMode("invalid")).toBe(false);
});
it("should return false for empty string", () => {
expect(isValidEnhancementMode("")).toBe(false);
});
it("should return false for uppercase mode", () => {
// Should be case-sensitive since we check object keys directly
expect(isValidEnhancementMode("IMPROVE")).toBe(false);
});
it("should return false for mixed case mode", () => {
expect(isValidEnhancementMode("ImProve")).toBe(false);
});
it("should return false for partial mode names", () => {
expect(isValidEnhancementMode("impro")).toBe(false);
expect(isValidEnhancementMode("tech")).toBe(false);
});
it("should return false for mode with extra characters", () => {
expect(isValidEnhancementMode("improve ")).toBe(false);
expect(isValidEnhancementMode(" improve")).toBe(false);
});
});
describe("getAvailableEnhancementModes", () => {
it("should return array of all enhancement modes", () => {
const modes = getAvailableEnhancementModes();
expect(Array.isArray(modes)).toBe(true);
expect(modes.length).toBe(4);
});
it("should include all valid modes", () => {
const modes = getAvailableEnhancementModes();
expect(modes).toContain("improve");
expect(modes).toContain("technical");
expect(modes).toContain("simplify");
expect(modes).toContain("acceptance");
});
it("should return modes in consistent order", () => {
const modes1 = getAvailableEnhancementModes();
const modes2 = getAvailableEnhancementModes();
expect(modes1).toEqual(modes2);
});
it("should return all valid modes that pass isValidEnhancementMode", () => {
const modes = getAvailableEnhancementModes();
modes.forEach((mode) => {
expect(isValidEnhancementMode(mode)).toBe(true);
});
});
});
describe("Integration tests", () => {
it("should work together: getEnhancementPrompt + buildUserPrompt", () => {
const mode = "improve";
const text = "Add search feature";
const { systemPrompt, description } = getEnhancementPrompt(mode);
const userPrompt = buildUserPrompt(mode, text);
expect(systemPrompt).toBe(IMPROVE_SYSTEM_PROMPT);
expect(description).toBeDefined();
expect(userPrompt).toContain(text);
});
it("should handle complete enhancement workflow", () => {
const availableModes = getAvailableEnhancementModes();
expect(availableModes.length).toBeGreaterThan(0);
availableModes.forEach((mode) => {
const isValid = isValidEnhancementMode(mode);
expect(isValid).toBe(true);
const systemPrompt = getSystemPrompt(mode);
expect(systemPrompt).toBeDefined();
expect(systemPrompt.length).toBeGreaterThan(0);
const examples = getExamples(mode);
expect(Array.isArray(examples)).toBe(true);
expect(examples.length).toBeGreaterThan(0);
const userPrompt = buildUserPrompt(mode, "test description");
expect(userPrompt).toContain("test description");
});
});
it("should provide consistent data across functions", () => {
const mode = "technical";
const promptConfig = getEnhancementPrompt(mode);
const systemPrompt = getSystemPrompt(mode);
const examples = getExamples(mode);
expect(promptConfig.systemPrompt).toBe(systemPrompt);
expect(examples).toBe(TECHNICAL_EXAMPLES);
});
});
describe("Examples content validation", () => {
it("IMPROVE_EXAMPLES should demonstrate improvement", () => {
IMPROVE_EXAMPLES.forEach((example) => {
// Output should be longer and more detailed than input
expect(example.output.length).toBeGreaterThan(example.input.length);
// Input should be brief/vague
expect(example.input.length).toBeLessThan(100);
});
});
it("TECHNICAL_EXAMPLES should contain technical terms", () => {
const technicalTerms = [
"API",
"endpoint",
"component",
"database",
"frontend",
"backend",
"validation",
"schema",
"React",
"GET",
"PUT",
"POST",
];
TECHNICAL_EXAMPLES.forEach((example) => {
const hasAnyTechnicalTerm = technicalTerms.some((term) =>
example.output.includes(term)
);
expect(hasAnyTechnicalTerm).toBe(true);
});
});
it("ACCEPTANCE_EXAMPLES should contain acceptance criteria format", () => {
ACCEPTANCE_EXAMPLES.forEach((example) => {
// Should contain numbered criteria or Given-When-Then format
const hasAcceptanceCriteria =
example.output.includes("Acceptance Criteria") ||
example.output.match(/\d+\./g);
expect(hasAcceptanceCriteria).toBeTruthy();
// Should contain Given-When-Then format
const hasGWT =
example.output.includes("Given") &&
example.output.includes("when") &&
example.output.includes("then");
expect(hasGWT).toBe(true);
});
});
});
});