Skip to main content
Glama
generators.test.ts15.3 kB
/** * Unit tests for template generators * * Tests renderTemplate(), generateClaudeMd(), generateMcpJson() */ import { describe, it, expect } from 'vitest'; import { renderTemplate, generateClaudeMd, generateAgentsMd, generateGeminiMd, generateMcpJson, getDefaultClaudeMdContext, type ClaudeMdContext, } from './generators.js'; describe('generators', () => { describe('renderTemplate', () => { it('replaces simple variables', () => { const result = renderTemplate('Hello {{name}}!', { name: 'World' }); expect(result).toBe('Hello World!'); }); it('replaces multiple variables', () => { const result = renderTemplate('{{greeting}} {{name}}!', { greeting: 'Hello', name: 'World', }); expect(result).toBe('Hello World!'); }); it('handles missing variables as empty string', () => { const result = renderTemplate('Hello {{name}}!', {}); expect(result).toBe('Hello !'); }); it('handles null values as empty string', () => { const result = renderTemplate('Hello {{name}}!', { name: null }); expect(result).toBe('Hello !'); }); it('handles undefined values as empty string', () => { const result = renderTemplate('Hello {{name}}!', { name: undefined }); expect(result).toBe('Hello !'); }); it('converts non-string values to string', () => { const result = renderTemplate('Count: {{count}}', { count: 42 }); expect(result).toBe('Count: 42'); }); it('handles if blocks - truthy value', () => { const template = '{{#if show}}Visible{{/if}}'; expect(renderTemplate(template, { show: true })).toBe('Visible'); }); it('handles if blocks - falsy value (false)', () => { const template = '{{#if show}}Visible{{/if}}'; expect(renderTemplate(template, { show: false })).toBe(''); }); it('handles if blocks - falsy value (empty string)', () => { const template = '{{#if show}}Visible{{/if}}'; expect(renderTemplate(template, { show: '' })).toBe(''); }); it('handles if blocks - falsy value (undefined)', () => { const template = '{{#if show}}Visible{{/if}}'; expect(renderTemplate(template, {})).toBe(''); }); it('handles if blocks with variables inside', () => { const template = '{{#if site_name}}**Site**: {{site_name}}\n{{/if}}'; const result = renderTemplate(template, { site_name: 'My Site' }); expect(result).toBe('**Site**: My Site\n'); }); it('handles multiple if blocks', () => { const template = '{{#if a}}A{{/if}}{{#if b}}B{{/if}}'; expect(renderTemplate(template, { a: true, b: false })).toBe('A'); expect(renderTemplate(template, { a: false, b: true })).toBe('B'); expect(renderTemplate(template, { a: true, b: true })).toBe('AB'); }); it('handles multiline content in if blocks', () => { const template = `{{#if show}}Line 1 Line 2 Line 3{{/if}}`; const result = renderTemplate(template, { show: true }); expect(result).toBe('Line 1\nLine 2\nLine 3'); }); }); describe('generateClaudeMd', () => { it('generates markdown with all fields', () => { const context: ClaudeMdContext = { site_name: 'Test Site', site_url: 'https://test.com', environment: 'production', generated_date: '2024-01-15', mcp_version: '2.1.0', }; const content = generateClaudeMd(context); expect(content).toContain('# CLAUDE.md - WP Navigator Project'); expect(content).toContain('**Site**: Test Site'); expect(content).toContain('**URL**: https://test.com'); expect(content).toContain('**Environment**: production'); expect(content).toContain('**Generated**: 2024-01-15'); expect(content).toContain('*Generated by WP Navigator v2.1.0*'); }); it('omits site_name when not provided', () => { const context: ClaudeMdContext = { environment: 'local', generated_date: '2024-01-15', mcp_version: '2.1.0', }; const content = generateClaudeMd(context); expect(content).not.toContain('**Site**:'); expect(content).toContain('**Environment**: local'); }); it('omits site_url when not provided', () => { const context: ClaudeMdContext = { site_name: 'Test', environment: 'local', generated_date: '2024-01-15', mcp_version: '2.1.0', }; const content = generateClaudeMd(context); expect(content).not.toContain('**URL**:'); }); it('includes all required sections', () => { const context = getDefaultClaudeMdContext(); const content = generateClaudeMd(context); // Check for required sections expect(content).toContain('## Overview'); expect(content).toContain('## Safety Defaults'); expect(content).toContain('## Available CLI Commands'); expect(content).toContain('## MCP Tool Categories'); expect(content).toContain('## Common Workflows'); expect(content).toContain('## Troubleshooting'); }); it('includes all 13 tool categories', () => { const context = getDefaultClaudeMdContext(); const content = generateClaudeMd(context); const expectedCategories = [ 'Core', 'Pages', 'Posts', 'Media', 'Comments', 'Categories', 'Tags', 'Taxonomies', 'Users', 'Plugins', 'Themes', 'Gutenberg', 'Testing', ]; for (const category of expectedCategories) { expect(content).toContain(`| ${category} |`); } }); }); describe('generateAgentsMd', () => { it('generates markdown with all fields', () => { const context: ClaudeMdContext = { site_name: 'Test Site', site_url: 'https://test.com', environment: 'production', generated_date: '2024-01-15', mcp_version: '2.3.0', }; const content = generateAgentsMd(context); expect(content).toContain('# AGENTS.md - WP Navigator Project'); expect(content).toContain('**Site**: Test Site'); expect(content).toContain('**URL**: https://test.com'); expect(content).toContain('**Environment**: production'); expect(content).toContain('**Generated**: 2024-01-15'); expect(content).toContain('*Generated by WP Navigator v2.3.0*'); }); it('omits site_name when not provided', () => { const context: ClaudeMdContext = { environment: 'local', generated_date: '2024-01-15', mcp_version: '2.3.0', }; const content = generateAgentsMd(context); expect(content).not.toContain('**Site**:'); expect(content).toContain('**Environment**: local'); }); it('omits site_url when not provided', () => { const context: ClaudeMdContext = { site_name: 'Test', environment: 'local', generated_date: '2024-01-15', mcp_version: '2.3.0', }; const content = generateAgentsMd(context); expect(content).not.toContain('**URL**:'); }); it('includes all required sections', () => { const context = getDefaultClaudeMdContext(); const content = generateAgentsMd(context); // Check for required sections expect(content).toContain('## Overview'); expect(content).toContain('## Safety Defaults'); expect(content).toContain('## Available CLI Commands'); expect(content).toContain('## MCP Tool Categories'); expect(content).toContain('## Common Workflows'); expect(content).toContain('## Troubleshooting'); }); it('includes Codex-specific sections', () => { const context = getDefaultClaudeMdContext(); const content = generateAgentsMd(context); // Check for Codex-specific sections expect(content).toContain('## Codex Integration'); expect(content).toContain('### MCP Server Configuration'); expect(content).toContain('config.toml'); expect(content).toContain('[mcp_servers.wpnav]'); }); it('includes Codex tool invocation examples', () => { const context = getDefaultClaudeMdContext(); const content = generateAgentsMd(context); expect(content).toContain('### Using WP Navigator Tools'); expect(content).toContain('wpnav_list_pages'); expect(content).toContain('wpnav_get_site_overview'); }); it('includes all 13 tool categories', () => { const context = getDefaultClaudeMdContext(); const content = generateAgentsMd(context); const expectedCategories = [ 'Core', 'Pages', 'Posts', 'Media', 'Comments', 'Categories', 'Tags', 'Taxonomies', 'Users', 'Plugins', 'Themes', 'Gutenberg', 'Testing', ]; for (const category of expectedCategories) { expect(content).toContain(`| ${category} |`); } }); it('references .codex/ directory in project files', () => { const context = getDefaultClaudeMdContext(); const content = generateAgentsMd(context); expect(content).toContain('.codex/'); expect(content).toContain('AGENTS.md'); }); }); describe('generateGeminiMd', () => { it('generates markdown with all fields', () => { const context: ClaudeMdContext = { site_name: 'Test Site', site_url: 'https://test.com', environment: 'production', generated_date: '2024-01-15', mcp_version: '2.3.0', }; const content = generateGeminiMd(context); expect(content).toContain('# GEMINI.md - WP Navigator Project'); expect(content).toContain('**Site**: Test Site'); expect(content).toContain('**URL**: https://test.com'); expect(content).toContain('**Environment**: production'); expect(content).toContain('**Generated**: 2024-01-15'); expect(content).toContain('*Generated by WP Navigator v2.3.0*'); }); it('omits site_name when not provided', () => { const context: ClaudeMdContext = { environment: 'local', generated_date: '2024-01-15', mcp_version: '2.3.0', }; const content = generateGeminiMd(context); expect(content).not.toContain('**Site**:'); expect(content).toContain('**Environment**: local'); }); it('omits site_url when not provided', () => { const context: ClaudeMdContext = { site_name: 'Test', environment: 'local', generated_date: '2024-01-15', mcp_version: '2.3.0', }; const content = generateGeminiMd(context); expect(content).not.toContain('**URL**:'); }); it('includes all required sections', () => { const context = getDefaultClaudeMdContext(); const content = generateGeminiMd(context); // Check for required sections expect(content).toContain('## Overview'); expect(content).toContain('## Quick Start'); expect(content).toContain('## Safety Defaults'); expect(content).toContain('## Available CLI Commands'); expect(content).toContain('## MCP Tool Categories'); expect(content).toContain('## Common Workflows'); expect(content).toContain('## Troubleshooting'); }); it('includes Gemini-specific sections', () => { const context = getDefaultClaudeMdContext(); const content = generateGeminiMd(context); // Check for Gemini-specific sections expect(content).toContain('## Gemini Integration'); expect(content).toContain('### MCP Server Configuration'); expect(content).toContain('settings.json'); expect(content).toContain('"mcpServers"'); }); it('includes Gemini tool invocation examples', () => { const context = getDefaultClaudeMdContext(); const content = generateGeminiMd(context); expect(content).toContain('### Using WP Navigator Tools'); expect(content).toContain('wpnav_list_pages'); expect(content).toContain('wpnav_get_site_overview'); }); it('includes all 13 tool categories', () => { const context = getDefaultClaudeMdContext(); const content = generateGeminiMd(context); const expectedCategories = [ 'Core', 'Pages', 'Posts', 'Media', 'Comments', 'Categories', 'Tags', 'Taxonomies', 'Users', 'Plugins', 'Themes', 'Gutenberg', 'Testing', ]; for (const category of expectedCategories) { expect(content).toContain(`| ${category} |`); } }); it('references .gemini/ directory in project files', () => { const context = getDefaultClaudeMdContext(); const content = generateGeminiMd(context); expect(content).toContain('.gemini/'); expect(content).toContain('GEMINI.md'); }); }); describe('getDefaultClaudeMdContext', () => { it('returns context with default values', () => { const context = getDefaultClaudeMdContext(); expect(context.environment).toBe('local'); expect(context.generated_date).toMatch(/^\d{4}-\d{2}-\d{2}$/); expect(context.mcp_version).toBeDefined(); }); it('allows overriding default values', () => { const context = getDefaultClaudeMdContext({ site_name: 'Custom Site', environment: 'production', }); expect(context.site_name).toBe('Custom Site'); expect(context.environment).toBe('production'); expect(context.generated_date).toMatch(/^\d{4}-\d{2}-\d{2}$/); }); }); describe('generateMcpJson', () => { it('generates valid JSON with defaults', () => { const content = generateMcpJson(); const parsed = JSON.parse(content); expect(parsed.mcpServers).toBeDefined(); expect(parsed.mcpServers.wpnav).toBeDefined(); expect(parsed.mcpServers.wpnav.command).toBe('npx'); expect(parsed.mcpServers.wpnav.args).toContain('-y'); expect(parsed.mcpServers.wpnav.args).toContain('@littlebearapps/wp-navigator-mcp'); expect(parsed.mcpServers.wpnav.args).toContain('./wpnav.config.json'); }); it('respects enableWrites option', () => { const withWrites = JSON.parse(generateMcpJson({ enableWrites: true })); const withoutWrites = JSON.parse(generateMcpJson({ enableWrites: false })); expect(withWrites.mcpServers.wpnav.env.WPNAV_ENABLE_WRITES).toBe('1'); expect(withoutWrites.mcpServers.wpnav.env.WPNAV_ENABLE_WRITES).toBe('0'); }); it('defaults enableWrites to false', () => { const parsed = JSON.parse(generateMcpJson()); expect(parsed.mcpServers.wpnav.env.WPNAV_ENABLE_WRITES).toBe('0'); }); it('respects custom configPath', () => { const content = generateMcpJson({ configPath: './custom-config.json' }); const parsed = JSON.parse(content); expect(parsed.mcpServers.wpnav.args).toContain('./custom-config.json'); expect(parsed.mcpServers.wpnav.args).not.toContain('./wpnav.config.json'); }); it('generates properly formatted JSON', () => { const content = generateMcpJson(); // Check it's properly indented (2 spaces) expect(content).toContain(' "mcpServers"'); expect(content).toContain(' "wpnav"'); }); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/littlebearapps/wp-navigator-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server