Skip to content

Commit

Permalink
Merge branch 'Expensify:main' into add-eslint-rule-for-validating-lef…
Browse files Browse the repository at this point in the history
…t-side-condition
  • Loading branch information
rayane-djouah authored Oct 9, 2024
2 parents fbbe2b2 + f55314a commit 1b61ea9
Show file tree
Hide file tree
Showing 6 changed files with 183 additions and 3 deletions.
1 change: 1 addition & 0 deletions eslint-plugin-expensify/CONST.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,6 @@ module.exports = {
PREFER_TYPE_FEST_TUPLE_TO_UNION: 'Prefer using `TupleToUnion` from `type-fest` for converting tuple types to union types.',
PREFER_TYPE_FEST_VALUE_OF: 'Prefer using `ValueOf` from `type-fest` to extract the type of the properties of an object.',
PREFER_AT: 'Prefer using the `.at()` method for array element access.',
PREFER_SHOULD_USE_NARROW_LAYOUT_INSTEAD_OF_IS_SMALL_SCREEN_WIDTH: 'Prefer using `shouldUseNarrowLayout` instead of `isSmallScreenWidth` from `useResponsiveLayout`.',

Check failure on line 36 in eslint-plugin-expensify/CONST.js

View workflow job for this annotation

GitHub Actions / lint

Trailing spaces not allowed
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
const {AST_NODE_TYPES} = require("@typescript-eslint/utils");

Check failure on line 1 in eslint-plugin-expensify/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth.js

View workflow job for this annotation

GitHub Actions / lint

Strings must use singlequote
const _ = require("underscore");

Check failure on line 2 in eslint-plugin-expensify/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth.js

View workflow job for this annotation

GitHub Actions / lint

Strings must use singlequote
const CONST = require("./CONST");

Check failure on line 3 in eslint-plugin-expensify/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth.js

View workflow job for this annotation

GitHub Actions / lint

Strings must use singlequote

module.exports = {
meta: {

Check failure on line 6 in eslint-plugin-expensify/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth.js

View workflow job for this annotation

GitHub Actions / lint

Expected indentation of 4 spaces but found 2
type: "problem",

Check failure on line 7 in eslint-plugin-expensify/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth.js

View workflow job for this annotation

GitHub Actions / lint

Expected indentation of 8 spaces but found 4

Check failure on line 7 in eslint-plugin-expensify/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth.js

View workflow job for this annotation

GitHub Actions / lint

Strings must use singlequote
docs: {

Check failure on line 8 in eslint-plugin-expensify/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth.js

View workflow job for this annotation

GitHub Actions / lint

Expected indentation of 8 spaces but found 4
description:

Check failure on line 9 in eslint-plugin-expensify/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth.js

View workflow job for this annotation

GitHub Actions / lint

Expected indentation of 12 spaces but found 6
"Warn against using isSmallScreenWidth from useResponsiveLayout and suggest using shouldUseNarrowLayout instead.",

Check failure on line 10 in eslint-plugin-expensify/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth.js

View workflow job for this annotation

GitHub Actions / lint

Strings must use singlequote
},
schema: [],
},
create(context) {

const sourceCode = context.sourceCode ?? context.getSourceCode();

return {
VariableDeclarator(node) {
if (
!node.init ||
!node.init.callee ||
node.init.callee.name !== "useResponsiveLayout"
) {
return;
}

// Check for 'const {isSmallScreenWidth, ...} = useResponsiveLayout();' pattern
if (node.id.type === AST_NODE_TYPES.ObjectPattern) {
node.id.properties.forEach((property) => {
if (!property.key || property.key.name !== "isSmallScreenWidth") {
return;
}
context.report({
node: property,
message:
CONST.MESSAGE
.PREFER_SHOULD_USE_NARROW_LAYOUT_INSTEAD_OF_IS_SMALL_SCREEN_WIDTH,
});
});
}

const scope = sourceCode.getScope ? sourceCode.getScope(node) : context.getScope();

// Check for 'const var = useResponsiveLayout();' and use of this var
const variableName = node.id.name;
const variableUsages = _.filter(
scope.references,
(reference) => reference.identifier.name === variableName
);
variableUsages.forEach((usage) => {
const parent = usage.identifier.parent;

// Check for 'const isSmallScreenWidth = var.isSmallScreenWidth;' pattern
if (
parent.type === AST_NODE_TYPES.MemberExpression &&
parent.property.name === "isSmallScreenWidth"
) {
context.report({
node: parent.property,
message:
CONST.MESSAGE
.PREFER_SHOULD_USE_NARROW_LAYOUT_INSTEAD_OF_IS_SMALL_SCREEN_WIDTH,
});
}

// Check for 'const {isSmallScreenWidth} = var;' pattern
if (
parent.type === AST_NODE_TYPES.VariableDeclarator &&
parent.id.type === AST_NODE_TYPES.ObjectPattern
) {
parent.id.properties.forEach((property) => {
if (!property.key || property.key.name !== "isSmallScreenWidth") {
return;
}
context.report({
node: property,
message:
CONST.MESSAGE
.PREFER_SHOULD_USE_NARROW_LAYOUT_INSTEAD_OF_IS_SMALL_SCREEN_WIDTH,
});
});
}
});
},
MemberExpression(node) {
// Check for 'const isSmallScreenWidth = useResponsiveLayout().isSmallScreenWidth;' pattern
if (
node.object.type !== "CallExpression" ||
node.object.callee.name !== "useResponsiveLayout" ||
node.property.name !== "isSmallScreenWidth"
) {
return;
}
context.report({
node,
message:
CONST.MESSAGE
.PREFER_SHOULD_USE_NARROW_LAYOUT_INSTEAD_OF_IS_SMALL_SCREEN_WIDTH,
});
},
};
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
const RuleTester = require("eslint").RuleTester;
const rule = require("../prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth");
const message =
require("../CONST").MESSAGE
.PREFER_SHOULD_USE_NARROW_LAYOUT_INSTEAD_OF_IS_SMALL_SCREEN_WIDTH;

const ruleTester = new RuleTester({
parserOptions: {
ecmaVersion: 6,
sourceType: "module",
},
});

ruleTester.run(
"prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth",
rule,
{
valid: [
{
code: "const {shouldUseNarrowLayout} = useResponsiveLayout();",
},
],
invalid: [
{
code: "const {isSmallScreenWidth} = useResponsiveLayout();",
errors: [
{
message,
},
],
},
{
code: "const {isSmallScreenWidth, shouldUseNarrowLayout} = useResponsiveLayout();",
errors: [
{
message,
},
],
},
{
code: `
const isSmallScreenWidth = useResponsiveLayout().isSmallScreenWidth;
`,
errors: [
{
message,
},
],
},
{
code: `
const dimensions = useResponsiveLayout();
const isSmallScreenWidth = dimensions.isSmallScreenWidth;
`,
errors: [
{
message,
},
],
},
{
code: `
const dimensions = useResponsiveLayout();
const {isSmallScreenWidth} = dimensions;
`,
errors: [
{
message,
},
],
},
],
}
);
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "eslint-config-expensify",
"version": "2.0.61",
"version": "2.0.62",
"description": "Expensify's ESLint configuration following our style guide",
"main": "index.js",
"repository": {
Expand Down
1 change: 1 addition & 0 deletions rules/expensify.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ module.exports = {
message: 'Please use SafeAreaView from react-native-safe-area-context',
}],
}],
"rulesdir/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth": "warn",
},
};

0 comments on commit 1b61ea9

Please sign in to comment.