import { ASTParser } from '../../src/parser.js'; describe('ASTParser', () => { describe('constructor and parsing', () => { it('should parse valid TypeScript/JSX code', () => { const code = ` import React from 'react'; import { makeStyles } from '@material-ui/core/styles'; const useStyles = makeStyles(() => ({ root: { display: 'flex', padding: 16, }, })); const Component = () =>
Hello
; `; expect(() => new ASTParser(code)).not.toThrow(); }); it('should throw error for invalid syntax', () => { const invalidCode = ` const invalid = { unclosed: "string }; `; expect(() => new ASTParser(invalidCode)).toThrow(/Failed to parse source code/); }); it('should handle empty code', () => { expect(() => new ASTParser('')).not.toThrow(); }); it('should handle complex JSX syntax', () => { const jsxCode = ` import React from 'react'; const Component = () => (
Hello World
); `; expect(() => new ASTParser(jsxCode)).not.toThrow(); }); }); describe('extractMakeStylesCalls', () => { it('should extract simple makeStyles calls', () => { const sourceCode = ` import { makeStyles } from '@material-ui/core/styles'; const useStyles = makeStyles(() => ({ root: { display: 'flex', padding: 16, }, })); `; const parser = new ASTParser(sourceCode); const extractions = parser.extractMakeStylesCalls(); expect(extractions).toHaveLength(1); expect(extractions[0]).toEqual({ importName: 'makeStyles', hookName: 'useStyles', styles: expect.arrayContaining([ expect.objectContaining({ name: 'root', properties: { display: 'flex', padding: 16, }, }), ]), sourceFile: expect.any(String), }); }); it('should return empty array for code without makeStyles', () => { const sourceCode = ` import React from 'react'; const Component = () =>
Hello
; `; const parser = new ASTParser(sourceCode); const extractions = parser.extractMakeStylesCalls(); expect(extractions).toEqual([]); }); it('should handle empty makeStyles call', () => { const sourceCode = ` import { makeStyles } from '@material-ui/core/styles'; const useStyles = makeStyles(() => ({})); `; const parser = new ASTParser(sourceCode); const extractions = parser.extractMakeStylesCalls(); expect(extractions).toHaveLength(1); expect(extractions[0].styles).toEqual([]); }); }); describe('error handling and edge cases', () => { it('should handle malformed makeStyles calls gracefully', () => { const sourceCode = ` import { makeStyles } from '@material-ui/core/styles'; const useStyles = makeStyles(); // No arguments `; const parser = new ASTParser(sourceCode); // Should not throw, but may return empty extractions expect(() => parser.extractMakeStylesCalls()).not.toThrow(); }); it('should handle mixed content with comments', () => { const sourceCode = ` // This is a comment import React from 'react'; import { makeStyles } from '@material-ui/core/styles'; /* Multi-line comment */ const useStyles = makeStyles(() => ({ root: { display: 'flex', // Inline comment padding: 16, }, })); `; const parser = new ASTParser(sourceCode); const extractions = parser.extractMakeStylesCalls(); expect(extractions).toHaveLength(1); expect(extractions[0].hookName).toBe('useStyles'); }); it('should handle TypeScript syntax', () => { const sourceCode = ` import { makeStyles, Theme } from '@material-ui/core/styles'; interface Props { color?: string; } const useStyles = makeStyles((theme) => ({ root: { display: 'flex', }, })); `; const parser = new ASTParser(sourceCode); expect(() => parser.extractMakeStylesCalls()).not.toThrow(); }); }); });