technical-writer-prompts.test.ts•7.4 kB
import {
generateTechnicalWriterPrompts,
analyzeProjectContext,
} from '../../src/prompts/technical-writer-prompts.js';
import { promises as fs } from 'fs';
import { join } from 'path';
import { tmpdir } from 'os';
describe('Technical Writer Diataxis Prompts', () => {
let testProjectPath: string;
beforeEach(async () => {
// Create a temporary test project
testProjectPath = join(tmpdir(), `test-project-${Date.now()}`);
await fs.mkdir(testProjectPath, { recursive: true });
// Create a basic package.json
const packageJson = {
name: 'test-project',
version: '1.0.0',
dependencies: {
react: '^18.0.0',
typescript: '^5.0.0',
},
scripts: {
test: 'jest',
},
};
await fs.writeFile(join(testProjectPath, 'package.json'), JSON.stringify(packageJson, null, 2));
// Create a basic README.md
await fs.writeFile(
join(testProjectPath, 'README.md'),
'# Test Project\n\nA test project for testing.',
);
// Create a test directory
await fs.mkdir(join(testProjectPath, 'tests'), { recursive: true });
await fs.writeFile(
join(testProjectPath, 'tests', 'example.test.js'),
'test("example", () => { expect(true).toBe(true); });',
);
// Create a CI file
await fs.mkdir(join(testProjectPath, '.github', 'workflows'), { recursive: true });
await fs.writeFile(
join(testProjectPath, '.github', 'workflows', 'ci.yml'),
'name: CI\non: [push, pull_request]',
);
});
afterEach(async () => {
// Clean up test project
try {
await fs.rm(testProjectPath, { recursive: true, force: true });
} catch (error) {
// Ignore cleanup errors
}
});
describe('generateTechnicalWriterPrompts', () => {
it('should generate tutorial writer prompts', async () => {
const prompts = await generateTechnicalWriterPrompts('tutorial-writer', testProjectPath);
expect(prompts.length).toBeGreaterThan(0);
expect(prompts[0]).toHaveProperty('role');
expect(prompts[0]).toHaveProperty('content');
expect(prompts[0].content).toHaveProperty('type', 'text');
expect(prompts[0].content).toHaveProperty('text');
expect(prompts[0].content.text).toContain('tutorial');
expect(prompts[0].content.text).toContain('Diataxis');
});
it('should generate how-to guide writer prompts', async () => {
const prompts = await generateTechnicalWriterPrompts('howto-guide-writer', testProjectPath);
expect(prompts.length).toBeGreaterThan(0);
expect(prompts[0].content.text).toContain('how-to guide');
expect(prompts[0].content.text).toContain('Problem-oriented');
});
it('should generate reference writer prompts', async () => {
const prompts = await generateTechnicalWriterPrompts('reference-writer', testProjectPath);
expect(prompts.length).toBeGreaterThan(0);
expect(prompts[0].content.text).toContain('reference documentation');
expect(prompts[0].content.text).toContain('Information-oriented');
});
it('should generate explanation writer prompts', async () => {
const prompts = await generateTechnicalWriterPrompts('explanation-writer', testProjectPath);
expect(prompts.length).toBeGreaterThan(0);
expect(prompts[0].content.text).toContain('explanation documentation');
expect(prompts[0].content.text).toContain('Understanding-oriented');
});
it('should generate diataxis organizer prompts', async () => {
const prompts = await generateTechnicalWriterPrompts('diataxis-organizer', testProjectPath);
expect(prompts.length).toBeGreaterThan(0);
expect(prompts[0].content.text).toContain('Diataxis framework');
expect(prompts[0].content.text).toContain('organize');
});
it('should generate readme optimizer prompts', async () => {
const prompts = await generateTechnicalWriterPrompts('readme-optimizer', testProjectPath);
expect(prompts.length).toBeGreaterThan(0);
expect(prompts[0].content.text).toContain('README');
expect(prompts[0].content.text).toContain('Diataxis-aware');
});
it('should throw error for unknown prompt type', async () => {
await expect(generateTechnicalWriterPrompts('unknown-type', testProjectPath)).rejects.toThrow(
'Unknown prompt type: unknown-type',
);
});
it('should include project context in prompts', async () => {
const prompts = await generateTechnicalWriterPrompts('tutorial-writer', testProjectPath);
const promptText = prompts[0].content.text;
expect(promptText).toContain('React'); // Should detect React from package.json
expect(promptText).toContain('TypeScript'); // Should detect TypeScript
});
});
describe('analyzeProjectContext', () => {
it('should analyze project context correctly', async () => {
const context = await analyzeProjectContext(testProjectPath);
expect(context).toHaveProperty('projectType');
expect(context).toHaveProperty('languages');
expect(context).toHaveProperty('frameworks');
expect(context).toHaveProperty('hasTests');
expect(context).toHaveProperty('hasCI');
expect(context).toHaveProperty('readmeExists');
expect(context).toHaveProperty('documentationGaps');
// Check specific values based on our test setup
expect(context.projectType).toBe('node_application');
expect(context.languages).toContain('TypeScript');
expect(context.frameworks).toContain('React');
expect(context.hasTests).toBe(true);
expect(context.hasCI).toBe(true);
expect(context.readmeExists).toBe(true);
expect(context.packageManager).toBe('npm');
});
it('should detect documentation gaps', async () => {
const context = await analyzeProjectContext(testProjectPath);
expect(Array.isArray(context.documentationGaps)).toBe(true);
// Should detect missing documentation since we only have a basic README
expect(context.documentationGaps.length).toBeGreaterThan(0);
});
it('should handle projects without package.json', async () => {
// Create a project without package.json
const simpleProjectPath = join(tmpdir(), `simple-project-${Date.now()}`);
await fs.mkdir(simpleProjectPath, { recursive: true });
try {
const context = await analyzeProjectContext(simpleProjectPath);
expect(context.projectType).toBe('unknown');
expect(context.languages).toEqual([]);
expect(context.frameworks).toEqual([]);
expect(context.readmeExists).toBe(false);
} finally {
await fs.rm(simpleProjectPath, { recursive: true, force: true });
}
});
it('should detect yarn package manager', async () => {
// Create yarn.lock to simulate yarn project
await fs.writeFile(join(testProjectPath, 'yarn.lock'), '# Yarn lockfile');
const context = await analyzeProjectContext(testProjectPath);
expect(context.packageManager).toBe('yarn');
});
it('should detect pnpm package manager', async () => {
// Create pnpm-lock.yaml to simulate pnpm project
await fs.writeFile(join(testProjectPath, 'pnpm-lock.yaml'), 'lockfileVersion: 5.4');
const context = await analyzeProjectContext(testProjectPath);
expect(context.packageManager).toBe('pnpm');
});
});
});