cps-interpreter/test/signature_match.spec.ts
2024-02-28 13:41:53 -07:00

157 lines
3.5 KiB
TypeScript

import { expect, test } from 'bun:test';
import {
type DenotableFunctionSignature,
denotableTypesEquivalent,
matchSignature,
} from '@/interpreter';
test('simple denotable types are equivalent', () => {
expect(denotableTypesEquivalent('int', 'int')).toBe(true);
expect(denotableTypesEquivalent('int', 'real')).toBe(false);
expect(denotableTypesEquivalent('int', 'null')).toBe(false);
expect(denotableTypesEquivalent('null', 'null')).toBe(true);
});
test('union data types are equivalent', () => {
expect(denotableTypesEquivalent(['int', 'real'], ['int', 'real'])).toBe(true);
expect(denotableTypesEquivalent('int', ['int', 'real'])).toBe(false);
});
test('function data types are equivalent', () => {
expect(
denotableTypesEquivalent(
[
{
arguments: ['int', 'real'],
return: 'int',
},
],
[
{
arguments: ['int', 'real'],
return: 'int',
},
],
),
).toBe(true);
expect(
denotableTypesEquivalent(
[
{
arguments: ['int', 'real'],
return: 'real',
},
],
[
{
arguments: ['int', 'real'],
return: 'int',
},
],
),
).toBe(false);
});
test('matches simple signatures', async () => {
const simpleSignature: DenotableFunctionSignature[] = [
{
arguments: ['int'],
return: 'int',
},
];
expect(matchSignature(['int'], simpleSignature)).toEqual(simpleSignature[0]);
});
test('finds first match', async () => {
const simpleSignature: DenotableFunctionSignature[] = [
{
arguments: ['int', 'int'],
return: 'int',
},
{
arguments: [['int', 'real'], 'int'],
return: 'real',
},
];
expect(matchSignature(['int', 'int'], simpleSignature)).toEqual(
simpleSignature[0],
);
expect(matchSignature(['real', 'int'], simpleSignature)).toEqual(
simpleSignature[1],
);
});
test('finds first match with a function signature', async () => {
const testSignature: DenotableFunctionSignature = {
arguments: ['int', 'real'],
return: 'int',
};
const simpleSignature: DenotableFunctionSignature[] = [
{
arguments: ['int', 'int'],
return: 'int',
},
{
arguments: [[testSignature, 'real'], 'int'],
return: 'function',
},
];
expect(matchSignature(['int', 'int'], simpleSignature)).toEqual(
simpleSignature[0],
);
expect(matchSignature(['real', 'int'], simpleSignature)).toEqual(
simpleSignature[1],
);
expect(matchSignature([testSignature, 'int'], simpleSignature)).toEqual(
simpleSignature[1],
);
});
test('finds first match with a function with many signatures', async () => {
const testSignature: DenotableFunctionSignature[] = [
{
arguments: ['int', 'real'],
return: 'int',
},
{
arguments: ['int', 'int'],
return: 'int',
},
];
const simpleSignature: DenotableFunctionSignature[] = [
{
arguments: ['int', 'int'],
return: 'int',
},
{
arguments: [[testSignature, 'real'], 'int'],
return: 'function',
},
];
expect(matchSignature(['int', 'int'], simpleSignature)).toEqual(
simpleSignature[0],
);
expect(matchSignature(['real', 'int'], simpleSignature)).toEqual(
simpleSignature[1],
);
expect(matchSignature([testSignature, 'int'], simpleSignature)).toEqual(
simpleSignature[1],
);
expect(
matchSignature([[testSignature[0]], 'int'], simpleSignature),
).toBeUndefined();
});