Skip to content

Commit

Permalink
Fix lint errors
Browse files Browse the repository at this point in the history
  • Loading branch information
rayane-djouah committed Oct 3, 2024
1 parent e12b697 commit 4ba4cbc
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 62 deletions.
98 changes: 51 additions & 47 deletions eslint-plugin-expensify/boolean-conditional-rendering.js
Original file line number Diff line number Diff line change
@@ -1,51 +1,55 @@
const { ESLintUtils } = require('@typescript-eslint/utils');
const _ = require('underscore');
const {ESLintUtils} = require('@typescript-eslint/utils');

module.exports = {
name: 'boolean-conditional-rendering',
meta: {
type: 'problem',
docs: {
description: 'Enforce boolean conditions in React conditional rendering',
recommended: 'error',
name: 'boolean-conditional-rendering',
meta: {
type: 'problem',
docs: {
description: 'Enforce boolean conditions in React conditional rendering',
recommended: 'error',
},
schema: [],
messages: {
nonBooleanConditional:
'The left side of conditional rendering should be a boolean, not "{{type}}".',
},
},
schema: [],
messages: {
nonBooleanConditional: 'The left side of conditional rendering should be a boolean, not \"{{type}}\".',
},
},
defaultOptions: [],
create(context) {
const parserServices = ESLintUtils.getParserServices(context);
const typeChecker = parserServices.program.getTypeChecker();
return {
LogicalExpression(node) {
if (node.operator === '&&' && isJSXElement(node.right)) {
const leftType = typeChecker.getTypeAtLocation(
parserServices.esTreeNodeToTSNodeMap.get(node.left)
);
if (!isBoolean(leftType)) {
const baseType = typeChecker.getBaseTypeOfLiteralType(leftType);
context.report({
node: node.left,
messageId: 'nonBooleanConditional',
data: {
type: typeChecker.typeToString(baseType),
},
});
}
defaultOptions: [],
create(context) {
function isJSXElement(node) {
return node.type === 'JSXElement' || node.type === 'JSXFragment';
}
function isBoolean(type) {
return (
// eslint-disable-next-line no-bitwise
(type.getFlags() & (16 | 528 | 512)) !== 0 // TypeFlags.Boolean | TypeFlags.BooleanLike | TypeFlags.BooleanLiteral
|| (type.isUnion()
// eslint-disable-next-line no-bitwise
&& _.every(type.types, t => (t.getFlags() & (16 | 528 | 512)) !== 0))
);
}
},
};
function isJSXElement(node) {
return node.type === 'JSXElement' || node.type === 'JSXFragment';
}
function isBoolean(type) {
return (
(type.getFlags() & (16 | 528 | 512)) !== 0 || // TypeFlags.Boolean | TypeFlags.BooleanLike | TypeFlags.BooleanLiteral
(type.isUnion() && type.types.every(t =>
(t.getFlags() & (16 | 528 | 512)) !== 0 // TypeFlags.Boolean | TypeFlags.BooleanLike | TypeFlags.BooleanLiteral
))
);
}
},
}
const parserServices = ESLintUtils.getParserServices(context);
const typeChecker = parserServices.program.getTypeChecker();
return {
LogicalExpression(node) {
if (!(node.operator === '&&' && isJSXElement(node.right))) {
return;
}
const leftType = typeChecker.getTypeAtLocation(
parserServices.esTreeNodeToTSNodeMap.get(node.left),
);
if (!isBoolean(leftType)) {
const baseType = typeChecker.getBaseTypeOfLiteralType(leftType);
context.report({
node: node.left,
messageId: 'nonBooleanConditional',
data: {
type: typeChecker.typeToString(baseType),
},
});
}
},
};
},
};
28 changes: 14 additions & 14 deletions eslint-plugin-expensify/tests/boolean-conditional-rendering.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ ruleTester.run('boolean-conditional-rendering', rule, {
errors: [
{
messageId: 'nonBooleanConditional',
data: { type: 'string' },
data: {type: 'string'},
},
],
},
Expand All @@ -107,7 +107,7 @@ ruleTester.run('boolean-conditional-rendering', rule, {
errors: [
{
messageId: 'nonBooleanConditional',
data: { type: 'number' },
data: {type: 'number'},
},
],
},
Expand All @@ -119,7 +119,7 @@ ruleTester.run('boolean-conditional-rendering', rule, {
errors: [
{
messageId: 'nonBooleanConditional',
data: { type: 'any[]' },
data: {type: 'any[]'},
},
],
},
Expand All @@ -131,7 +131,7 @@ ruleTester.run('boolean-conditional-rendering', rule, {
errors: [
{
messageId: 'nonBooleanConditional',
data: { type: '{}' },
data: {type: '{}'},
},
],
},
Expand All @@ -143,7 +143,7 @@ ruleTester.run('boolean-conditional-rendering', rule, {
errors: [
{
messageId: 'nonBooleanConditional',
data: { type: 'any' },
data: {type: 'any'},
},
],
},
Expand All @@ -155,7 +155,7 @@ ruleTester.run('boolean-conditional-rendering', rule, {
errors: [
{
messageId: 'nonBooleanConditional',
data: { type: 'any' },
data: {type: 'any'},
},
],
},
Expand All @@ -167,7 +167,7 @@ ruleTester.run('boolean-conditional-rendering', rule, {
errors: [
{
messageId: 'nonBooleanConditional',
data: { type: 'void' },
data: {type: 'void'},
},
],
},
Expand All @@ -179,7 +179,7 @@ ruleTester.run('boolean-conditional-rendering', rule, {
errors: [
{
messageId: 'nonBooleanConditional',
data: { type: 'unknown' },
data: {type: 'unknown'},
},
],
},
Expand All @@ -191,7 +191,7 @@ ruleTester.run('boolean-conditional-rendering', rule, {
errors: [
{
messageId: 'nonBooleanConditional',
data: { type: 'string | boolean' },
data: {type: 'string | boolean'},
},
],
},
Expand All @@ -203,7 +203,7 @@ ruleTester.run('boolean-conditional-rendering', rule, {
errors: [
{
messageId: 'nonBooleanConditional',
data: { type: 'any' },
data: {type: 'any'},
},
],
},
Expand All @@ -216,7 +216,7 @@ ruleTester.run('boolean-conditional-rendering', rule, {
errors: [
{
messageId: 'nonBooleanConditional',
data: { type: 'string' },
data: {type: 'string'},
},
],
},
Expand All @@ -228,7 +228,7 @@ ruleTester.run('boolean-conditional-rendering', rule, {
errors: [
{
messageId: 'nonBooleanConditional',
data: { type: 'Promise<boolean>' },
data: {type: 'Promise<boolean>'},
},
],
},
Expand All @@ -240,7 +240,7 @@ ruleTester.run('boolean-conditional-rendering', rule, {
errors: [
{
messageId: 'nonBooleanConditional',
data: { type: 'string' },
data: {type: 'string'},
},
],
},
Expand All @@ -252,7 +252,7 @@ ruleTester.run('boolean-conditional-rendering', rule, {
errors: [
{
messageId: 'nonBooleanConditional',
data: { type: 'string' },
data: {type: 'string'},
},
],
},
Expand Down
1 change: 0 additions & 1 deletion rules/expensify.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ module.exports = {
message: 'Please use SafeAreaView from react-native-safe-area-context',
}],
}],
'rulesdir/boolean-conditional-rendering': 'error',
},
};

0 comments on commit 4ba4cbc

Please sign in to comment.