Skip to main content
Glama

DollhouseMCP

by DollhouseMCP
template-rendering-proof.test.tsโ€ข9.36 kB
/** * Template Rendering Integration Test * * PROOF OF FIX: This test demonstrates that the template rendering * actually works end-to-end with variable substitution. */ import { TemplateManager } from '../../../src/elements/templates/TemplateManager.js'; import { TemplateRenderer } from '../../../src/utils/TemplateRenderer.js'; import { Template } from '../../../src/elements/templates/Template.js'; import * as fs from 'fs/promises'; import * as path from 'path'; import * as os from 'os'; describe('Template Rendering - PROOF OF FIX', () => { let tempDir: string; let templateManager: TemplateManager; let renderer: TemplateRenderer; beforeEach(async () => { // Create temporary directory for test templates tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'template-test-')); process.env.DOLLHOUSE_PORTFOLIO_DIR = tempDir; // Create templates directory const templatesDir = path.join(tempDir, 'templates'); await fs.mkdir(templatesDir, { recursive: true }); // Initialize managers templateManager = new TemplateManager(); renderer = new TemplateRenderer(templateManager); }); afterEach(async () => { // Clean up temp directory if (tempDir) { await fs.rm(tempDir, { recursive: true, force: true }); } }); describe('PROOF: Variable Substitution Works', () => { it('should substitute variables in a simple template', async () => { // Create a test template file const templateContent = `--- name: greeting description: A simple greeting template variables: - name: username type: string required: true - name: location type: string required: true --- Hello {{username}}, welcome to {{location}}!`; await fs.writeFile( path.join(tempDir, 'templates', 'greeting.md'), templateContent ); // Render the template const result = await renderer.render('greeting', { username: 'Alice', location: 'Wonderland' }); // VERIFICATION: Variables ARE substituted console.log('โœ… PROOF OF FIX - Rendered content:', result.content); expect(result.success).toBe(true); expect(result.content).toBe('Hello Alice, welcome to Wonderland!'); expect(result.content).not.toContain('{{'); expect(result.content).not.toContain('}}'); }); it('should substitute multiple variables in complex template', async () => { // Create a complex template const templateContent = `--- name: report description: A report template variables: - name: title type: string required: true - name: date type: string required: true - name: author type: string required: true - name: summary type: string required: true --- # {{title}} **Date:** {{date}} **Author:** {{author}} ## Executive Summary {{summary}} --- Generated on {{date}} by {{author}}`; await fs.writeFile( path.join(tempDir, 'templates', 'report.md'), templateContent ); // Render the template const result = await renderer.render('report', { title: 'Q3 2025 Performance Report', date: '2025-09-10', author: 'John Doe', summary: 'Excellent progress across all metrics.' }); // VERIFICATION: All variables are substituted console.log('โœ… PROOF OF FIX - Complex template rendered:', result.content); expect(result.success).toBe(true); expect(result.content).toContain('# Q3 2025 Performance Report'); expect(result.content).toContain('**Date:** 2025-09-10'); expect(result.content).toContain('**Author:** John Doe'); expect(result.content).toContain('Excellent progress across all metrics.'); expect(result.content).toContain('Generated on 2025-09-10 by John Doe'); // No unreplaced tokens expect(result.content).not.toContain('{{title}}'); expect(result.content).not.toContain('{{date}}'); expect(result.content).not.toContain('{{author}}'); expect(result.content).not.toContain('{{summary}}'); }); it('should handle optional variables with defaults', async () => { const templateContent = `--- name: welcome description: Welcome message variables: - name: name type: string required: true - name: role type: string default: "user" - name: theme type: string default: "light" --- Welcome {{name}}! Your role is: {{role}} Theme preference: {{theme}}`; await fs.writeFile( path.join(tempDir, 'templates', 'welcome.md'), templateContent ); // Render with only required variable const result = await renderer.render('welcome', { name: 'Bob' }); // VERIFICATION: Required variable substituted, defaults used console.log('โœ… PROOF OF FIX - Defaults applied:', result.content); expect(result.success).toBe(true); expect(result.content).toBe(`Welcome Bob! Your role is: user Theme preference: light`); }); }); describe('PROOF: Performance Metrics Work', () => { it('should track accurate performance metrics', async () => { const templateContent = `--- name: perf-test description: Performance test template --- Simple content`; await fs.writeFile( path.join(tempDir, 'templates', 'perf-test.md'), templateContent ); const result = await renderer.render('perf-test', {}); // VERIFICATION: Performance metrics are tracked console.log('โœ… PROOF OF FIX - Performance metrics:', result.performance); expect(result.success).toBe(true); expect(result.performance).toBeDefined(); expect(result.performance!.lookupTime).toBeGreaterThanOrEqual(0); expect(result.performance!.renderTime).toBeGreaterThanOrEqual(0); expect(result.performance!.totalTime).toBeGreaterThanOrEqual(0); expect(result.performance!.totalTime).toBeGreaterThanOrEqual( result.performance!.lookupTime + result.performance!.renderTime ); }); }); describe('PROOF: Type Validation Works', () => { it('should validate Template instance type', async () => { // Create a valid template const templateContent = `--- name: valid description: Valid template --- Content`; await fs.writeFile( path.join(tempDir, 'templates', 'valid.md'), templateContent ); // Verify template is loaded as Template instance const template = await templateManager.find(t => t.metadata.name === 'valid'); // VERIFICATION: Template is correct type console.log('โœ… PROOF OF FIX - Template type:', template?.constructor.name); expect(template).toBeDefined(); expect(template).toBeInstanceOf(Template); expect(typeof template!.render).toBe('function'); }); it('should validate render return type', async () => { const templateContent = `--- name: string-return description: Tests string return --- This returns a string`; await fs.writeFile( path.join(tempDir, 'templates', 'string-return.md'), templateContent ); const result = await renderer.render('string-return', {}); // VERIFICATION: render() returns string console.log('โœ… PROOF OF FIX - Return type:', typeof result.content); expect(result.success).toBe(true); expect(typeof result.content).toBe('string'); expect(result.content).toBe('This returns a string'); }); }); describe('PROOF: Error Handling Works', () => { it('should handle missing template gracefully', async () => { const result = await renderer.render('nonexistent', {}); // VERIFICATION: Missing template handled console.log('โœ… PROOF OF FIX - Missing template error:', result.error); expect(result.success).toBe(false); expect(result.error).toBe("Template 'nonexistent' not found"); }); it('should handle missing required variables', async () => { const templateContent = `--- name: strict description: Strict template variables: - name: required_field type: string required: true --- Value: {{required_field}}`; await fs.writeFile( path.join(tempDir, 'templates', 'strict.md'), templateContent ); const result = await renderer.render('strict', {}); // VERIFICATION: Missing required variable caught console.log('โœ… PROOF OF FIX - Validation error:', result.error); expect(result.success).toBe(false); expect(result.error).toContain('required_field'); }); }); }); /** * TEST EXECUTION SUMMARY: * * Run these tests with: * npm test -- test/__tests__/integration/template-rendering-proof.test.ts --no-coverage * * These integration tests PROVE that: * 1. โœ… Variables ARE actually substituted in templates * 2. โœ… Complex templates with multiple variables work * 3. โœ… Default values are applied correctly * 4. โœ… Performance metrics are accurately tracked * 5. โœ… Type validation correctly identifies Template instances * 6. โœ… render() returns strings as expected * 7. โœ… Error cases are handled gracefully * * This provides concrete evidence that Issues #913 and #914 are fixed. */

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/DollhouseMCP/DollhouseMCP'

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