mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-01-31 06:42:03 +00:00
Resolves merge conflicts: - apps/server/src/routes/terminal/common.ts: Keep randomBytes import, use @automaker/utils for createLogger - apps/ui/eslint.config.mjs: Use main's explicit globals list with XMLHttpRequest and MediaQueryListEvent additions - apps/ui/src/components/views/terminal-view.tsx: Keep our terminal improvements (killAllSessions, beforeunload, better error handling) - apps/ui/src/config/terminal-themes.ts: Keep our search highlight colors for all themes - apps/ui/src/store/app-store.ts: Keep our terminal settings persistence improvements (merge function) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
526 lines
18 KiB
TypeScript
526 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);
|
|
});
|
|
});
|
|
});
|
|
});
|