Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed Lint issues and updated Eslint rules #2163

Open
wants to merge 12 commits into
base: develop
Choose a base branch
from
Open
89 changes: 72 additions & 17 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
const MAX_PARAMS = 4;
const JSX_INDENT_SIZE = 2;

module.exports = {
env: {
node: true,
browser: true,
es2020: true,
},
extends: ['eslint:recommended', 'plugin:@typescript-eslint/eslint-recommended', 'plugin:@typescript-eslint/recommended', 'plugin:react/recommended', 'plugin:storybook/recommended'],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react/recommended',
'plugin:storybook/recommended',
'plugin:import/recommended', // Add this line to include recommended rules from eslint-plugin-import
],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaFeatures: {
Expand All @@ -13,55 +23,95 @@ module.exports = {
ecmaVersion: 11,
sourceType: 'module',
},
plugins: ['react', '@typescript-eslint', '@emotion', 'cypress'],
plugins: ['react', '@typescript-eslint', '@emotion', 'cypress', 'import'], // Add 'import' here
rules: {
// General JavaScript/TypeScript
'no-console': 'warn',
'no-debugger': 'error',
'prefer-const': 'warn',
'no-var': 'error',
'consistent-return': 'warn',
eqeqeq: ['error', 'always'],
'@typescript-eslint/explicit-module-boundary-types': 'warn',
'@typescript-eslint/explicit-function-return-type': 'warn',

// React Best Practices
'react/jsx-key': 'error',
'react/no-array-index-key': 'warn',
'react/jsx-curly-brace-presence': [
'warn',
{ props: 'never', children: 'never' },
],

// Code Quality
complexity: ['warn', { max: 10 }],
'max-lines': [
'warn',
{ max: 300, skipBlankLines: true, skipComments: true },
],
'max-params': ['warn', MAX_PARAMS],
'no-magic-numbers': ['warn', { ignore: [0, 1] }],

// Security
'no-eval': 'error',
'no-new-func': 'error',

// Existing Rules
'no-undef': 'warn',
'no-unsafe-optional-chaining': 'warn',
'no-use-before-define': 'off',
'@typescript-eslint/no-use-before-define': 'warn',
'no-empty-pattern': 'warn',
// base rule disabled as it can report incorrect errors
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': [
'warn', // or "error"
'warn',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
caughtErrorsIgnorePattern: '^_',
},
],

'react/react-in-jsx-scope': 'off',
'react/jsx-props-no-spreading': 'off',
'react/jsx-props-no-spreading': 'warn',
'react/jsx-filename-extension': [
1,
'warn',
{ extensions: ['.js', '.jsx', '.tsx'] },
],
'react/no-unknown-property': [
2,
'error',
{
ignore: ['jsx', 'global'],
},
],
'react/jsx-indent': 'off',
'import/extensions': 'off',
'import/no-unresolved': 'off',
'react/jsx-indent': ['warn', JSX_INDENT_SIZE],
'import/extensions': [
'warn',
'always',
{
js: 'never',
jsx: 'never',
ts: 'never',
tsx: 'never',
},
],
mohitb35 marked this conversation as resolved.
Show resolved Hide resolved
'import/no-unresolved': 'warn', // should be error
'import/named': 'warn', // should be error
'react/jsx-no-literals': 'off',
'@typescript-eslint/ban-types': 'off',
'@typescript-eslint/no-empty-interface': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/ban-types': 'warn',
'@typescript-eslint/no-empty-interface': 'warn',
'@typescript-eslint/no-empty-function': 'warn',
'react/display-name': 'off',
'react/no-find-dom-node': 'off',
'@emotion/jsx-import': 'error',
'@emotion/no-vanilla': 'error',
'@emotion/import-from-emotion': 'error',
'@emotion/styled-import': 'error',
'@typescript-eslint/no-var-requires': 0,
'react/prop-types': 'off',
'@typescript-eslint/no-var-requires': 'warn',
'react/prop-types': 'warn',
'cypress/no-assigning-return-values': 'error',
'cypress/no-unnecessary-waiting': 'error',
'cypress/assertion-before-screenshot': 'warn',
'cypress/no-force': 'warn',
'cypress/no-force': 'error',
'cypress/no-async-tests': 'error',
'cypress/no-pause': 'error',
},
Expand All @@ -70,4 +120,9 @@ module.exports = {
cy: true,
NodeJS: true,
},
settings: {
'import/resolver': {
typescript: {},
},
},
};
112 changes: 112 additions & 0 deletions ESLintREADME.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# ESLint Rules Overview
This document provides an overview of the ESLint rules configured for our project, including what each rule does, why it's important, and how to address issues or ignore the rule if necessary.

