apisurf
Version:
Analyze API surface changes between npm package versions to catch breaking changes
173 lines (172 loc) • 6.07 kB
JavaScript
import { describe, expect, it } from '@jest/globals';
import { parseTypeDefinition } from './parseTypeDefinition.js';
describe('parseTypeDefinition', () => {
it('should parse a simple type alias', () => {
const lines = [
'export type ID = string;'
];
const result = parseTypeDefinition(lines, 0, 'ID');
expect(result).toEqual({
name: 'ID',
kind: 'type',
extendedProperties: undefined,
signature: 'export type ID = string;'
});
});
it('should parse a union type', () => {
const lines = [
'export type Status = "active" | "inactive" | "pending";'
];
const result = parseTypeDefinition(lines, 0, 'Status');
expect(result).toEqual({
name: 'Status',
kind: 'type',
extendedProperties: undefined,
signature: 'export type Status = "active" | "inactive" | "pending";'
});
});
it('should parse an object type', () => {
const lines = [
'export type User = {',
' id: string;',
' name: string;',
' email?: string;',
'};'
];
const result = parseTypeDefinition(lines, 0, 'User');
expect(result).toEqual({
name: 'User',
kind: 'type',
extendedProperties: [
{ name: 'id', required: true },
{ name: 'name', required: true },
{ name: 'email', required: false }
],
signature: 'export type User = { id: any; name: any; email?: any }'
});
});
it('should parse a function type', () => {
const lines = [
'export type Handler = (event: Event) => void;'
];
const result = parseTypeDefinition(lines, 0, 'Handler');
expect(result).toEqual({
name: 'Handler',
kind: 'type',
signature: 'export type Handler = (event: Event) => void;'
});
});
it('should parse a generic function type', () => {
const lines = [
'export type Transform<T> = (input: T) => T;'
];
const result = parseTypeDefinition(lines, 0, 'Transform');
expect(result).toEqual({
name: 'Transform',
kind: 'type',
signature: 'export type Transform<T> = (input: T) => T;'
});
});
it('should parse a multi-line function type', () => {
const lines = [
'export type ComplexHandler = (',
' data: Data,',
' options: Options',
') => Promise<Result>;'
];
const result = parseTypeDefinition(lines, 0, 'ComplexHandler');
expect(result).toEqual({
name: 'ComplexHandler',
kind: 'type',
signature: 'export type ComplexHandler = ( data: Data, options: Options ) => Promise<Result>;'
});
});
it('should parse an intersection type', () => {
const lines = [
'export type AdminUser = User & { role: "admin" };'
];
const result = parseTypeDefinition(lines, 0, 'AdminUser');
expect(result).toEqual({
name: 'AdminUser',
kind: 'type',
extendedProperties: undefined,
signature: 'export type AdminUser = User & { role: "admin" };'
});
});
it('should parse a conditional type', () => {
const lines = [
'export type IsString<T> = T extends string ? true : false;'
];
const result = parseTypeDefinition(lines, 0, 'IsString');
expect(result).toEqual({
name: 'IsString',
kind: 'type',
extendedProperties: undefined,
signature: 'export type IsString<T> = T extends string ? true : false;'
});
});
it('should parse an object type with methods', () => {
const lines = [
'export type Service = {',
' start(): void;',
' stop(): void;',
' status?: () => string;',
'};'
];
const result = parseTypeDefinition(lines, 0, 'Service');
expect(result).toEqual({
name: 'Service',
kind: 'type',
extendedProperties: [
{ name: 'start', required: true },
{ name: 'stop', required: true },
{ name: 'status', required: false }
],
signature: 'export type Service = { start: any; stop: any; status?: any }'
});
});
it('should parse an empty object type', () => {
const lines = [
'export type Empty = {};'
];
const result = parseTypeDefinition(lines, 0, 'Empty');
expect(result).toEqual({
name: 'Empty',
kind: 'type',
extendedProperties: [],
signature: 'export type Empty = { }'
});
});
it('should parse a mapped type', () => {
const lines = [
'export type Readonly<T> = { readonly [K in keyof T]: T[K] };'
];
const result = parseTypeDefinition(lines, 0, 'Readonly');
expect(result).toEqual({
name: 'Readonly',
kind: 'type',
extendedProperties: undefined,
signature: 'export type Readonly<T> = { readonly [K in keyof T]: T[K] };'
});
});
it('should start parsing from the specified index', () => {
const lines = [
'some other code',
'more code',
'export type Point = {',
' x: number;',
' y: number;',
'};'
];
const result = parseTypeDefinition(lines, 2, 'Point');
expect(result).toEqual({
name: 'Point',
kind: 'type',
extendedProperties: [
{ name: 'x', required: true },
{ name: 'y', required: true }
],
signature: 'export type Point = { x: any; y: any }'
});
});
});