dpml-prompt
Version:
DPML-powered AI prompt framework - Revolutionary AI-First CLI system based on Deepractice Prompt Markup Language. Build sophisticated AI agents with structured prompts, memory systems, and execution frameworks.
134 lines (107 loc) • 4.68 kB
JavaScript
const ResourceProtocolParser = require('../../../lib/core/resource/resourceProtocolParser')
const {
LoadingSemantics,
ParsedReference,
QueryParams
} = require('../../../lib/core/resource/types')
describe('ResourceProtocolParser - Unit Tests', () => {
let parser
beforeEach(() => {
parser = new ResourceProtocolParser()
})
describe('基础语法解析', () => {
test('应该解析基本的资源引用', () => {
const result = parser.parse('@prompt://protocols')
expect(result.protocol).toBe('prompt')
expect(result.path).toBe('protocols')
expect(result.loadingSemantics).toBe(LoadingSemantics.DEFAULT)
expect(result.isNested).toBe(false)
})
test('应该解析带查询参数的资源引用', () => {
const result = parser.parse('@file://test.md?line=5-10&cache=true')
expect(result.protocol).toBe('file')
expect(result.path).toBe('test.md')
expect(result.queryParams.line).toBe('5-10')
expect(result.queryParams.cache).toBe(true)
})
test('应该解析热加载语义', () => {
const result = parser.parse('@!prompt://core')
expect(result.protocol).toBe('prompt')
expect(result.path).toBe('core')
expect(result.loadingSemantics).toBe(LoadingSemantics.HOT_LOAD)
})
test('应该解析懒加载语义', () => {
const result = parser.parse('@?file://lazy-resource.md')
expect(result.protocol).toBe('file')
expect(result.path).toBe('lazy-resource.md')
expect(result.loadingSemantics).toBe(LoadingSemantics.LAZY_LOAD)
})
})
describe('嵌套引用解析', () => {
test('应该解析简单嵌套引用', () => {
const result = parser.parse('@prompt://@file://nested.md')
expect(result.protocol).toBe('prompt')
expect(result.isNested).toBe(true)
expect(result.nestedRef.inner.protocol).toBe('file')
expect(result.nestedRef.inner.path).toBe('nested.md')
})
test('应该解析多层嵌套引用', () => {
const result = parser.parse('@prompt://@memory://@file://deep.md')
expect(result.protocol).toBe('prompt')
expect(result.isNested).toBe(true)
expect(result.nestedRef.inner.protocol).toBe('memory')
expect(result.nestedRef.inner.isNested).toBe(true)
expect(result.nestedRef.depth).toBe(2)
})
})
describe('查询参数解析', () => {
test('应该解析多个查询参数', () => {
const params = parser.parseQueryParams('line=1-10&format=json&cache=true')
expect(params.line).toBe('1-10')
expect(params.format).toBe('json')
expect(params.cache).toBe(true)
})
test('应该处理空查询参数', () => {
const params = parser.parseQueryParams('')
expect(params.getAll()).toEqual({})
})
test('应该处理URL编码的参数', () => {
const params = parser.parseQueryParams('query=%E4%B8%AD%E6%96%87')
expect(params.get('query')).toBe('中文')
})
})
describe('语法验证', () => {
test('应该验证有效的语法', () => {
expect(parser.validateSyntax('@prompt://protocols')).toBe(true)
expect(parser.validateSyntax('@!file://test.md')).toBe(true)
expect(parser.validateSyntax('@?memory://declarative')).toBe(true)
})
test('应该拒绝无效的语法', () => {
expect(parser.validateSyntax('prompt://protocols')).toBe(false) // 缺少@
expect(parser.validateSyntax('@://test')).toBe(false) // 空协议
expect(parser.validateSyntax('@123protocol://test')).toBe(false) // 协议名不能以数字开头
expect(parser.validateSyntax('')).toBe(false) // 空字符串
})
})
describe('错误处理', () => {
test('应该抛出适当的错误信息', () => {
expect(() => parser.parse('')).toThrow('Invalid resource reference')
expect(() => parser.parse(null)).toThrow('Invalid resource reference')
expect(() => parser.parse('invalid')).toThrow('Invalid resource reference syntax')
})
})
describe('工具方法', () => {
test('应该正确提取协议名', () => {
expect(parser.extractProtocol('@prompt://protocols')).toBe('prompt')
expect(parser.extractProtocol('@!file://test.md')).toBe('file')
})
test('应该正确提取路径', () => {
expect(parser.extractPath('@prompt://protocols?format=json')).toBe('protocols')
expect(parser.extractPath('@file://path/to/file.md')).toBe('path/to/file.md')
})
test('应该正确提取查询参数', () => {
expect(parser.extractParams('@file://test.md?line=5-10')).toBe('line=5-10')
expect(parser.extractParams('@file://test.md')).toBe('')
})
})
})