## General JavaScript/TypeScript Rules
### no-console
- What It Does: Warns when console.log statements are used in the code.
- Why It's Needed: Console statements can leave debug logs in production code, which can be a security risk or clutter the output.
- How to Fix: Remove console.log statements or replace them with a proper logging mechanism.
- Ignore If: You might need to ignore this rule during development if you frequently use console.log for debugging.

### no-debugger
- What It Does: Disallows the use of debugger statements.
- Why It's Needed: debugger statements can stop the execution of code, which might cause issues in production.
- How to Fix: Remove debugger statements before committing code.
- Ignore If: Only if debugging in development, but ensure to remove before deployment.

### prefer-const
- What It Does: Encourages the use of const for variables that are never reassigned.
- Why It's Needed: Using const improves readability and ensures variables that should not be reassigned are not mistakenly changed.
- How to Fix: Replace let with const for variables that do not get reassigned.
- Ignore If: You have a variable that must be reassigned or if your code does not follow this practice due to specific reasons.

### no-var
- What It Does: Enforces the use of let and const instead of var.
- Why It's Needed: var has function-scoped behavior which can lead to unexpected issues. let and const are block-scoped and provide better predictability.
- How to Fix: Replace var with let or const.
- Ignore If: Rare cases where var is needed due to legacy code or specific JavaScript patterns.

### consistent-return
- What It Does: Ensures that all code paths in a function either return a value or do not return a value.
- Why It's Needed: This rule helps avoid bugs by ensuring functions have a predictable return behavior.
- How to Fix: Ensure that all return paths in a function return a value if required, or explicitly return undefined if no value is intended.
- Ignore If: Only if there's a deliberate design choice to not consistently return values, but it's better to address the inconsistency.

### eqeqeq
- What It Does: Enforces the use of === and !== instead of == and !=.
- Why It's Needed: == and != perform type coercion which can lead to unexpected results. Using === and !== ensures strict comparison.
- How to Fix: Replace == and != with === and !==.
- Ignore If: In specific cases where type coercion is intentionally desired.

### @typescript-eslint/explicit-module-boundary-types
- What It Does: Enforces explicit return types on functions and class methods.
- Why It's Needed: Ensures that the types of function outputs are clear, which improves code readability and type safety.
- How to Fix: Explicitly define return types for all functions and methods.
- Ignore If: Only if you are certain that the return type is clear without explicit annotation, but it's generally better to define it.


### @typescript-eslint/explicit-function-return-type
- What It Does: Enforces explicit return types for functions.
- Why It's Needed: Helps with code clarity and maintainability by ensuring all functions have clearly defined return types.
- How to Fix: Add return types to all functions.
- Ignore If: Only in cases where the return type is obvious from the context or if the function is a small utility.

## React Best Practices
### react/jsx-key
- What It Does: Ensures that all elements in a list have a key prop.
- Why It's Needed: key helps React identify which items have changed, are added, or are removed, optimizing rendering.
- How to Fix: Add a unique key prop to all elements in an array or iterator.
- Ignore If: Only in cases where you are certain that the key is not necessary or if the list is static and does not change.

### react/no-array-index-key
- What It Does: Disallows using array indices as keys in React lists.
- Why It's Needed: Array indices can cause issues with component state and performance if the list changes dynamically.
- How to Fix: Use unique and stable identifiers for keys instead of array indices.
- Ignore If: Only if the list is static and the use of indices does not impact the functionality.

### react/jsx-curly-brace-presence
- What It Does: Enforces the use of curly braces for expressions in JSX.
- Why It's Needed: Improves readability by making it clear where expressions are used in JSX.
- How to Fix: Wrap JSX expressions in curly braces.
- Ignore If: Only if you have a compelling reason not to use curly braces for JSX expressions.


## Code Quality

### complexity
- What It Does: Limits the complexity of functions to keep them manageable.
- Why It's Needed: Keeps functions simple and easier to understand, reducing the likelihood of bugs.
- How to Fix: Refactor functions to reduce complexity by breaking them into smaller, more manageable pieces.
- Ignore If: Only in cases where the function's complexity is unavoidable due to the nature of the logic.

### max-lines
- What It Does: Limits the number of lines in a file.
- Why It's Needed: Encourages modular code by keeping files small and focused.
- How to Fix: Break large files into smaller modules or components.
- Ignore If: Only if the file size is justified by the functionality and modularization is not practical.

### max-params
- What It Does: Limits the number of parameters a function can have.
- Why It's Needed: Reduces complexity by keeping functions focused and easier to understand.
- How to Fix: Refactor functions to use fewer parameters, possibly by grouping related parameters into objects.
- Ignore If: Only if the function's complexity and number of parameters are justified.

### no-magic-numbers
- What It Does: Disallows the use of magic numbers (hard-coded numeric values without explanation).
- Why It's Needed: Improves code readability by replacing magic numbers with named constants or variables.
- How to Fix: Define constants for magic numbers and use them in your code.
- Ignore If: Only if the number is self-explanatory or used in a very limited context.

## Security

