mirror of
https://github.com/gorules/zen.git
synced 2026-10-03 16:02:27 +00:00
77 lines
2.8 KiB
TypeScript
77 lines
2.8 KiB
TypeScript
import { describe, expect, it } from '@jest/globals';
|
|
import * as tsc from 'typescript';
|
|
import { Workspace } from '../index';
|
|
import { createFunctionChecker, createTypeResolver, variableTypeToTs } from '../ts-support';
|
|
|
|
const SOURCE = `enum Level { Basic = 'basic', Premium = 'premium' }
|
|
type Region = 'EU' | 'US';
|
|
interface Extra { note: string; }
|
|
export const handler = async (input: FunctionInput) => {
|
|
return {
|
|
level: input.total > 500 ? Level.Premium : Level.Basic,
|
|
region: 'EU' as Region,
|
|
score: Math.round(input.total / 10),
|
|
extra: { note: 'hi' } as Extra,
|
|
};
|
|
};`;
|
|
|
|
const INPUT_TYPE = { type: 'object', fields: { total: { type: 'number' } } } as never;
|
|
|
|
describe('ts-support', () => {
|
|
it('expands aliases, enums and interfaces in resolved types', () => {
|
|
const resolver = createTypeResolver(tsc);
|
|
const resolved = resolver(SOURCE, INPUT_TYPE);
|
|
expect(resolved).toContain('"basic" | "premium"');
|
|
expect(resolved).toContain('"EU" | "US"');
|
|
expect(resolved).toContain('note: string');
|
|
expect(resolved).not.toContain('Level');
|
|
expect(resolved).not.toContain('Region');
|
|
expect(resolved).not.toContain('Extra');
|
|
});
|
|
|
|
it('reports TS diagnostics with prelude-adjusted offsets', () => {
|
|
const checker = createFunctionChecker(tsc);
|
|
const broken = SOURCE.replace('Level.Basic', 'Level.Missing');
|
|
const diagnostics = checker(broken, INPUT_TYPE);
|
|
expect(diagnostics.some((d) => d.message.includes("'Missing'"))).toBe(true);
|
|
for (const diagnostic of diagnostics) {
|
|
expect(diagnostic.start).toBeGreaterThanOrEqual(0);
|
|
expect(broken.slice(diagnostic.start, diagnostic.start + diagnostic.length)).toBe('Missing');
|
|
}
|
|
});
|
|
|
|
it('auto-resolves function types when passed to Workspace', () => {
|
|
const ws = new Workspace(createTypeResolver(tsc));
|
|
ws.setDocument('g', {
|
|
nodes: [
|
|
{
|
|
id: 'in1',
|
|
type: 'inputNode',
|
|
name: 'Request',
|
|
content: {
|
|
schema: JSON.stringify({
|
|
type: 'object',
|
|
required: ['total'],
|
|
properties: { total: { type: 'number' } },
|
|
}),
|
|
},
|
|
},
|
|
{ id: 'fn', type: 'functionNode', name: 'Score', content: { source: SOURCE } },
|
|
{ id: 'out1', type: 'outputNode', name: 'Response', content: {} },
|
|
],
|
|
edges: [
|
|
{ id: 'e1', sourceId: 'in1', targetId: 'fn' },
|
|
{ id: 'e2', sourceId: 'fn', targetId: 'out1' },
|
|
],
|
|
});
|
|
expect(ws.diagnostics('g')).toEqual([]);
|
|
const outputs = ws.outputs({ policyPath: 'g' });
|
|
const level = outputs.find((o) => o.path === 'level');
|
|
expect(level?.resolvedType).toEqual({ name: null, type: 'enum', values: ['basic', 'premium'] });
|
|
});
|
|
|
|
it('renders variable types as TypeScript', () => {
|
|
expect(variableTypeToTs(INPUT_TYPE)).toBe('{ total: number }');
|
|
});
|
|
});
|