From b614205ac390c14b1dc2570c422e35c72f33a4a3 Mon Sep 17 00:00:00 2001 From: Elise DUBILLOT Date: Thu, 17 Aug 2023 11:23:13 +0200 Subject: [PATCH 1/7] add rule avoid-css-animations --- CHANGELOG.md | 1 + eslint-plugin/README.md | 1 + .../docs/rules/avoid-css-animations.md | 24 ++++++ .../lib/rules/avoid-css-animations.js | 61 ++++++++++++++ eslint-plugin/package.json | 2 +- .../tests/lib/rules/avoid-css-animations.js | 80 +++++++++++++++++++ 6 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 eslint-plugin/docs/rules/avoid-css-animations.md create mode 100644 eslint-plugin/lib/rules/avoid-css-animations.js create mode 100644 eslint-plugin/tests/lib/rules/avoid-css-animations.js diff --git a/CHANGELOG.md b/CHANGELOG.md index ccd92e5..6ec9ccf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- [#21](https://github.com/green-code-initiative/ecoCode-javascript/pull/21) Add rule `@ecocode/avoid-css-animations` - [#14](https://github.com/green-code-initiative/ecoCode-javascript/pull/14) Create SonarQube plugin - [#12](https://github.com/green-code-initiative/ecoCode-javascript/issues/12) Pack ESLint plugin into SonarQube plugin - [#16](https://github.com/green-code-initiative/ecoCode-javascript/pull/16) Use centralized rules specifications diff --git a/eslint-plugin/README.md b/eslint-plugin/README.md index c6188f2..d06acf9 100644 --- a/eslint-plugin/README.md +++ b/eslint-plugin/README.md @@ -58,6 +58,7 @@ Add `@ecocode` to the `plugins` section of your `.eslintrc`, followed by rules c | Name | Description | ⚠️ | | :------------------------------------------------------------------------------------- | :--------------------------------------------------------- | :- | +| [avoid-css-animations](docs/rules/avoid-css-animations.md) | Avoid usage of CSS animations | ✅ | | [avoid-high-accuracy-geolocation](docs/rules/avoid-high-accuracy-geolocation.md) | Avoid using high accuracy geolocation in web applications. | ✅ | | [no-import-all-from-library](docs/rules/no-import-all-from-library.md) | Should not import all from library | ✅ | | [no-multiple-access-dom-element](docs/rules/no-multiple-access-dom-element.md) | Disallow multiple access of same DOM element. | ✅ | diff --git a/eslint-plugin/docs/rules/avoid-css-animations.md b/eslint-plugin/docs/rules/avoid-css-animations.md new file mode 100644 index 0000000..bd43381 --- /dev/null +++ b/eslint-plugin/docs/rules/avoid-css-animations.md @@ -0,0 +1,24 @@ +# Avoid usage of CSS animations (`@ecocode/avoid-css-animations`) + +⚠️ This rule _warns_ in the ✅ `recommended` config. + + + +## Rule Details + +This rule aims to limit the usage of all types of CSS animations which can be very costly in terms of CPU and memory. +They must only be used when they are indispensable and should be limited to the CSS properties `opacity` and `transform` with it's associated functions : `translate`, `rotate` and `scale`. +You can also inform the navigator of upcoming changes with the `will-change` instruction for more optimization. + +## Examples +Examples of **non compliant** code for this rule: + +```js +
+``` + +Examples of **compliant** code for this rule: + +```js +
+``` diff --git a/eslint-plugin/lib/rules/avoid-css-animations.js b/eslint-plugin/lib/rules/avoid-css-animations.js new file mode 100644 index 0000000..e23482d --- /dev/null +++ b/eslint-plugin/lib/rules/avoid-css-animations.js @@ -0,0 +1,61 @@ +/** + * Copyright (C) 2023 Green Code Initiative + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +"use strict"; + +/** @type {import('eslint').Rule.RuleModule} */ +module.exports = { + meta: { + type: "suggestion", + docs: { + description: "Avoid usage of CSS animations", + category: "eco-design", + recommended: "warn", + }, + messages: { + AvoidCSSAnimations: "Avoid using {{attribute}} in CSS.", + }, + schema: [], + }, + + create(context) { + return { + JSXOpeningElement(node) { + if (node.attributes.find((attr) => attr.name.name === "style")) { + const styleProp = node.attributes.find( + (attr) => attr.name.name === "style", + ); + + // To prevent (for example)
+ const transformValue = styleProp.value.expression.properties.find( + (prop) => + prop.key.name.includes("transition") || + prop.key.name.includes("animation"), + ); + if (transformValue && transformValue.value) { + context.report({ + node: transformValue, + messageId: "AvoidCSSAnimations", + data: { + attribute: transformValue.key.name, + }, + }); + } + } + }, + }; + }, +}; diff --git a/eslint-plugin/package.json b/eslint-plugin/package.json index 82cb2d0..28e89cb 100644 --- a/eslint-plugin/package.json +++ b/eslint-plugin/package.json @@ -51,4 +51,4 @@ "eslint": ">=7" }, "packageManager": "yarn@3.6.0" -} +} \ No newline at end of file diff --git a/eslint-plugin/tests/lib/rules/avoid-css-animations.js b/eslint-plugin/tests/lib/rules/avoid-css-animations.js new file mode 100644 index 0000000..d7fabe2 --- /dev/null +++ b/eslint-plugin/tests/lib/rules/avoid-css-animations.js @@ -0,0 +1,80 @@ +/** + * Copyright (C) 2023 Green Code Initiative + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const rule = require("../../../lib/rules/avoid-css-animations"); +const RuleTester = require("eslint").RuleTester; + +//------------------------------------------------------------------------------ +// Tests +//------------------------------------------------------------------------------ + +const ruleTester = new RuleTester({ + parserOptions: { + ecmaVersion: 2021, + sourceType: "module", + ecmaFeatures: { + jsx: true, + }, + }, +}); + +ruleTester.run("avoid-css-animations", rule, { + valid: [ + ` + import React from 'react'; + import './styles.css'; // External CSS file + + const MyComponent = () => { + return
This content is styled using an external CSS file.
; + }; + + export default MyComponent; + `, + ], + + invalid: [ + { + code: "
", + errors: [ + { + messageId: "AvoidCSSAnimations", + data: { + attribute: "transition", + }, + type: "Property", + }, + ], + }, + { + code: "
", + errors: [ + { + messageId: "AvoidCSSAnimations", + data: { + attribute: "animationName", + }, + type: "Property", + }, + ], + }, + ], +}); From 5b72e699f169e59d999258c072e91392a1aa1461 Mon Sep 17 00:00:00 2001 From: Elise DUBILLOT Date: Thu, 10 Aug 2023 13:43:57 +0200 Subject: [PATCH 2/7] add rule no-empty-image-src-attribute --- CHANGELOG.md | 1 + eslint-plugin/README.md | 1 + .../rules/no-empty-image-src-attribute.md | 26 +++++++ .../lib/rules/no-empty-image-src-attribute.js | 58 +++++++++++++++ eslint-plugin/tests/lib/files/logo.svg | 0 .../lib/rules/no-empty-image-src-attribute.js | 73 +++++++++++++++++++ 6 files changed, 159 insertions(+) create mode 100644 eslint-plugin/docs/rules/no-empty-image-src-attribute.md create mode 100644 eslint-plugin/lib/rules/no-empty-image-src-attribute.js create mode 100644 eslint-plugin/tests/lib/files/logo.svg create mode 100644 eslint-plugin/tests/lib/rules/no-empty-image-src-attribute.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ec9ccf..21d3c12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - [#21](https://github.com/green-code-initiative/ecoCode-javascript/pull/21) Add rule `@ecocode/avoid-css-animations` +- [#19](https://github.com/green-code-initiative/ecoCode-javascript/pull/19) add rule `@ecocode/no-empty-image-src-attribute` - [#14](https://github.com/green-code-initiative/ecoCode-javascript/pull/14) Create SonarQube plugin - [#12](https://github.com/green-code-initiative/ecoCode-javascript/issues/12) Pack ESLint plugin into SonarQube plugin - [#16](https://github.com/green-code-initiative/ecoCode-javascript/pull/16) Use centralized rules specifications diff --git a/eslint-plugin/README.md b/eslint-plugin/README.md index d06acf9..3241bc1 100644 --- a/eslint-plugin/README.md +++ b/eslint-plugin/README.md @@ -60,6 +60,7 @@ Add `@ecocode` to the `plugins` section of your `.eslintrc`, followed by rules c | :------------------------------------------------------------------------------------- | :--------------------------------------------------------- | :- | | [avoid-css-animations](docs/rules/avoid-css-animations.md) | Avoid usage of CSS animations | ✅ | | [avoid-high-accuracy-geolocation](docs/rules/avoid-high-accuracy-geolocation.md) | Avoid using high accuracy geolocation in web applications. | ✅ | +| [no-empty-image-src-attribute](docs/rules/no-empty-image-src-attribute.md) | Disallow usage of image with empty source attribute | ✅ | | [no-import-all-from-library](docs/rules/no-import-all-from-library.md) | Should not import all from library | ✅ | | [no-multiple-access-dom-element](docs/rules/no-multiple-access-dom-element.md) | Disallow multiple access of same DOM element. | ✅ | | [no-multiple-style-changes](docs/rules/no-multiple-style-changes.md) | Disallow multiple style changes at once. | ✅ | diff --git a/eslint-plugin/docs/rules/no-empty-image-src-attribute.md b/eslint-plugin/docs/rules/no-empty-image-src-attribute.md new file mode 100644 index 0000000..a160a5a --- /dev/null +++ b/eslint-plugin/docs/rules/no-empty-image-src-attribute.md @@ -0,0 +1,26 @@ +# Disallow usage of image with empty source attribute (`@ecocode/no-empty-image-src-attribute`) + +⚠️ This rule _warns_ in the ✅ `recommended` config. + + + +## Rule Details + +This rule aims to prohibit the usage of without specifying its source attribute because it causes extra and unnecessary http requests. This rule is build for the [react library](https://react.dev/) and JSX. + +## Examples + +Examples of **non compliant** code for this rule: + +```js + + +``` + +Examples of **compliant** code for this rule: + +```js +import imgSvg from './img.svg' + + +``` diff --git a/eslint-plugin/lib/rules/no-empty-image-src-attribute.js b/eslint-plugin/lib/rules/no-empty-image-src-attribute.js new file mode 100644 index 0000000..c966fd9 --- /dev/null +++ b/eslint-plugin/lib/rules/no-empty-image-src-attribute.js @@ -0,0 +1,58 @@ +/** + * Copyright (C) 2023 Green Code Initiative + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +"use strict"; + +/** @type {import('eslint').Rule.RuleModule} */ +module.exports = { + meta: { + type: "suggestion", + docs: { + description: "Disallow usage of image with empty source attribute", + category: "eco-design", + recommended: "warn", + }, + messages: { + SpecifySrcAttribute: + "Make sure to specify src attribute when using .", + }, + schema: [], + }, + create(context) { + return { + JSXOpeningElement(node) { + if (node.name.name === "img") { + const srcValue = node.attributes.find( + (attr) => attr.name.name === "src", + ); + if (srcValue && srcValue.value && srcValue.value.value === "") { + //to prevent Empty image + context.report({ + node: srcValue, + messageId: "SpecifySrcAttribute", + }); + } else if (!srcValue) { + //to prevent + context.report({ + node, + messageId: "SpecifySrcAttribute", + }); + } + } + }, + }; + }, +}; diff --git a/eslint-plugin/tests/lib/files/logo.svg b/eslint-plugin/tests/lib/files/logo.svg new file mode 100644 index 0000000..e69de29 diff --git a/eslint-plugin/tests/lib/rules/no-empty-image-src-attribute.js b/eslint-plugin/tests/lib/rules/no-empty-image-src-attribute.js new file mode 100644 index 0000000..4092c49 --- /dev/null +++ b/eslint-plugin/tests/lib/rules/no-empty-image-src-attribute.js @@ -0,0 +1,73 @@ +/** + * Copyright (C) 2023 Green Code Initiative + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const rule = require("../../../lib/rules/no-empty-image-src-attribute"); +const RuleTester = require("eslint").RuleTester; + +//------------------------------------------------------------------------------ +// Tests +//------------------------------------------------------------------------------ + +const ruleTester = new RuleTester({ + parserOptions: { + ecmaVersion: 2021, + sourceType: "module", + ecmaFeatures: { + jsx: true, + }, + }, +}); +const expectedError1 = { + messageId: "SpecifySrcAttribute", + type: "JSXAttribute", +}; +const expectedError2 = { + messageId: "SpecifySrcAttribute", + type: "JSXOpeningElement", +}; + +ruleTester.run("image-src-attribute-not-empty", rule, { + valid: [ + ` + This is a SVG image + `, + ` + import logoSvg from "../files/logo.svg"; + This is a SVG image + `, + ], + + invalid: [ + { + code: ` + + `, + errors: [expectedError1], + }, + { + code: ` + This is an empty image + `, + errors: [expectedError2], + }, + ], +}); From 414b552007fd362bc7b06935f6607e55c57c6b70 Mon Sep 17 00:00:00 2001 From: utarwyn Date: Fri, 4 Aug 2023 20:07:28 +0200 Subject: [PATCH 3/7] Add provenance when publishing package --- .github/workflows/publish.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 9658d49..5a2b6ae 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -14,6 +14,8 @@ env: jobs: publish-npm: runs-on: ubuntu-latest + permissions: + id-token: write steps: - name: Checkout tag "${{ github.ref_name }}" uses: actions/checkout@v3 @@ -34,7 +36,7 @@ jobs: run: cp LICENSE.md eslint-plugin/ - name: Publish package on NPM - run: npm publish --access public + run: npm publish --provenance --access public working-directory: eslint-plugin env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} From 2fdb01fd32746ab162ef5386fef8163abaec15c5 Mon Sep 17 00:00:00 2001 From: utarwyn Date: Tue, 8 Aug 2023 19:35:10 +0200 Subject: [PATCH 4/7] Simplify list of files to pack with npm --- eslint-plugin/.npmignore | 5 ----- eslint-plugin/package.json | 3 +++ 2 files changed, 3 insertions(+), 5 deletions(-) delete mode 100644 eslint-plugin/.npmignore diff --git a/eslint-plugin/.npmignore b/eslint-plugin/.npmignore deleted file mode 100644 index 70ba64f..0000000 --- a/eslint-plugin/.npmignore +++ /dev/null @@ -1,5 +0,0 @@ -* -!lib/**/* -!package.json -!LICENSE.md -!README.md diff --git a/eslint-plugin/package.json b/eslint-plugin/package.json index 28e89cb..7308521 100644 --- a/eslint-plugin/package.json +++ b/eslint-plugin/package.json @@ -17,6 +17,9 @@ "license": "GPL-3.0", "author": "Green Code Initiative", "main": "./lib/standalone.js", + "files": [ + "lib" + ], "scripts": { "clean": "rimraf dist", "lint": "npm-run-all \"lint:*\"", From 3ff14101fdf078cad53e84a8d871636566671739 Mon Sep 17 00:00:00 2001 From: Elise DUBILLOT Date: Tue, 25 Jul 2023 14:11:56 +0200 Subject: [PATCH 5/7] add rule limit-db-query-results --- CHANGELOG.md | 1 + eslint-plugin/README.md | 1 + .../docs/rules/limit-db-query-results.md | 23 +++++++ .../lib/rules/limit-db-query-results.js | 55 ++++++++++++++++ .../tests/lib/rules/limit-db-query-results.js | 62 +++++++++++++++++++ 5 files changed, 142 insertions(+) create mode 100644 eslint-plugin/docs/rules/limit-db-query-results.md create mode 100644 eslint-plugin/lib/rules/limit-db-query-results.js create mode 100644 eslint-plugin/tests/lib/rules/limit-db-query-results.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 21d3c12..7025945 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [#21](https://github.com/green-code-initiative/ecoCode-javascript/pull/21) Add rule `@ecocode/avoid-css-animations` - [#19](https://github.com/green-code-initiative/ecoCode-javascript/pull/19) add rule `@ecocode/no-empty-image-src-attribute` +- [#18](https://github.com/green-code-initiative/ecoCode-javascript/pull/18) add rule `@ecocode/limit-db-query-results` - [#14](https://github.com/green-code-initiative/ecoCode-javascript/pull/14) Create SonarQube plugin - [#12](https://github.com/green-code-initiative/ecoCode-javascript/issues/12) Pack ESLint plugin into SonarQube plugin - [#16](https://github.com/green-code-initiative/ecoCode-javascript/pull/16) Use centralized rules specifications diff --git a/eslint-plugin/README.md b/eslint-plugin/README.md index 3241bc1..0caeb20 100644 --- a/eslint-plugin/README.md +++ b/eslint-plugin/README.md @@ -60,6 +60,7 @@ Add `@ecocode` to the `plugins` section of your `.eslintrc`, followed by rules c | :------------------------------------------------------------------------------------- | :--------------------------------------------------------- | :- | | [avoid-css-animations](docs/rules/avoid-css-animations.md) | Avoid usage of CSS animations | ✅ | | [avoid-high-accuracy-geolocation](docs/rules/avoid-high-accuracy-geolocation.md) | Avoid using high accuracy geolocation in web applications. | ✅ | +| [limit-db-query-results](docs/rules/limit-db-query-results.md) | Should limit the number of returns for a SQL query | ✅ | | [no-empty-image-src-attribute](docs/rules/no-empty-image-src-attribute.md) | Disallow usage of image with empty source attribute | ✅ | | [no-import-all-from-library](docs/rules/no-import-all-from-library.md) | Should not import all from library | ✅ | | [no-multiple-access-dom-element](docs/rules/no-multiple-access-dom-element.md) | Disallow multiple access of same DOM element. | ✅ | diff --git a/eslint-plugin/docs/rules/limit-db-query-results.md b/eslint-plugin/docs/rules/limit-db-query-results.md new file mode 100644 index 0000000..4626876 --- /dev/null +++ b/eslint-plugin/docs/rules/limit-db-query-results.md @@ -0,0 +1,23 @@ +# Should limit the number of returns for a SQL query (`@ecocode/limit-db-query-results`) + +⚠️ This rule _warns_ in the ✅ `recommended` config. + + + +## Rule Details + +This rule aims at reducing CPU consumption by limiting the number of returns for a single SQL query. + +## Examples + +Examples of **non compliant** code for this rule: + +```js +const query = "SELECT * FROM clients"; +``` + +Examples of **compliant** code for this rule: + +```js +const query = "SELECT columns FROM table_name FETCH FIRST number ROWS ONLY"; +``` diff --git a/eslint-plugin/lib/rules/limit-db-query-results.js b/eslint-plugin/lib/rules/limit-db-query-results.js new file mode 100644 index 0000000..9a7b2e7 --- /dev/null +++ b/eslint-plugin/lib/rules/limit-db-query-results.js @@ -0,0 +1,55 @@ +/** + * Copyright (C) 2023 Green Code Initiative + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +"use strict"; + +/** @type {import('eslint').Rule.RuleModule} */ +module.exports = { + meta: { + type: "suggestion", + docs: { + description: "Should limit the number of returns for a SQL query", + category: "eco-design", + recommended: "warn", + }, + messages: { + LimitTheNumberOfReturns: + "Try and limit the number of data returned for a single query (by using the LIMIT keyword for example)", + }, + schema: [], + }, + create(context) { + //list of limiting clauses to check against + const limitingClauses = ["LIMIT", "TOP", "ROW_NUMBER", "FETCH FIRST"]; + return { + Literal: function (node) { + if (typeof node.value == "string") { + const query = node.value.toUpperCase(); + if ( + query.includes("SELECT") && + query.includes("FROM") && + !limitingClauses.some((clause) => query.includes(clause)) + ) { + context.report({ + node: node, + messageId: "LimitTheNumberOfReturns", + }); + } + } + }, + }; + }, +}; diff --git a/eslint-plugin/tests/lib/rules/limit-db-query-results.js b/eslint-plugin/tests/lib/rules/limit-db-query-results.js new file mode 100644 index 0000000..6658c42 --- /dev/null +++ b/eslint-plugin/tests/lib/rules/limit-db-query-results.js @@ -0,0 +1,62 @@ +/** + * Copyright (C) 2023 Green Code Initiative + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +"use strict"; +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const rule = require("../../../lib/rules/limit-db-query-results"), + RuleTester = require("eslint").RuleTester; + +//------------------------------------------------------------------------------ +// Tests +//------------------------------------------------------------------------------ + +const ruleTester = new RuleTester({ + parserOptions: { + ecmaVersion: 6, + sourceType: "module", + }, +}); +const expectedError = { + messageId: "LimitTheNumberOfReturns", + type: "Literal", +}; + +ruleTester.run("limit-db-query-results", rule, { + valid: [ + ` + const query = "SELECT * FROM customers LIMIT 10;"; + `, + ` + const query = "SELECT TOP 5 * FROM products;"; + `, + ` + const query = "SELECT * FROM orders FETCH FIRST 20 ROWS ONLY;"; + `, + ` + const query = "WITH numbered_customers AS (SELECT *, ROW_NUMBER() OVER (ORDER BY customer_id) AS row_num FROM customers) SELECT * FROM numbered_customers WHERE row_num <= 50;"; + `, + ], + + invalid: [ + { + code: `const query = "SELECT * FROM bikes;";`, + errors: [expectedError], + }, + ], +}); From 962e05a30b87afa17bfcbf05047b466a94c72183 Mon Sep 17 00:00:00 2001 From: utarwyn Date: Fri, 18 Aug 2023 00:33:22 +0200 Subject: [PATCH 6/7] PR #21 feedbacks --- .../docs/rules/avoid-css-animations.md | 17 +++++++++---- .../lib/rules/avoid-css-animations.js | 25 ++++++++++--------- eslint-plugin/package.json | 2 +- .../tests/lib/rules/avoid-css-animations.js | 1 + 4 files changed, 27 insertions(+), 18 deletions(-) diff --git a/eslint-plugin/docs/rules/avoid-css-animations.md b/eslint-plugin/docs/rules/avoid-css-animations.md index bd43381..7fca356 100644 --- a/eslint-plugin/docs/rules/avoid-css-animations.md +++ b/eslint-plugin/docs/rules/avoid-css-animations.md @@ -6,19 +6,26 @@ ## Rule Details -This rule aims to limit the usage of all types of CSS animations which can be very costly in terms of CPU and memory. -They must only be used when they are indispensable and should be limited to the CSS properties `opacity` and `transform` with it's associated functions : `translate`, `rotate` and `scale`. -You can also inform the navigator of upcoming changes with the `will-change` instruction for more optimization. +This rule aims to limit the usage of all types of CSS animations which can be very costly in terms of CPU and memory. +They must only be used when they are indispensable and should be limited to the CSS properties `opacity` and `transform` +with it's associated functions : `translate`, `rotate` and `scale`. You can also inform the navigator of upcoming +changes with the `will-change` instruction for more optimization. ## Examples + Examples of **non compliant** code for this rule: ```js -
+
``` Examples of **compliant** code for this rule: ```js -
+
``` + +## Further details + +This recommendation is made by the +CNUMR: [Avoid JavaScript / CSS animations](https://github.com/cnumr/best-practices/blob/main/chapters/BP_039_en.md) diff --git a/eslint-plugin/lib/rules/avoid-css-animations.js b/eslint-plugin/lib/rules/avoid-css-animations.js index e23482d..fa1b7f1 100644 --- a/eslint-plugin/lib/rules/avoid-css-animations.js +++ b/eslint-plugin/lib/rules/avoid-css-animations.js @@ -30,27 +30,28 @@ module.exports = { }, schema: [], }, - create(context) { + const forbiddenProperties = ["transition", "animation"]; return { JSXOpeningElement(node) { - if (node.attributes.find((attr) => attr.name.name === "style")) { - const styleProp = node.attributes.find( - (attr) => attr.name.name === "style", - ); + const styleAttribute = node.attributes.find( + (attribute) => attribute.name.name === "style", + ); - // To prevent (for example)
- const transformValue = styleProp.value.expression.properties.find( + if (styleAttribute != null) { + // To prevent (for example)
+ const property = styleAttribute.value.expression.properties.find( (prop) => - prop.key.name.includes("transition") || - prop.key.name.includes("animation"), + forbiddenProperties.some((forbidProp) => + prop.key.name.includes(forbidProp), + ), ); - if (transformValue && transformValue.value) { + if (property != null) { context.report({ - node: transformValue, + node: property, messageId: "AvoidCSSAnimations", data: { - attribute: transformValue.key.name, + attribute: property.key.name, }, }); } diff --git a/eslint-plugin/package.json b/eslint-plugin/package.json index 7308521..d0a2e2b 100644 --- a/eslint-plugin/package.json +++ b/eslint-plugin/package.json @@ -54,4 +54,4 @@ "eslint": ">=7" }, "packageManager": "yarn@3.6.0" -} \ No newline at end of file +} diff --git a/eslint-plugin/tests/lib/rules/avoid-css-animations.js b/eslint-plugin/tests/lib/rules/avoid-css-animations.js index d7fabe2..0cc3e14 100644 --- a/eslint-plugin/tests/lib/rules/avoid-css-animations.js +++ b/eslint-plugin/tests/lib/rules/avoid-css-animations.js @@ -49,6 +49,7 @@ ruleTester.run("avoid-css-animations", rule, { export default MyComponent; `, + `
Hello world
`, ], invalid: [ From 2879047a5ecd3971287aec8a5ac7a83b68579c10 Mon Sep 17 00:00:00 2001 From: utarwyn Date: Fri, 18 Aug 2023 01:00:43 +0200 Subject: [PATCH 7/7] Fix error when style attribute is not an object --- eslint-plugin/lib/rules/avoid-css-animations.js | 2 +- eslint-plugin/tests/lib/rules/avoid-css-animations.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/eslint-plugin/lib/rules/avoid-css-animations.js b/eslint-plugin/lib/rules/avoid-css-animations.js index fa1b7f1..9f9d8cc 100644 --- a/eslint-plugin/lib/rules/avoid-css-animations.js +++ b/eslint-plugin/lib/rules/avoid-css-animations.js @@ -38,7 +38,7 @@ module.exports = { (attribute) => attribute.name.name === "style", ); - if (styleAttribute != null) { + if (styleAttribute && styleAttribute.value.expression) { // To prevent (for example)
const property = styleAttribute.value.expression.properties.find( (prop) => diff --git a/eslint-plugin/tests/lib/rules/avoid-css-animations.js b/eslint-plugin/tests/lib/rules/avoid-css-animations.js index 0cc3e14..20a2fce 100644 --- a/eslint-plugin/tests/lib/rules/avoid-css-animations.js +++ b/eslint-plugin/tests/lib/rules/avoid-css-animations.js @@ -50,6 +50,7 @@ ruleTester.run("avoid-css-animations", rule, { export default MyComponent; `, `
Hello world
`, + `
My red element
`, ], invalid: [