@@ -80,3 +80,139 @@ test("takeAndProcessSnapshot: skips coverage files without user scripts", async
8080 fs . rmSync ( tmpDir , { recursive : true , force : true } ) ;
8181 }
8282} ) ;
83+
84+ // --- Babel plugin selection and parsing tests ---
85+
86+ test ( "Babel plugin selection: TypeScript files get typescript and decorators-legacy plugins" , ( t ) => {
87+ const scriptPath = "/project/src/service.ts" ;
88+ const isTypeScript = / \. ( t s | t s x | m t s | c t s ) $ / . test ( scriptPath ) ;
89+ const isTSX = / \. t s x $ / . test ( scriptPath ) ;
90+ const babelPlugins : string [ ] = isTypeScript
91+ ? [ "typescript" , "decorators-legacy" , ...( isTSX ? [ "jsx" ] : [ ] ) ]
92+ : [ "decorators-legacy" ] ;
93+
94+ t . deepEqual ( babelPlugins , [ "typescript" , "decorators-legacy" ] ) ;
95+ } ) ;
96+
97+ test ( "Babel plugin selection: TSX files get typescript, decorators-legacy, and jsx plugins" , ( t ) => {
98+ const scriptPath = "/project/src/Component.tsx" ;
99+ const isTypeScript = / \. ( t s | t s x | m t s | c t s ) $ / . test ( scriptPath ) ;
100+ const isTSX = / \. t s x $ / . test ( scriptPath ) ;
101+ const babelPlugins : string [ ] = isTypeScript
102+ ? [ "typescript" , "decorators-legacy" , ...( isTSX ? [ "jsx" ] : [ ] ) ]
103+ : [ "decorators-legacy" ] ;
104+
105+ t . deepEqual ( babelPlugins , [ "typescript" , "decorators-legacy" , "jsx" ] ) ;
106+ } ) ;
107+
108+ test ( "Babel plugin selection: .mts files get typescript and decorators-legacy plugins" , ( t ) => {
109+ const scriptPath = "/project/src/module.mts" ;
110+ const isTypeScript = / \. ( t s | t s x | m t s | c t s ) $ / . test ( scriptPath ) ;
111+ const isTSX = / \. t s x $ / . test ( scriptPath ) ;
112+ const babelPlugins : string [ ] = isTypeScript
113+ ? [ "typescript" , "decorators-legacy" , ...( isTSX ? [ "jsx" ] : [ ] ) ]
114+ : [ "decorators-legacy" ] ;
115+
116+ t . deepEqual ( babelPlugins , [ "typescript" , "decorators-legacy" ] ) ;
117+ } ) ;
118+
119+ test ( "Babel plugin selection: .cts files get typescript and decorators-legacy plugins" , ( t ) => {
120+ const scriptPath = "/project/src/commonjs.cts" ;
121+ const isTypeScript = / \. ( t s | t s x | m t s | c t s ) $ / . test ( scriptPath ) ;
122+ const isTSX = / \. t s x $ / . test ( scriptPath ) ;
123+ const babelPlugins : string [ ] = isTypeScript
124+ ? [ "typescript" , "decorators-legacy" , ...( isTSX ? [ "jsx" ] : [ ] ) ]
125+ : [ "decorators-legacy" ] ;
126+
127+ t . deepEqual ( babelPlugins , [ "typescript" , "decorators-legacy" ] ) ;
128+ } ) ;
129+
130+ test ( "Babel plugin selection: JavaScript files get only decorators-legacy plugin" , ( t ) => {
131+ const scriptPath = "/project/src/service.js" ;
132+ const isTypeScript = / \. ( t s | t s x | m t s | c t s ) $ / . test ( scriptPath ) ;
133+ const isTSX = / \. t s x $ / . test ( scriptPath ) ;
134+ const babelPlugins : string [ ] = isTypeScript
135+ ? [ "typescript" , "decorators-legacy" , ...( isTSX ? [ "jsx" ] : [ ] ) ]
136+ : [ "decorators-legacy" ] ;
137+
138+ t . deepEqual ( babelPlugins , [ "decorators-legacy" ] ) ;
139+ } ) ;
140+
141+ test ( "Babel plugin selection: .mjs files get only decorators-legacy plugin" , ( t ) => {
142+ const scriptPath = "/project/src/module.mjs" ;
143+ const isTypeScript = / \. ( t s | t s x | m t s | c t s ) $ / . test ( scriptPath ) ;
144+ const isTSX = / \. t s x $ / . test ( scriptPath ) ;
145+ const babelPlugins : string [ ] = isTypeScript
146+ ? [ "typescript" , "decorators-legacy" , ...( isTSX ? [ "jsx" ] : [ ] ) ]
147+ : [ "decorators-legacy" ] ;
148+
149+ t . deepEqual ( babelPlugins , [ "decorators-legacy" ] ) ;
150+ } ) ;
151+
152+ test ( "Babel plugin selection: .cjs files get only decorators-legacy plugin" , ( t ) => {
153+ const scriptPath = "/project/src/commonjs.cjs" ;
154+ const isTypeScript = / \. ( t s | t s x | m t s | c t s ) $ / . test ( scriptPath ) ;
155+ const isTSX = / \. t s x $ / . test ( scriptPath ) ;
156+ const babelPlugins : string [ ] = isTypeScript
157+ ? [ "typescript" , "decorators-legacy" , ...( isTSX ? [ "jsx" ] : [ ] ) ]
158+ : [ "decorators-legacy" ] ;
159+
160+ t . deepEqual ( babelPlugins , [ "decorators-legacy" ] ) ;
161+ } ) ;
162+
163+ // --- Babel parser integration tests ---
164+
165+ test ( "Babel parser: can parse TypeScript with parameter decorators (decorators-legacy)" , ( t ) => {
166+ // eslint-disable-next-line @typescript-eslint/no-var-requires
167+ const babelParser = require ( "@babel/parser" ) ;
168+ const tsCode = `
169+ class Service {
170+ constructor(@inject('repo') private repo: any) {}
171+ }
172+ ` ;
173+
174+ // Should parse without error using decorators-legacy
175+ const ast = babelParser . parse ( tsCode , {
176+ sourceType : "module" ,
177+ plugins : [ "typescript" , "decorators-legacy" ] ,
178+ } ) ;
179+
180+ t . truthy ( ast ) ;
181+ t . is ( ast . type , "File" ) ;
182+ } ) ;
183+
184+ test ( "Babel parser: can parse TSX with JSX syntax" , ( t ) => {
185+ // eslint-disable-next-line @typescript-eslint/no-var-requires
186+ const babelParser = require ( "@babel/parser" ) ;
187+ const tsxCode = `
188+ const Component = () => <div>Hello</div>;
189+ export { Component };
190+ ` ;
191+
192+ // Should parse without error using typescript + jsx + decorators-legacy
193+ const ast = babelParser . parse ( tsxCode , {
194+ sourceType : "module" ,
195+ plugins : [ "typescript" , "decorators-legacy" , "jsx" ] ,
196+ } ) ;
197+
198+ t . truthy ( ast ) ;
199+ t . is ( ast . type , "File" ) ;
200+ } ) ;
201+
202+ test ( "Babel parser: can parse JavaScript with class decorators" , ( t ) => {
203+ // eslint-disable-next-line @typescript-eslint/no-var-requires
204+ const babelParser = require ( "@babel/parser" ) ;
205+ const jsCode = `
206+ @decorator
207+ class Example {}
208+ ` ;
209+
210+ // Should parse without error using decorators-legacy
211+ const ast = babelParser . parse ( jsCode , {
212+ sourceType : "module" ,
213+ plugins : [ "decorators-legacy" ] ,
214+ } ) ;
215+
216+ t . truthy ( ast ) ;
217+ t . is ( ast . type , "File" ) ;
218+ } ) ;
0 commit comments