eslint-plugin-raflint 1.4.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3 @@
1
+ import type { ESLint } from 'eslint';
2
+ declare const plugin: ESLint.Plugin;
3
+ export default plugin;
package/dist/index.js ADDED
@@ -0,0 +1,9 @@
1
+ import noConditionalObjectSpread from './rules/noConditionalObjectSpread.js';
2
+ import noPathJoin from './rules/noPathJoin.js';
3
+ const plugin = {
4
+ rules: {
5
+ 'no-conditional-object-spread': noConditionalObjectSpread,
6
+ 'no-path-join': noPathJoin,
7
+ },
8
+ };
9
+ export default plugin;
@@ -0,0 +1,3 @@
1
+ import type { Rule } from 'eslint';
2
+ declare const rule: Rule.RuleModule;
3
+ export default rule;
@@ -0,0 +1,13 @@
1
+ const rule = {
2
+ create: (context) => ({
3
+ SpreadElement(node) {
4
+ if (node.argument.type === 'ConditionalExpression' || node.argument.type === 'LogicalExpression') {
5
+ context.report({
6
+ node,
7
+ message: 'Conditional object spread is not allowed.',
8
+ });
9
+ }
10
+ },
11
+ }),
12
+ };
13
+ export default rule;
@@ -0,0 +1,3 @@
1
+ import type { Rule } from 'eslint';
2
+ declare const rule: Rule.RuleModule;
3
+ export default rule;
@@ -0,0 +1,34 @@
1
+ const rule = {
2
+ meta: {
3
+ type: 'suggestion',
4
+ docs: {
5
+ description: 'Disallow path.join() in favor of template strings',
6
+ recommended: true,
7
+ },
8
+ fixable: 'code',
9
+ schema: [],
10
+ },
11
+ create(context) {
12
+ return {
13
+ CallExpression(node) {
14
+ if (!(node.callee.type === 'MemberExpression' && node.callee.object.name === 'path' && node.callee.property.name === 'join' && node.arguments.length >= 2)) {
15
+ return;
16
+ }
17
+ const sourceCode = context.sourceCode ?? context.getSourceCode();
18
+ const parts = node.arguments.map((argument) => {
19
+ if (argument.type === 'Literal' && typeof argument.value === 'string') {
20
+ return argument.value;
21
+ }
22
+ return `\${${sourceCode.getText(argument)}}`;
23
+ });
24
+ const replacement = `\`${parts.join('/')}\``;
25
+ context.report({
26
+ node,
27
+ message: 'Utilisez des template strings au lieu de path.join() pour la concaténation de chemins simples',
28
+ fix: (fixer) => fixer.replaceText(node, replacement),
29
+ });
30
+ },
31
+ };
32
+ },
33
+ };
34
+ export default rule;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-raflint",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "private": false,
5
5
  "description": "",
6
6
  "keywords": [],
@@ -11,38 +11,48 @@
11
11
  "license": "ISC",
12
12
  "author": "Raphael Piccolo",
13
13
  "type": "module",
14
- "exports": "./index.js",
14
+ "main": "./dist/index.js",
15
+ "exports": "./dist/index.js",
16
+ "types": "./dist/index.d.ts",
17
+ "files": [
18
+ "dist"
19
+ ],
15
20
  "scripts": {
21
+ "build": "tsc",
16
22
  "cov": "c8 npm run test",
17
- "jest": "SILENT=1 node --no-warnings --experimental-vm-modules ./node_modules/.bin/jest",
18
23
  "prepare": "husky",
19
- "test": "SILENT=1 mocha --timeout 15000 {lib,test}/**/*.test.js"
24
+ "prepublishOnly": "npm run build",
25
+ "test": "SILENT=1 mocha --timeout 60000 {,lib/**/,test/**/}*.test.ts"
20
26
  },
