diff --git a/src/rules/expo-font-loaded-check.ts b/src/rules/expo-font-loaded-check.ts index 0e30739..5237675 100644 --- a/src/rules/expo-font-loaded-check.ts +++ b/src/rules/expo-font-loaded-check.ts @@ -9,16 +9,25 @@ export function expoFontLoadedCheck(ast: File, _code: string): LintResult[] { let usesFontsCall: { line: number; column: number } | null = null; let hasLoadedCheck = false; + let loadedVarName: string | null = null; traverse(ast, { - CallExpression(path) { - const { callee, loc } = path.node; - - // Check for useFonts() call - if (callee.type === 'Identifier' && callee.name === 'useFonts') { + VariableDeclarator(path) { + const { id, init } = path.node; + + // Match: const [loaded, error] = useFonts(...) or const [fontsLoaded] = useFonts(...) + if ( + init?.type === 'CallExpression' && + init.callee.type === 'Identifier' && + init.callee.name === 'useFonts' && + id.type === 'ArrayPattern' && + id.elements.length > 0 && + id.elements[0]?.type === 'Identifier' + ) { + loadedVarName = id.elements[0].name; usesFontsCall = { - line: loc?.start.line ?? 0, - column: loc?.start.column ?? 0, + line: init.loc?.start.line ?? 0, + column: init.loc?.start.column ?? 0, }; } }, @@ -28,21 +37,25 @@ export function expoFontLoadedCheck(ast: File, _code: string): LintResult[] { const { test } = path.node; // Check for `if (!loaded)` or `if (!loaded && !error)` patterns - if (checkForLoadedReference(test)) { + if (loadedVarName !== null && checkForLoadedReference(test, loadedVarName)) { hasLoadedCheck = true; } }, ConditionalExpression(path) { const { test } = path.node; - if (checkForLoadedReference(test)) { + if (loadedVarName !== null && checkForLoadedReference(test, loadedVarName)) { hasLoadedCheck = true; } }, LogicalExpression(path) { const { left, right } = path.node; - if (checkForLoadedReference(left) || checkForLoadedReference(right)) { + if ( + loadedVarName !== null && + (checkForLoadedReference(left, loadedVarName) || + checkForLoadedReference(right, loadedVarName)) + ) { hasLoadedCheck = true; } }, @@ -63,11 +76,11 @@ export function expoFontLoadedCheck(ast: File, _code: string): LintResult[] { return results; } -function checkForLoadedReference(node: any): boolean { +function checkForLoadedReference(node: any, varName: string): boolean { if (!node) return false; // Direct identifier check - if (node.type === 'Identifier' && node.name === 'loaded') { + if (node.type === 'Identifier' && node.name === varName) { return true; } @@ -76,14 +89,16 @@ function checkForLoadedReference(node: any): boolean { node.type === 'UnaryExpression' && node.operator === '!' && node.argument?.type === 'Identifier' && - node.argument.name === 'loaded' + node.argument.name === varName ) { return true; } // Check nested expressions if (node.type === 'LogicalExpression') { - return checkForLoadedReference(node.left) || checkForLoadedReference(node.right); + return ( + checkForLoadedReference(node.left, varName) || checkForLoadedReference(node.right, varName) + ); } return false; diff --git a/tests/expo-font-loaded-check.test.ts b/tests/expo-font-loaded-check.test.ts index 960f259..28a12fa 100644 --- a/tests/expo-font-loaded-check.test.ts +++ b/tests/expo-font-loaded-check.test.ts @@ -54,6 +54,35 @@ describe('expo-font-loaded-check rule', () => { expect(results).toHaveLength(0); }); + it('should allow useFonts with custom variable name for loaded state', () => { + const code = ` + function Component() { + const [fontsLoaded, fontError] = useFonts({ + Inter_400Regular, + Inter_600SemiBold, + Inter_700Bold, + }); + if (!fontsLoaded && !fontError) { + return null; + } + return Hello; + } + `; + const results = lintJsxCode(code, config); + expect(results).toHaveLength(0); + }); + + it('should detect useFonts with custom variable name but no check', () => { + const code = ` + function Component() { + const [fontsLoaded, fontError] = useFonts({ Inter_400Regular }); + return Hello; + } + `; + const results = lintJsxCode(code, config); + expect(results).toHaveLength(1); + }); + it('should detect useFonts with incorrect check', () => { const code = ` function Component() {