Skip to main content
Glama

AI Code Toolkit

by AgiFlow
ScaffoldConfigLoader.test.ts5.57 kB
import { beforeEach, describe, expect, it, vi } from 'vitest'; import { ScaffoldConfigLoader } from '../../src/services/ScaffoldConfigLoader'; import { createMockFileSystemService, createMockTemplateService } from '../__mocks__'; describe('ScaffoldConfigLoader', () => { let loader: ScaffoldConfigLoader; let mockFileSystem: ReturnType<typeof createMockFileSystemService>; let mockTemplate: ReturnType<typeof createMockTemplateService>; beforeEach(() => { mockFileSystem = createMockFileSystemService(); mockTemplate = createMockTemplateService(); loader = new ScaffoldConfigLoader(mockFileSystem, mockTemplate); }); describe('parseIncludeEntry', () => { it('should parse basic file path', () => { const result = loader.parseIncludeEntry('src/index.ts', {}); expect(result.sourcePath).toBe('src/index.ts'); expect(result.targetPath).toBe('src/index.ts'); expect(result.conditions).toEqual({}); }); it('should parse conditional includes', () => { const result = loader.parseIncludeEntry('layout.tsx?withLayout=true', { withLayout: true }); expect(result.sourcePath).toBe('layout.tsx'); expect(result.conditions).toEqual({ withLayout: 'true' }); }); it('should parse multiple conditions', () => { const result = loader.parseIncludeEntry('test.tsx?withTests=true&withDocs=false', {}); expect(result.conditions).toEqual({ withTests: 'true', withDocs: 'false', }); }); it('should parse arrow syntax for path mapping', () => { const result = loader.parseIncludeEntry('template.tsx->src/app/page.tsx', {}); expect(result.sourcePath).toBe('template.tsx'); expect(result.targetPath).toBe('src/app/page.tsx'); }); it('should combine arrow syntax with conditions', () => { const result = loader.parseIncludeEntry('template.tsx->{{ path }}/page.tsx?withPage=true', { path: 'custom', }); expect(result.sourcePath).toBe('template.tsx'); expect(result.conditions).toEqual({ withPage: 'true' }); }); }); describe('shouldIncludeFile', () => { it('should return true when no conditions', () => { const result = loader.shouldIncludeFile(undefined, {}); expect(result).toBe(true); }); it('should return true when boolean condition matches', () => { const result = loader.shouldIncludeFile({ withLayout: 'true' }, { withLayout: true }); expect(result).toBe(true); }); it('should return false when boolean condition does not match', () => { const result = loader.shouldIncludeFile({ withLayout: 'true' }, { withLayout: false }); expect(result).toBe(false); }); it('should return true when string condition matches', () => { const result = loader.shouldIncludeFile({ type: 'component' }, { type: 'component' }); expect(result).toBe(true); }); it('should return false when string condition does not match', () => { const result = loader.shouldIncludeFile({ type: 'component' }, { type: 'page' }); expect(result).toBe(false); }); it('should handle multiple conditions', () => { const result = loader.shouldIncludeFile( { withTests: 'true', type: 'service' }, { withTests: true, type: 'service' }, ); expect(result).toBe(true); }); }); describe('replaceVariablesInPath', () => { it('should replace variables in path', () => { mockTemplate.renderString.mockReturnValue('src/app/dashboard/page.tsx'); const _result = loader.replaceVariablesInPath('src/app/{{ pagePath }}/page.tsx', { pagePath: 'dashboard', }); expect(mockTemplate.renderString).toHaveBeenCalled(); }); }); describe('validateTemplate', () => { it('should return valid for existing template with all files', async () => { mockFileSystem.pathExists.mockResolvedValue(true); // Mock parseArchitectConfig to return a valid config const parseArchitectConfigSpy = vi.spyOn(loader as any, 'parseArchitectConfig'); parseArchitectConfigSpy.mockResolvedValue({ boilerplate: { name: 'test', includes: ['package.json', 'src/index.ts'], }, }); const result = await loader.validateTemplate('/templates/test', 'boilerplate'); expect(result.isValid).toBe(true); expect(result.errors).toHaveLength(0); }); it('should return errors for non-existent template', async () => { mockFileSystem.pathExists.mockResolvedValue(false); const result = await loader.validateTemplate('/nonexistent', 'boilerplate'); expect(result.isValid).toBe(false); expect(result.errors.length).toBeGreaterThan(0); }); it('should detect missing template files', async () => { mockFileSystem.pathExists .mockResolvedValueOnce(true) // Template dir exists .mockResolvedValueOnce(false) // First file missing .mockResolvedValueOnce(false); // .liquid version also missing // Mock parseArchitectConfig to return a config with a missing file const parseArchitectConfigSpy = vi.spyOn(loader as any, 'parseArchitectConfig'); parseArchitectConfigSpy.mockResolvedValue({ boilerplate: { name: 'test', includes: ['missing-file.ts'], }, }); const result = await loader.validateTemplate('/templates/test', 'boilerplate'); expect(result.isValid).toBe(false); expect(result.missingFiles.length).toBeGreaterThan(0); }); }); });

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/AgiFlow/aicode-toolkit'

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