@@ -31,6 +31,111 @@ describe('config loader', () => {
3131 expect ( config ?. output . dir ) . toBe ( './docs' ) ;
3232 } ) ;
3333
34+ it ( 'loads TypeScript config files' , async ( ) => {
35+ const tempDir = await createTempDir ( ) ;
36+ const configPath = path . join ( tempDir , 'autodocs.config.ts' ) ;
37+ await fs . writeFile (
38+ configPath ,
39+ `export default { include: ['src/**/*.ts'], output: { dir: './typed', format: 'json' } };` ,
40+ 'utf-8'
41+ ) ;
42+
43+ const config = await loadConfig ( tempDir ) ;
44+ expect ( config ) . not . toBeNull ( ) ;
45+ expect ( config ?. output . dir ) . toBe ( './typed' ) ;
46+ expect ( config ?. output . format ) . toBe ( 'json' ) ;
47+ } ) ;
48+
49+ it ( 'loads JSON config from an explicit config path' , async ( ) => {
50+ const tempDir = await createTempDir ( ) ;
51+ const configPath = path . join ( tempDir , 'autodocs.config.json' ) ;
52+ await fs . writeFile (
53+ configPath ,
54+ JSON . stringify ( { include : [ 'lib/**/*.ts' ] , output : { dir : './explicit' , format : 'json' } } ) ,
55+ 'utf-8'
56+ ) ;
57+
58+ const config = await loadConfig ( configPath ) ;
59+ expect ( config ) . not . toBeNull ( ) ;
60+ expect ( config ?. include ) . toContain ( 'lib/**/*.ts' ) ;
61+ expect ( config ?. output . dir ) . toBe ( './explicit' ) ;
62+ expect ( config ?. output . format ) . toBe ( 'json' ) ;
63+ } ) ;
64+
65+ it ( 'returns null when no config file exists' , async ( ) => {
66+ const tempDir = await createTempDir ( ) ;
67+ const config = await loadConfig ( tempDir ) ;
68+ expect ( config ) . toBeNull ( ) ;
69+ } ) ;
70+
71+ it ( 'falls back to manual JSON parsing when cosmiconfig returns null for explicit path' , async ( ) => {
72+ const tempDir = await createTempDir ( ) ;
73+ const configPath = path . join ( tempDir , 'autodocs.config.json' ) ;
74+ await fs . writeFile (
75+ configPath ,
76+ JSON . stringify ( { output : { dir : './fallback-json' , format : 'json' } } ) ,
77+ 'utf-8'
78+ ) ;
79+
80+ await jest . isolateModulesAsync ( async ( ) => {
81+ jest . doMock ( 'cosmiconfig' , ( ) => ( {
82+ cosmiconfig : ( ) => ( {
83+ search : jest . fn ( ) ,
84+ load : jest . fn ( ) . mockResolvedValue ( null ) ,
85+ } ) ,
86+ } ) ) ;
87+
88+ const { loadConfig : isolatedLoadConfig } = await import ( '../src/config/loader' ) ;
89+ const config = await isolatedLoadConfig ( configPath ) ;
90+ expect ( config ) . not . toBeNull ( ) ;
91+ expect ( config ?. output . dir ) . toBe ( './fallback-json' ) ;
92+ expect ( config ?. output . format ) . toBe ( 'json' ) ;
93+ } ) ;
94+ } ) ;
95+
96+ it ( 'falls back to jiti for explicit JS config when cosmiconfig returns null for explicit path' , async ( ) => {
97+ const tempDir = await createTempDir ( ) ;
98+ const configPath = path . join ( tempDir , 'autodocs.config.js' ) ;
99+ await fs . writeFile (
100+ configPath ,
101+ `module.exports = { output: { dir: './fallback-js', format: 'json' } };` ,
102+ 'utf-8'
103+ ) ;
104+
105+ await jest . isolateModulesAsync ( async ( ) => {
106+ jest . doMock ( 'cosmiconfig' , ( ) => ( {
107+ cosmiconfig : ( ) => ( {
108+ search : jest . fn ( ) ,
109+ load : jest . fn ( ) . mockResolvedValue ( null ) ,
110+ } ) ,
111+ } ) ) ;
112+
113+ const { loadConfig : isolatedLoadConfig } = await import ( '../src/config/loader' ) ;
114+ const config = await isolatedLoadConfig ( configPath ) ;
115+ expect ( config ) . not . toBeNull ( ) ;
116+ expect ( config ?. output . dir ) . toBe ( './fallback-js' ) ;
117+ expect ( config ?. output . format ) . toBe ( 'json' ) ;
118+ } ) ;
119+ } ) ;
120+
121+ it ( 'wraps loader errors with a clear message' , async ( ) => {
122+ const tempDir = await createTempDir ( ) ;
123+
124+ await jest . isolateModulesAsync ( async ( ) => {
125+ jest . doMock ( 'cosmiconfig' , ( ) => ( {
126+ cosmiconfig : ( ) => ( {
127+ search : jest . fn ( ) . mockRejectedValue ( new Error ( 'broken loader' ) ) ,
128+ load : jest . fn ( ) ,
129+ } ) ,
130+ } ) ) ;
131+
132+ const { loadConfig : isolatedLoadConfig } = await import ( '../src/config/loader' ) ;
133+ await expect ( isolatedLoadConfig ( tempDir ) ) . rejects . toThrow (
134+ 'Failed to load config: broken loader'
135+ ) ;
136+ } ) ;
137+ } ) ;
138+
34139 it ( 'resolves relative paths' , async ( ) => {
35140 const tempDir = await createTempDir ( ) ;
36141 const config = resolveConfigPaths (
0 commit comments