apisurf
Version:
Analyze API surface changes between npm package versions to catch breaking changes
163 lines (162 loc) • 5.68 kB
JavaScript
import { describe, expect, it } from '@jest/globals';
import { parseInterfaceDefinition } from './parseInterfaceDefinition.js';
describe('parseInterfaceDefinition', () => {
it('should parse a simple interface', () => {
const lines = [
'export interface User {',
' id: number;',
' name: string;',
' email: string;',
'}'
];
const result = parseInterfaceDefinition(lines, 0, 'User');
expect(result).toEqual({
name: 'User',
kind: 'interface',
extendedProperties: [
{ name: 'id', required: true },
{ name: 'name', required: true },
{ name: 'email', required: true }
],
signature: 'export interface User { id: any; name: any; email: any }'
});
});
it('should parse an interface with optional properties', () => {
const lines = [
'export interface Config {',
' host: string;',
' port?: number;',
' secure?: boolean;',
'}'
];
const result = parseInterfaceDefinition(lines, 0, 'Config');
expect(result).toEqual({
name: 'Config',
kind: 'interface',
extendedProperties: [
{ name: 'host', required: true },
{ name: 'port', required: false },
{ name: 'secure', required: false }
],
signature: 'export interface Config { host: any; port?: any; secure?: any }'
});
});
it('should handle empty interface', () => {
const lines = [
'export interface Empty {',
'}'
];
const result = parseInterfaceDefinition(lines, 0, 'Empty');
expect(result).toEqual({
name: 'Empty',
kind: 'interface',
extendedProperties: [],
signature: 'export interface Empty { }'
});
});
it('should handle interface with methods', () => {
const lines = [
'export interface Service {',
' start(): void;',
' stop(): void;',
' status?: () => string;',
'}'
];
const result = parseInterfaceDefinition(lines, 0, 'Service');
expect(result).toEqual({
name: 'Service',
kind: 'interface',
extendedProperties: [
{ name: 'start', required: true },
{ name: 'stop', required: true },
{ name: 'status', required: false }
],
signature: 'export interface Service { start: any; stop: any; status?: any }'
});
});
it('should handle interface with nested objects', () => {
const lines = [
'export interface Nested {',
' user: {',
' id: number;',
' name: string;',
' };',
' settings?: {',
' theme: string;',
' };',
'}'
];
const result = parseInterfaceDefinition(lines, 0, 'Nested');
expect(result).toEqual({
name: 'Nested',
kind: 'interface',
extendedProperties: [
{ name: 'user', required: true },
{ name: 'settings', required: false }
],
signature: 'export interface Nested { user: any; settings?: any }'
});
});
it('should ignore comments and blank lines', () => {
const lines = [
'export interface WithComments {',
' // This is a comment',
' prop1: string;',
'',
' /* Multi-line',
' comment */',
' prop2?: number;',
'}'
];
const result = parseInterfaceDefinition(lines, 0, 'WithComments');
expect(result).toEqual({
name: 'WithComments',
kind: 'interface',
extendedProperties: [
{ name: 'prop1', required: true },
{ name: 'prop2', required: false }
],
signature: 'export interface WithComments { prop1: any; prop2?: any }'
});
});
it('should start parsing from the specified index', () => {
const lines = [
'some other code',
'more code',
'export interface Product {',
' id: string;',
' name: string;',
' price: number;',
'}'
];
const result = parseInterfaceDefinition(lines, 2, 'Product');
expect(result).toEqual({
name: 'Product',
kind: 'interface',
extendedProperties: [
{ name: 'id', required: true },
{ name: 'name', required: true },
{ name: 'price', required: true }
],
signature: 'export interface Product { id: any; name: any; price: any }'
});
});
it('should handle interface extending other interfaces', () => {
const lines = [
'export interface Admin extends User {',
' role: string;',
' permissions: string[];',
'}'
];
const result = parseInterfaceDefinition(lines, 0, 'Admin');
expect(result).toEqual({
name: 'Admin',
kind: 'interface',
extendedProperties: [
{ name: 'role', required: true },
{ name: 'permissions', required: true }
],
signature: 'export interface Admin { role: any; permissions: any }'
});
});
});