147 lines
4.9 KiB
TypeScript
147 lines
4.9 KiB
TypeScript
/**
|
|
* Framework Templates Test Suite
|
|
*
|
|
* Tests the framework-agnostic template registry, ensuring:
|
|
* - All adapters have corresponding framework info
|
|
* - Universal templates map correctly to framework-specific configs
|
|
* - Template resolution works for all framework/template combinations
|
|
*/
|
|
|
|
import { describe, it, expect } from 'vitest'
|
|
import {
|
|
FRAMEWORK_REGISTRY,
|
|
UNIVERSAL_TEMPLATES,
|
|
listFrameworks,
|
|
getFrameworkInfo,
|
|
getTemplatesForFramework,
|
|
getUniversalTemplate,
|
|
resolveTemplateConfig,
|
|
} from '../framework-templates'
|
|
import { listAdapters } from '../adapters'
|
|
import { AGENT_TEMPLATES } from '../agent-templates'
|
|
|
|
describe('Framework Registry', () => {
|
|
it('has an entry for every registered adapter', () => {
|
|
const adapters = listAdapters()
|
|
for (const adapter of adapters) {
|
|
expect(FRAMEWORK_REGISTRY[adapter]).toBeDefined()
|
|
expect(FRAMEWORK_REGISTRY[adapter].id).toBe(adapter)
|
|
}
|
|
})
|
|
|
|
it('every framework has required connection config', () => {
|
|
for (const fw of listFrameworks()) {
|
|
expect(fw.connection).toBeDefined()
|
|
expect(fw.connection.connectionMode).toMatch(/^(webhook|polling|websocket)$/)
|
|
expect(fw.connection.heartbeatInterval).toBeGreaterThan(0)
|
|
expect(fw.connection.setupHints.length).toBeGreaterThan(0)
|
|
expect(fw.connection.exampleSnippet.length).toBeGreaterThan(0)
|
|
}
|
|
})
|
|
|
|
it('every framework has a label and description', () => {
|
|
for (const fw of listFrameworks()) {
|
|
expect(fw.label).toBeTruthy()
|
|
expect(fw.description).toBeTruthy()
|
|
}
|
|
})
|
|
|
|
it('getFrameworkInfo returns correct framework', () => {
|
|
const info = getFrameworkInfo('langgraph')
|
|
expect(info?.id).toBe('langgraph')
|
|
expect(info?.label).toBe('LangGraph')
|
|
})
|
|
|
|
it('getFrameworkInfo returns undefined for unknown', () => {
|
|
expect(getFrameworkInfo('nonexistent')).toBeUndefined()
|
|
})
|
|
})
|
|
|
|
describe('Universal Templates', () => {
|
|
it('has at least 5 template archetypes', () => {
|
|
expect(UNIVERSAL_TEMPLATES.length).toBeGreaterThanOrEqual(5)
|
|
})
|
|
|
|
it('every template has required fields', () => {
|
|
for (const tpl of UNIVERSAL_TEMPLATES) {
|
|
expect(tpl.type).toBeTruthy()
|
|
expect(tpl.label).toBeTruthy()
|
|
expect(tpl.description).toBeTruthy()
|
|
expect(tpl.emoji).toBeTruthy()
|
|
expect(tpl.frameworks.length).toBeGreaterThan(0)
|
|
expect(tpl.capabilities.length).toBeGreaterThan(0)
|
|
}
|
|
})
|
|
|
|
it('every template supports at least "generic" framework', () => {
|
|
for (const tpl of UNIVERSAL_TEMPLATES) {
|
|
expect(tpl.frameworks).toContain('generic')
|
|
}
|
|
})
|
|
|
|
it('templates with openclawTemplateType reference valid OpenClaw templates', () => {
|
|
for (const tpl of UNIVERSAL_TEMPLATES) {
|
|
if (tpl.openclawTemplateType) {
|
|
const ocTemplate = AGENT_TEMPLATES.find(t => t.type === tpl.openclawTemplateType)
|
|
expect(ocTemplate).toBeDefined()
|
|
}
|
|
}
|
|
})
|
|
|
|
it('getUniversalTemplate returns correct template', () => {
|
|
const tpl = getUniversalTemplate('developer')
|
|
expect(tpl?.type).toBe('developer')
|
|
expect(tpl?.label).toBe('Developer')
|
|
})
|
|
|
|
it('getUniversalTemplate returns undefined for unknown', () => {
|
|
expect(getUniversalTemplate('nonexistent')).toBeUndefined()
|
|
})
|
|
})
|
|
|
|
describe('Template-Framework Resolution', () => {
|
|
it('getTemplatesForFramework returns templates for known frameworks', () => {
|
|
for (const fw of listAdapters()) {
|
|
const templates = getTemplatesForFramework(fw)
|
|
expect(templates.length).toBeGreaterThan(0)
|
|
}
|
|
})
|
|
|
|
it('getTemplatesForFramework returns empty for unknown framework', () => {
|
|
expect(getTemplatesForFramework('nonexistent')).toEqual([])
|
|
})
|
|
|
|
it('resolveTemplateConfig returns OpenClaw template for openclaw framework', () => {
|
|
const result = resolveTemplateConfig('developer', 'openclaw')
|
|
expect(result).toBeDefined()
|
|
expect(result?.template).toBeDefined()
|
|
expect(result?.template?.type).toBe('developer')
|
|
expect(result?.universal.type).toBe('developer')
|
|
})
|
|
|
|
it('resolveTemplateConfig returns universal-only for non-openclaw frameworks', () => {
|
|
const result = resolveTemplateConfig('developer', 'langgraph')
|
|
expect(result).toBeDefined()
|
|
expect(result?.template).toBeUndefined()
|
|
expect(result?.universal.type).toBe('developer')
|
|
})
|
|
|
|
it('resolveTemplateConfig returns undefined for unknown template', () => {
|
|
expect(resolveTemplateConfig('nonexistent', 'generic')).toBeUndefined()
|
|
})
|
|
|
|
it('resolveTemplateConfig returns undefined for unsupported framework', () => {
|
|
expect(resolveTemplateConfig('developer', 'nonexistent')).toBeUndefined()
|
|
})
|
|
|
|
it('all universal templates resolve for all their declared frameworks', () => {
|
|
for (const tpl of UNIVERSAL_TEMPLATES) {
|
|
for (const fw of tpl.frameworks) {
|
|
const result = resolveTemplateConfig(tpl.type, fw)
|
|
expect(result).toBeDefined()
|
|
expect(result?.universal.type).toBe(tpl.type)
|
|
}
|
|
}
|
|
})
|
|
})
|