@@ -71,4 +71,71 @@ describe('Extractor Edge Cases', () => {
7171 expect ( entry ?. kind ) . toBe ( 'interface' ) ;
7272 expect ( entry ?. members ?. length ) . toBeGreaterThan ( 0 ) ;
7373 } ) ;
74+
75+ it ( 'builds stable heritage ids for multiple symbol shapes' , async ( ) => {
76+ const tempDir = await createTempDir ( 'autodocs-extractor-' ) ;
77+ const entryPath = await writeTempFile (
78+ tempDir ,
79+ 'src/heritage.ts' ,
80+ `
81+ export interface InterfaceBase {
82+ value: string;
83+ }
84+ export type TypeBase = {
85+ count: number;
86+ };
87+ export class ClassBase {}
88+ export const VariableBase = class {};
89+ export function FunctionBase(this: unknown) {}
90+ export enum EnumBase {
91+ Alpha = 'alpha'
92+ }
93+
94+ export interface InterfaceChild extends InterfaceBase {}
95+ export interface TypeChild extends TypeBase {}
96+ export interface UnknownChild extends MissingBase {}
97+
98+ export class ClassChild extends ClassBase {}
99+ export class VariableChild extends VariableBase {}
100+ export class FunctionChild extends (FunctionBase as unknown as { new (): unknown }) {}
101+ export class EnumChild extends (EnumBase as unknown as { new (): unknown }) {}
102+ `
103+ ) ;
104+
105+ const result = createProgram ( [ entryPath ] ) ;
106+ const docs = extractDocs ( result . program , { rootDir : tempDir } ) ;
107+
108+ const interfaceChild = docs . find ( ( d ) => d . name === 'InterfaceChild' ) ;
109+ const typeChild = docs . find ( ( d ) => d . name === 'TypeChild' ) ;
110+ const unknownChild = docs . find ( ( d ) => d . name === 'UnknownChild' ) ;
111+ const classChild = docs . find ( ( d ) => d . name === 'ClassChild' ) ;
112+ const variableChild = docs . find ( ( d ) => d . name === 'VariableChild' ) ;
113+ const functionChild = docs . find ( ( d ) => d . name === 'FunctionChild' ) ;
114+ const enumChild = docs . find ( ( d ) => d . name === 'EnumChild' ) ;
115+
116+ expect ( interfaceChild ?. heritage ?. [ 0 ] ) . toMatchObject ( { name : 'InterfaceBase' , kind : 'extends' } ) ;
117+ expect ( typeChild ?. heritage ?. [ 0 ] ) . toMatchObject ( { kind : 'extends' } ) ;
118+ expect ( typeChild ?. heritage ?. [ 0 ] ?. name ) . toBeTruthy ( ) ;
119+ expect ( unknownChild ?. heritage ?. [ 0 ] ) . toMatchObject ( { name : 'unknown' , kind : 'extends' } ) ;
120+ expect ( classChild ?. heritage ?. [ 0 ] ) . toMatchObject ( { kind : 'extends' } ) ;
121+ expect ( variableChild ?. heritage ?. [ 0 ] ) . toMatchObject ( { kind : 'extends' } ) ;
122+ expect ( functionChild ?. heritage ?. [ 0 ] ) . toMatchObject ( { kind : 'extends' } ) ;
123+ expect ( enumChild ?. heritage ?. [ 0 ] ) . toMatchObject ( { kind : 'extends' } ) ;
124+ expect ( classChild ?. heritage ?. [ 0 ] ?. name ) . toBeTruthy ( ) ;
125+ expect ( variableChild ?. heritage ?. [ 0 ] ?. name ) . toBeTruthy ( ) ;
126+ expect ( functionChild ?. heritage ?. [ 0 ] ?. name ) . toBeTruthy ( ) ;
127+ expect ( enumChild ?. heritage ?. [ 0 ] ?. name ) . toBeTruthy ( ) ;
128+
129+ for ( const entry of [
130+ interfaceChild ,
131+ typeChild ,
132+ unknownChild ,
133+ classChild ,
134+ variableChild ,
135+ functionChild ,
136+ enumChild ,
137+ ] ) {
138+ expect ( entry ?. heritage ?. [ 0 ] ?. id ) . toMatch ( / ^ [ 0 - 9 a - f ] { 8 } $ / ) ;
139+ }
140+ } ) ;
74141} ) ;
0 commit comments