21
27
  "dependencies": {
22
- "@babel/eslint-parser": "^7.28.6",
23
- "eslint-plugin-n": "^17.24.0",
24
- "eslint-plugin-sonarjs": "^4.0.2",
25
- "eslint-plugin-unicorn": "^64.0.0"
28
+ "@babel/eslint-parser": "^8.0.1",
29
+ "eslint-plugin-n": "^18.2.1",
30
+ "eslint-plugin-sonarjs": "^4.1.0",
31
+ "eslint-plugin-unicorn": "^69.0.0"
26
32
  },
27
33
  "devDependencies": {
28
- "@eslint/js": "^9.39.4",
29
- "@stoplight/spectral-cli": "^6.15.0",
34
+ "@eslint/js": "^10.0.1",
35
+ "@stoplight/spectral-cli": "^6.16.0",
30
36
  "c8": "^11.0.0",
31
- "eslint": "^9.39.4",
32
- "eslint-plugin-import": "^2.32.0",
33
- "eslint-plugin-promise": "^7.2.1",
34
- "eslint-plugin-raflint": "^1.3.4",
35
- "globals": "^17.4.0",
36
- "html-validate": "^10.11.2",
37
+ "eslint": "^10.5.0",
38
+ "eslint-plugin-import-x": "^4.17.1",
39
+ "eslint-plugin-promise": "^7.3.0",
40
+ "eslint-plugin-raflint": "^1.4.1",
41
+ "globals": "^17.7.0",
37
42
  "husky": "^9.1.7",
38
- "jest": "^30.3.0",
39
- "lint-staged": "^16.4.0",
40
- "markdownlint": "^0.40.0",
41
- "mocha": "^11.7.5",
42
- "prettier": "^3.8.1",
43
- "ts-api-utils": "^2.5.0"
43
+ "lint-staged": "^17.0.8",
44
+ "markdownlint": "^0.41.0",
45
+ "mocha": "^11.7.6",
46
+ "prettier": "^3.9.1",
47
+ "ts-api-utils": "^2.5.0",
48
+ "tsx": "^4.22.4",
49
+ "typescript": "^6.0.3"
44
50
  },
45
51
  "engines": {
46
52
  "node": ">=21.0.0"
53
+ },
54
+ "allowScripts": {
55
+ "unrs-resolver": true,
56
+ "esbuild": true
47
57
  }
48
58
  }