### no-eval
- What It Does: Disallows the use of eval().
- Why It's Needed: eval() can execute arbitrary code and may introduce security risks.
- How to Fix: Avoid using eval() and find alternative ways to achieve the desired functionality.
- Ignore If: Only if eval() is absolutely necessary and you are aware of the security implications.

### no-new-func
- What It Does: Disallows the use of the Function constructor.
- Why It's Needed: The Function constructor can execute arbitrary code and has similar risks as eval().
- How to Fix: Replace Function constructor usage with safer alternatives.
- Ignore If: Only if the Function constructor is essential for a specific, well-understood case.
10 changes: 5 additions & 5 deletions cypress/support/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
Cypress.Commands.add('spainDonation', () => {
cy.visit(Cypress.env('TEST_SERVER') + '/yucatan');
cy.skipIntroVideo();
cy.wait(5000);

Check notice on line 48 in cypress/support/commands.js

View check run for this annotation

codefactor.io / CodeFactor

cypress/support/commands.js#L48

No magic number: 5000. (no-magic-numbers)
cy.get('[data-test-id="donateButton"]').click();
cy.contactForm(
'Peter',
Expand Down Expand Up @@ -87,7 +87,7 @@
cy.get('[data-test-id="test-donateButton"]')
.click()
.then(() => {
cy.wait(15000).then(() => {

Check notice on line 90 in cypress/support/commands.js

View check run for this annotation

codefactor.io / CodeFactor

cypress/support/commands.js#L90

No magic number: 15000. (no-magic-numbers)
// cy.get('#test-source-authorize-3ds').click()
cy.get('[data-test-id="test-thankYou"]').should('exist');
});
Expand Down Expand Up @@ -180,7 +180,7 @@
cy.visit(Cypress.env('TEST_SERVER'));
cy.skipIntroVideo();
cy.visit(Cypress.env('TEST_SERVER') + '/s/sagar-aryal')
.wait(10000)

Check notice on line 183 in cypress/support/commands.js

View check run for this annotation

codefactor.io / CodeFactor

cypress/support/commands.js#L183

No magic number: 10000. (no-magic-numbers)
.then(() => {
cy.get('[data-test-id="searchIcon"]').type('yucatan restoration');
cy.get('#ProjSnippetDonate_proj_WZkyugryh35sMmZMmXCwq7YY').click();
Expand Down Expand Up @@ -211,15 +211,15 @@

Cypress.Commands.add('projectDetails', () => {
//define a variable consisting alphabets in small and capital letter
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz';
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz';

Check warning on line 214 in cypress/support/commands.js

View check run for this annotation

codefactor.io / CodeFactor

cypress/support/commands.js#L214

Unexpected var, use let or const instead. (no-var)

//specify the length for the new string
var lenString = 4;
var randomstring = '';
const lenString = 4;
let randomstring = '';

//loop to select a new character in each iteration
for (var i = 0; i < lenString; i++) {
var rnum = Math.floor(Math.random() * characters.length);
for (let i = 0; i < lenString; i++) {

Check warning on line 221 in cypress/support/commands.js

View check run for this annotation

codefactor.io / CodeFactor

cypress/support/commands.js#L221

Unexpected var, use let or const instead. (no-var)
const rnum = Math.floor(Math.random() * characters.length);

Check warning on line 222 in cypress/support/commands.js

View check run for this annotation

codefactor.io / CodeFactor

cypress/support/commands.js#L222

Unexpected var, use let or const instead. (no-var)
randomstring += characters.substring(rnum, rnum + 1);
console.log(`randomstring`, randomstring);
}
Expand All @@ -227,7 +227,7 @@
//display the generated string
// document.getElementById("slug").innerHTML = randomstring;
cy.visit(Cypress.env('TEST_SERVER') + '/profile/projects/add-project');
cy.wait(20000);

Check notice on line 230 in cypress/support/commands.js

View check run for this annotation

codefactor.io / CodeFactor

cypress/support/commands.js#L230

No magic number: 20000. (no-magic-numbers)
cy.get('[data-test-id="projectName"]').type('Peter Farm');
cy.get('[data-test-id="slug"]').type(randomstring);
cy.get('[data-test-id="classification"]').click();
Expand All @@ -248,7 +248,7 @@
cy.get('[data-test-id="plantingDensity"]').type('100');
cy.get('[data-test-id="employeeCount"]').type('20');
cy.get('[data-test-id="detailAnalysisCont"]').click();
cy.wait(5000);

Check notice on line 251 in cypress/support/commands.js

View check run for this annotation

codefactor.io / CodeFactor

cypress/support/commands.js#L251

No magic number: 5000. (no-magic-numbers)
cy.get('[data-test-id="siteName"]').type(randomstring);
cy.get('[data-test-id="siteStatus"]').click();
cy.contains('Planted').click();
Expand Down
Loading
Loading