203 lines
4.6 KiB
TypeScript
203 lines
4.6 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
|
|
import {
|
|
flattenParameterCandidates,
|
|
findBackspaceTokenRange,
|
|
findTokenRangeAtCursor,
|
|
flattenParameterNames,
|
|
formatParamToken,
|
|
getTokenRanges,
|
|
insertTextAtCursor,
|
|
parseTokenParts,
|
|
splitTokenDisplay,
|
|
} from './paramToken';
|
|
|
|
describe('paramToken utils', () => {
|
|
it('should flatten parameter names with nested paths', () => {
|
|
const result = flattenParameterNames([
|
|
{
|
|
name: 'input',
|
|
},
|
|
{
|
|
name: 'documents',
|
|
children: [
|
|
{
|
|
name: 'title',
|
|
},
|
|
{
|
|
name: 'meta',
|
|
children: [
|
|
{
|
|
name: 'author',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
]);
|
|
|
|
expect(result).toEqual([
|
|
'input',
|
|
'documents',
|
|
'documents.title',
|
|
'documents.meta',
|
|
'documents.meta.author',
|
|
]);
|
|
});
|
|
|
|
it('should keep unresolved candidates in parameter list', () => {
|
|
const result = flattenParameterCandidates([
|
|
{
|
|
name: 'input',
|
|
refType: 'ref',
|
|
ref: '',
|
|
},
|
|
{
|
|
name: 'docs',
|
|
refType: 'ref',
|
|
ref: 'documents',
|
|
},
|
|
{
|
|
name: 'runtimeInput',
|
|
refType: 'input',
|
|
},
|
|
]);
|
|
|
|
expect(result).toEqual([
|
|
{
|
|
dataType: undefined,
|
|
disconnected: false,
|
|
displayName: 'input',
|
|
name: 'input',
|
|
resolved: false,
|
|
},
|
|
{
|
|
dataType: undefined,
|
|
disconnected: false,
|
|
displayName: 'docs',
|
|
name: 'docs',
|
|
resolved: true,
|
|
},
|
|
{
|
|
dataType: undefined,
|
|
disconnected: false,
|
|
displayName: 'runtimeInput',
|
|
name: 'runtimeInput',
|
|
resolved: true,
|
|
},
|
|
]);
|
|
});
|
|
|
|
it('should insert token text in the middle by cursor range', () => {
|
|
const result = insertTextAtCursor('hello world', '{{input}}', 6, 11);
|
|
expect(result).toEqual({
|
|
value: 'hello {{input}}',
|
|
cursor: 15,
|
|
});
|
|
});
|
|
|
|
it('should append token text when cursor info is missing', () => {
|
|
const result = insertTextAtCursor('hello', '{{name}}');
|
|
expect(result).toEqual({
|
|
value: 'hello{{name}}',
|
|
cursor: 13,
|
|
});
|
|
});
|
|
|
|
it('should parse token parts and mark valid tokens', () => {
|
|
const parts = parseTokenParts('你好 {{ user.name }} 与 {{unknown}}', [
|
|
'user.name',
|
|
'docs',
|
|
]);
|
|
|
|
expect(parts).toEqual([
|
|
{
|
|
type: 'text',
|
|
text: '你好 ',
|
|
},
|
|
{
|
|
type: 'token',
|
|
text: '{{ user.name }}',
|
|
key: 'user.name',
|
|
valid: true,
|
|
},
|
|
{
|
|
type: 'text',
|
|
text: ' 与 ',
|
|
},
|
|
{
|
|
type: 'token',
|
|
text: '{{unknown}}',
|
|
key: 'unknown',
|
|
valid: false,
|
|
},
|
|
]);
|
|
});
|
|
|
|
it('should keep plain text when token syntax is invalid', () => {
|
|
const parts = parseTokenParts('abc {{}} def', ['a']);
|
|
expect(parts).toEqual([
|
|
{
|
|
type: 'text',
|
|
text: 'abc {{}} def',
|
|
},
|
|
]);
|
|
});
|
|
|
|
it('should split token display and hide braces text', () => {
|
|
const result = splitTokenDisplay('{{ user.name }}', 'user.name');
|
|
expect(result).toEqual({
|
|
hiddenPrefix: '{{ ',
|
|
visibleText: 'user.name',
|
|
hiddenSuffix: ' }}',
|
|
});
|
|
});
|
|
|
|
it('should find full token range for backspace delete', () => {
|
|
const content = 'hello {{input}} world';
|
|
const tokenEndCursor = 'hello {{input}}'.length;
|
|
const range = findBackspaceTokenRange(content, tokenEndCursor);
|
|
|
|
expect(range).toEqual({
|
|
start: 6,
|
|
end: 15,
|
|
text: '{{input}}',
|
|
key: 'input',
|
|
});
|
|
});
|
|
|
|
it('should support boundary match for arrow skip behavior', () => {
|
|
const content = 'x{{docs}}y';
|
|
const tokenStart = 1;
|
|
const tokenEnd = 9;
|
|
|
|
const rightBoundary = findTokenRangeAtCursor(content, tokenStart, {
|
|
includeStart: true,
|
|
includeEnd: false,
|
|
});
|
|
const leftBoundary = findTokenRangeAtCursor(content, tokenEnd, {
|
|
includeStart: false,
|
|
includeEnd: true,
|
|
});
|
|
|
|
expect(rightBoundary?.key).toBe('docs');
|
|
expect(leftBoundary?.key).toBe('docs');
|
|
});
|
|
|
|
it('should format and parse Enjoy parameter tokens', () => {
|
|
expect(formatParamToken('申请人', 'enjoy')).toBe('#(申请人)');
|
|
expect(getTokenRanges('申请:#(申请人)', 'enjoy')).toEqual([
|
|
{
|
|
start: 3,
|
|
end: 9,
|
|
text: '#(申请人)',
|
|
key: '申请人',
|
|
},
|
|
]);
|
|
});
|
|
|
|
it('should keep complex Enjoy expressions as editable text', () => {
|
|
expect(getTokenRanges('#(申请人 ?? 被申请人)', 'enjoy')).toEqual([]);
|
|
});
|
|
});
|