package/TESTING.md DELETED
@@ -1,18 +0,0 @@
1
- # Comment tester la règle no-path-join
2
- ## Test manuel avec le fichier d'exemple
3
-
4
- Un fichier d'exemple `assets/testExample.js` a été créé pour démontrer le fonctionnement de la règle. Pour tester manuellement:
5
-
6
- 1. Vérifier que la règle détecte les problèmes:
7
-
8
- ```bash
9
- npx eslint -c eslinttest.config.js assets/testExample.js
10
- ```
11
-
12
- Vous devriez voir des erreurs pour les lignes contenant `path.join(directory, filename)` et `path.join(process.cwd(), 'file.txt')`.
13
-
14
- 2. Vérifier que la règle corrige automatiquement le code:
15
-
16
- ```bash
17
- npx eslint -c eslinttest.config.js assets/testExample.js --fix
18
- ```
@@ -1,22 +0,0 @@
1
- // Exemple de code utilisant path.join() qui sera détecté par notre règle
2
- import path from 'node:path';
3
-
4
- // Définition des variables pour éviter les erreurs ESLint
5
- const directory = '/home/user';
6
- const filename = 'file.txt';
7
- const root = '/';
8
-
9
- // Ce code sera détecté et corrigé par notre règle
10
- const filePath1 = `${directory}/${filename}`;
11
-
12
- // Ce code sera détecté et corrigé par notre règle
13
- const filePath2 = `${process.cwd()}/file.txt`;
14
-
15
- // Ce code ne sera pas détecté car il a plus de 2 arguments
16
- const filePath3 = path.join(root, directory, filename);
17
-
18
- // Ce code est déjà au format recommandé
19
- const filePath4 = `${directory}/${filename}`;
20
-
21
- // Pour éviter les erreurs "unused variable"
22
- console.log(filePath1, filePath2, filePath3, filePath4);
package/eslint.config.js DELETED
@@ -1,282 +0,0 @@
1
- import sonarjs from 'eslint-plugin-sonarjs';
2
- import unicorn from 'eslint-plugin-unicorn';
3
- import promise from 'eslint-plugin-promise';
4
- import n from 'eslint-plugin-n';
5
- import raflint from 'eslint-plugin-raflint';
6
- import pluginimport from 'eslint-plugin-import';
7
- import babelParser from '@babel/eslint-parser';
8
- import js from '@eslint/js';
9
- import globals from 'globals';
10
-
11
- export default [
12
- // eslint:recommended,
13
- js.configs.recommended,
14
-
15
- // unicorn
16
- unicorn.configs['flat/recommended'],
17
-
18
- // n
19
- n.configs['flat/recommended'],
20
-
21
- // sonarjs
22
- sonarjs.configs.recommended,
23
-
24
- // promise
25
- promise.configs['flat/recommended'],
26
-
27
- // plugin:import/recommended,
28
- pluginimport.flatConfigs.recommended,
29
-
30
- {
31
- ignores: ['node_modules/', 'web/', 'public/', 'coverage/', 'data/', 'vendor/', 'cypress/', 'react/', 'js/', 'assets/', '**/old/'],
32
- },
33
- {
34
- languageOptions: {
35
- globals: {
36
- ...globals.browser,
37
- ...globals.node,
38
- ...globals.mocha,
39
- },
40
- parser: babelParser,
41
- parserOptions: {
42
- ecmaVersion: 'latest',
43
- sourceType: 'module',
44
- requireConfigFile: false,
45
- },
46
- },
47
- plugins: {
48
- raflint,
49
- },
50
- rules: {
51
- 'sonarjs/no-empty-function': 0,
52
- 'sonarjs/no-unused-expressions': 0,
53
- 'sonarjs/no-unsafe-unzip': 0,
54
- 'sonarjs/os-command': 0,
55
- 'sonarjs/cors': 0,
56
- 'sonarjs/publicly-writable-directories': 0,
57
- 'sonarjs/file-permissions': 0,
58
- 'sonarjs/no-empty-test-file': 0,
59
- 'import/no-named-as-default-member': 0,
60
- 'import/no-unresolved': [
61
- 'error',
62
- {
63
- ignore: [
64
- '^yargs/helpers$',
65
- '^p-queue$',
66
- '^@vitejs/plugin-react$',
67
- '^public-ip$',
68
- '^@modelcontextprotocol/sdk/',
69
- '^@maizzle/framework$'
70
- ],
71
- },
72
- ],
73
- 'sonarjs/regex-complexity': 0,
74
- 'sonarjs/no-clear-text-protocols': 0,
75
- 'sonarjs/no-infinite-loop': 0,
76
- 'sonarjs/no-hardcoded-ip': 0,
77
- 'sonarjs/pluginRules-of-hooks': 0,
78
- 'sonarjs/sonar-no-fallthrough': 0,
79
- 'sonarjs/no-ignored-exceptions': 0,
80
- 'sonarjs/slow-regex': 0,
81
- 'sonarjs/concise-regex': 0,
82
- 'sonarjs/hashing': 0,
83
- 'sonarjs/no-dead-store': 0,
84
- 'sonarjs/no-unused-vars': 0,
85
- 'sonarjs/no-hardcoded-passwords': 0,
86
- 'sonarjs/no-hardcoded-secrets': 0,
87
- 'sonarjs/unnecessary-character-escapes': 0,
88
- 'sonarjs/pseudo-random': 0,
89
- 'sonarjs/no-os-command-from-path': 0,
90
- 'sonarjs/anchor-precedence': 0,
91
- 'sonarjs/no-nested-functions': 0,
92
- 'sonarjs/new-cap': 0,
93
- 'sonarjs/sql-queries': 0,
94
- 'sonarjs/content-length': 0,
95
- 'sonarjs/no-commented-code': 0,
96
- 'raflint/no-conditional-object-spread': ['error'],
97
- 'raflint/no-path-join': ['error'],
98
- 'unicorn/prefer-event-target': 0,
99
- 'unicorn/prefer-structured-clone': 0,
100
- 'unicorn/prefer-string-raw': 0,
101
- 'unicorn/no-anonymous-default-export': 0,
102
- 'unicorn/better-regex': 0,
103
- 'unicorn/catch-error-name': 0,
104
- 'unicorn/consistent-function-scoping': 0,
105
- 'unicorn/expiring-todo-comments': 0,
106
- 'unicorn/explicit-length-check': 0,
107
- 'unicorn/import-style': 0,
108
- 'unicorn/no-array-for-each': 0,
109
- 'unicorn/prefer-single-call': 0,
110
- 'unicorn/no-array-reduce': 0,
111
- 'unicorn/no-lonely-if': 0,
112
- 'unicorn/no-negated-condition': 0,
113
- 'unicorn/no-null': 0,
114
- 'unicorn/no-process-exit': 0,
115
- 'unicorn/no-this-assignment': 0,
116
- 'unicorn/no-unnecessary-await': 0,
117
- 'unicorn/no-unused-properties': 0,
118
- 'unicorn/prefer-code-point': 0,
119
- 'unicorn/prefer-default-parameters': 0,
120
- 'unicorn/prefer-export-from': 0,
121
- 'unicorn/prefer-native-coercion-functions': 0,
122
- 'unicorn/prefer-number-properties': 0,
123
- 'unicorn/prefer-set-has': 0,
124
- 'unicorn/prefer-set-size': 0,
125
- 'unicorn/prefer-spread': 0,
126
- 'unicorn/prefer-string-replace-all': 0,
127
- 'unicorn/prefer-string-slice': 0,
128
- 'unicorn/prefer-switch': 0,
129
- 'unicorn/prefer-ternary': 0,
130
- 'unicorn/prefer-top-level-await': 0,
131
- 'unicorn/prevent-abbreviations': 0,
132
- 'unicorn/relative-url-style': 0,
133
- 'unicorn/switch-case-braces': 0,
134
- 'unicorn/template-indent': 0,
135
- 'unicorn/text-encoding-identifier-case': 0,
136
- 'unicorn/prefer-regexp-test': 0,
137
- 'unicorn/prefer-optional-catch-binding': 0,
138
- 'unicorn/filename-case': [
139
- 'error',
140
- {
141
- case: 'camelCase',
142
- },
143
- ],
144
- 'sonarjs/cognitive-complexity': 0,
145
- 'sonarjs/no-nested-template-literals': 0,
146
- 'sonarjs/no-collapsible-if': 0,
147
- 'sonarjs/no-duplicate-string': 0,
148
- 'sonarjs/prefer-immediate-return': 0,
149
- 'sonarjs/no-identical-functions': 0,
150
- 'sonarjs/prefer-object-literal': 0,
151
- 'sonarjs/prefer-single-boolean-return': 0,
152
- 'n/no-unpublished-import': 0,
153
- 'n/no-unsupported-features/es-syntax': 0,
154
- 'n/no-missing-import': 0,
155
- 'n/no-process-exit': 0,
156
-
157
- // si on l'active ça pose pb dans check / automerge
158
- 'n/shebang': 0,
159
-
160
- 'one-var-declaration-per-line': ['error', 'always'],
161
- 'one-var': ['error', 'never'],
162
- 'no-unused-expressions': 'error',
163
- 'no-nested-ternary': 'error',
164
- 'no-use-before-define': [
165
- 'error',
166
- {
167
- functions: false,
168
- classes: false,
169
- variables: true,
170
- allowNamedExports: false,
171
- },
172
- ],
173
- 'no-new-native-nonconstructor': 'error',
174
- 'no-empty-static-block': 'error',
175
- 'symbol-description': 'error',
176
- 'require-yield': 'error',
177
- 'prefer-spread': 'error',
178
- 'prefer-rest-params': 'error',
179
- 'prefer-object-spread': 'error',
180
- 'prefer-object-has-own': 'error',
181
- 'prefer-numeric-literals': 'error',
182
- 'prefer-exponentiation-operator': 'error',
183
- 'operator-assignment': 'error',
184
- 'no-useless-rename': 'error',
185
- 'no-useless-constructor': 'error',
186
- 'no-useless-computed-key': 'error',
187
- 'no-unused-labels': 'error',
188
- 'no-script-url': 'error',
189
- 'no-new-object': 'error',
190
- 'no-multi-assign': 'error',
191
- 'no-loop-func': 'error',
192
- 'no-inline-comments': 'error',
193
- 'no-implicit-coercion': 'error',
194
- 'no-extra-boolean-cast': 'error',
195
- 'no-confusing-arrow': 'error',
196
- 'no-case-declarations': 'error',
197
- 'no-bitwise': 'error',
198
- 'no-array-constructor': 'error',
199
- 'no-alert': 'error',
200
- 'logical-assignment-operators': 'error',
201
- 'grouped-accessor-pairs': 'error',
202
- 'func-name-matching': 'error',
203
- 'dot-notation': 'error',
204
- 'consistent-this': ['error', 'self'],
205
- 'accessor-pairs': 'error',
206
- 'no-unused-private-class-members': 'error',
207
- 'no-promise-executor-return': 'error',
208
- 'no-duplicate-imports': 'error',
209
- 'no-constant-binary-expression': 'error',
210
- 'no-undef-init': 'error',
211
- 'no-label-var': 'error',
212
- 'init-declarations': ['error', 'always'],
213
- 'wrap-iife': ['error', 'inside'],
214
- yoda: 'error',
215
- 'vars-on-top': 'error',
216
- radix: ['error', 'as-needed'],
217
- 'prefer-regex-literals': 'error',
218
- 'prefer-promise-reject-errors': 'error',
219
- 'no-warning-comments': 'error',
220
- 'no-void': 'error',
221
- 'no-useless-return': 'error',
222
- 'no-useless-concat': 'error',
223
- 'no-useless-call': 'error',
224
- 'no-throw-literal': 'error',
225
- 'no-sequences': 'error',
226
- 'no-self-compare': 'error',
227
- 'no-return-assign': 'error',
228
- 'no-proto': 'error',
229
- 'no-octal-escape': 'error',
230
- 'no-nonoctal-decimal-escape': 'error',
231
- 'no-new-wrappers': 'error',
232
- 'no-new-func': 'error',
233
- 'no-new': 'error',
234
- 'no-multi-str': 'error',
235
- 'no-multi-spaces': 'error',
236
- 'no-lone-blocks': 'error',
237
- 'no-labels': 'error',
238
- 'no-iterator': 'error',
239
- 'no-empty-function': 'error',
240
- 'block-scoped-var': 'error',
241
- 'prefer-arrow-callback': 'error',
242
- 'no-implied-eval': 'error',
243
- 'no-implicit-globals': 'error',
244
- 'no-floating-decimal': 'error',
245
- 'no-extra-label': 'error',
246
- 'no-extra-bind': 'error',
247
- 'no-extend-native': [
248
- 'error',
249
- {
250
- exceptions: ['Object'],
251
- },
252
- ],
253
- 'no-eval': 'error',
254
- 'no-constant-condition': ['error', { checkLoops: false }],
255
- 'no-eq-null': 'error',
256
- 'no-else-return': 'error',
257
- 'no-unused-vars': 0,
258
- 'no-console': 0,
259
- 'no-empty': 0,
260
- 'no-redeclare': 0,
261
- 'no-useless-escape': 0,
262
- 'no-var': 'error',
263
- 'object-shorthand': ['error', 'properties'],
264
- 'prefer-template': 'error',
265
- 'no-div-regex': 'error',
266
- 'no-constructor-return': 'error',
267
- 'no-caller': 'error',
268
- 'max-classes-per-file': 'error',
269
- 'default-param-last': 'error',
270
- 'default-case-last': 'error',
271
- 'default-case': 'error',
272
- 'array-callback-return': 'error',
273
- 'no-unsafe-optional-chaining': 'error',
274
- 'no-unreachable-loop': 'error',
275
- 'no-template-curly-in-string': 'error',
276
- 'no-loss-of-precision': 'error',
277
- 'no-inner-declarations': 0,
278
- 'no-process-exit': 0,
279
- 'prefer-const': ['error', { destructuring: 'all' }],
280
- },
281
- },
282
- ];
@@ -1,13 +0,0 @@
1
- import raflintPlugin from './index.js';
2
-
3
- export default [
4
- {
5
- files: ['**/*.js'],
6
- plugins: {
7
- raflint: raflintPlugin,
8
- },
9
- rules: {
10
- 'raflint/no-path-join': 'error',
11
- },
12
- },
13
- ];
package/index.js DELETED
@@ -1,53 +0,0 @@
1
- import noConditionalObjectSpread from './rules/noConditionalObjectSpread.js';
2
- import noPathJoin from './rules/noPathJoin.js';
3
-
4
- export default {
5
- rules: {
6
- 'no-conditional-object-spread': noConditionalObjectSpread,
7
- 'no-path-join': noPathJoin,
8
- },
9
- };
10
-
11
- /*
12
- import path from 'node:path';
13
- import { fileURLToPath } from 'node:url';
14
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
15
- import fs from 'node:fs';
16
- const { name, version } = JSON.parse(await fs.promises.readFile(`${__dirname}/package.json`));
17
-
18
- import noConditionalObjectSpread from './rules/noConditionalObjectSpread.js';
19
- import noPathJoin from './rules/noPathJoin.js';
20
-
21
- const rules = {
22
- 'no-conditional-object-spread': noConditionalObjectSpread,
23
- 'no-path-join': noPathJoin,
24
- };
25
-
26
- export default {
27
- meta: {
28
- name,
29
- version,
30
- },
31
- rules,
32
- configs: {
33
- 'flat/recommended': {
34
- plugins: {
35
- raflint: {
36
- meta: {
37
- name,
38
- version,
39
- },
40
- rules: {
41
- 'raflint/no-conditional-object-spread': "error",
42
- 'raflint/no-path-join': "error"
43
- },
44
- }
45
- },
46
- rules: {
47
- 'raflint/no-conditional-object-spread': "error",
48
- 'raflint/no-path-join': "error"
49
- },
50
- },
51
- }
52
- };
53
- */
package/jest.config.js DELETED
@@ -1,4 +0,0 @@
1
- export default {
2
- transform: {},
3
- testTimeout: 60_000,
4
- };
@@ -1,14 +0,0 @@
1
- export default {
2
- create(context) {
3
- return {
4
- SpreadElement(node) {
5
- if (node.argument.type === 'ConditionalExpression' || node.argument.type === 'LogicalExpression') {
6
- context.report({
7
- node,
8
- message: 'Conditional object spread is not allowed.',
9
- });
10
- }
11
- },
12
- };
13
- },
14
- };
@@ -1,43 +0,0 @@
1
- export default {
2
- meta: {
3
- type: 'suggestion',
4
- docs: {
5
- description: 'Disallow path.join() in favor of template strings',
6
- category: 'Stylistic Issues',
7
- recommended: true,
8
- },
9
- fixable: 'code',
10
- schema: [],
11
- },
12
- create(context) {
13
- return {
14
- CallExpression(node) {
15
- if (
16
- node.callee.type === 'MemberExpression' &&
17
- node.callee.object.name === 'path' &&
18
- node.callee.property.name === 'join' &&
19
- node.arguments.length >= 2
20
- ) {
21
- const sourceCode = context.sourceCode ?? context.getSourceCode();
22
-
23
- const parts = node.arguments.map((arg) => {
24
- if (arg.type === 'Literal' && typeof arg.value === 'string') {
25
- return arg.value;
26
- }
27
- return `\${${sourceCode.getText(arg)}}`;
28
- });
29
-
30
- const replacement = `\`${parts.join('/')}\``;
31
-
32
- context.report({
33
- node,
34
- message: 'Utilisez des template strings au lieu de path.join() pour la concaténation de chemins simples',
35
- fix(fixer) {
36
- return fixer.replaceText(node, replacement);
37
- },
38
- });
39
- }
40
- },
41
- };
42
- },
43
- };
@@ -1,46 +0,0 @@
1
- import { RuleTester } from 'eslint';
2
- import noConditionalObjectSpread from '../rules/noConditionalObjectSpread.js';
3
- import path from 'node:path';
4
- import { fileURLToPath } from 'node:url';
5
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
6
-
7
- const ruleTester = new RuleTester({
8
- languageOptions: {
9
- parser: await import('@babel/eslint-parser'),
10
- ecmaVersion: 'latest',
11
- sourceType: 'module',
12
- parserOptions: {
13
- requireConfigFile: false,
14
- },
15
- },
16
- });
17
-
18
- ruleTester.run('no-conditional-object-spread', noConditionalObjectSpread, {
19
- valid: [
20
- {
21
- code: `
22
- const condition = true;
23
- const obj = {};
24
- if (condition) obj.prop = value;
25
- `,
26
- },
27
- ],
28
- invalid: [
29
- {
30
- code: `
31
- const obj = {
32
- ...(condition ? { prop: 'value' } : {}),
33
- };
34
- `,
35
- errors: [{ message: 'Conditional object spread is not allowed.' }],
36
- },
37
- {
38
- code: `
39
- const obj = {
40
- ...(condition && { prop: 'value' }),
41
- };
42
- `,
43
- errors: [{ message: 'Conditional object spread is not allowed.' }],
44
- },
45
- ],
46
- });
@@ -1,78 +0,0 @@
1
- import { RuleTester } from 'eslint';
2
- import noPathJoin from '../rules/noPathJoin.js';
3
- import path from 'node:path';
4
- import { fileURLToPath } from 'node:url';
5
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
6
-
7
- const ruleTester = new RuleTester({
8
- languageOptions: {
9
- parser: await import('@babel/eslint-parser'),
10
- ecmaVersion: 'latest',
11
- sourceType: 'module',
12
- parserOptions: {
13
- requireConfigFile: false,
14
- },
15
- },
16
- });
17
-
18
- ruleTester.run('no-path-join', noPathJoin, {
19
- valid: [
20
- {
21
- code: `
22
- const filePath = \`\${directory}/\${filename}\`;
23
- `,
24
- },
25
- {
26
- // Cas avec un seul argument (non concerné)
27
- code: `
28
- const filePath = path.join(directory);
29
- `,
30
- },
31
- {
32
- // Cas avec un autre objet que path
33
- code: `
34
- const result = utils.join(a, b);
35
- `,
36
- },
37
- ],
38
- invalid: [
39
- {
40
- code: `
41
- const filePath = path.join(directory, filename);
42
- `,
43
- errors: [{ message: 'Utilisez des template strings au lieu de path.join() pour la concaténation de chemins simples' }],
44
- output: `
45
- const filePath = \`\${directory}/\${filename}\`;
46
- `,
47
- },
48
- {
49
- code: `
50
- const filePath = path.join(process.cwd(), 'file.txt');
51
- `,
52
- errors: [{ message: 'Utilisez des template strings au lieu de path.join() pour la concaténation de chemins simples' }],
53
- output: `
54
- const filePath = \`\${process.cwd()}/file.txt\`;
55
- `,
56
- },
57
- {
58
- // 3 arguments
59
- code: `
60
- const filePath = path.join(root, directory, filename);
61
- `,
62
- errors: [{ message: 'Utilisez des template strings au lieu de path.join() pour la concaténation de chemins simples' }],
63
- output: `
64
- const filePath = \`\${root}/\${directory}/\${filename}\`;
65
- `,
66
- },
67
- {
68
- // Mix variables et littéraux
69
- code: `
70
- const filePath = path.join(root, 'uploads', filename);
71
- `,
72
- errors: [{ message: 'Utilisez des template strings au lieu de path.join() pour la concaténation de chemins simples' }],
73
- output: `
74
- const filePath = \`\${root}/uploads/\${filename}\`;
75
- `,
76
- },
77
- ],
78
- });