eslint-plugin-unicorn 4.0.0 → 5.0.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.
package/index.js CHANGED
@@ -34,7 +34,7 @@ module.exports = {
34
34
  'unicorn/regex-shorthand': 'error',
35
35
  'unicorn/prefer-spread': 'error',
36
36
  'unicorn/error-message': 'error',
37
- 'unicorn/no-unsafe-regex': 'error',
37
+ 'unicorn/no-unsafe-regex': 'off',
38
38
  'unicorn/prefer-add-event-listener': 'error'
39
39
  }
40
40
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-unicorn",
3
- "version": "4.0.0",
3
+ "version": "5.0.0",
4
4
  "description": "Various awesome ESLint rules",
5
5
  "license": "MIT",
6
6
  "repository": "sindresorhus/eslint-plugin-unicorn",
@@ -10,10 +10,10 @@
10
10
  "url": "sindresorhus.com"
11
11
  },
12
12
  "engines": {
13
- "node": ">=4"
13
+ "node": ">=6"
14
14
  },
15
15
  "scripts": {
16
- "test": "xo && nyc ava",
16
+ "test": "nyc ava",
17
17
  "integration": "./test/integration/test.js",
18
18
  "coveralls": "nyc report --reporter=text-lcov | coveralls"
19
19
  },
@@ -46,17 +46,17 @@
46
46
  "chalk": "^2.0.1",
47
47
  "coveralls": "^3.0.0",
48
48
  "del": "^3.0.0",
49
- "eslint": "^4.0.0",
49
+ "eslint": "^5.0.0",
50
50
  "eslint-ava-rule-tester": "^2.0.0",
51
- "execa": "^0.9.0",
52
- "listr": "^0.13.0",
53
- "nyc": "^11.0.3",
51
+ "execa": "^0.10.0",
52
+ "listr": "^0.14.1",
53
+ "nyc": "^12.0.2",
54
54
  "pify": "^3.0.0",
55
55
  "tempy": "^0.2.1",
56
56
  "xo": "*"
57
57
  },
58
58
  "peerDependencies": {
59
- "eslint": ">=4"
59
+ "eslint": ">=5.0.0"
60
60
  },
61
61
  "ava": {
62
62
  "files": [
package/readme.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  > Various awesome ESLint rules
6
6
 
7
- You might want to check out [XO](https://github.com/sindresorhus/xo), which includes this plugin.
7
+ You might want to check out [XO](https://github.com/xojs/xo), which includes this plugin.
8
8
 
9
9
 
10
10
  ## Install
@@ -26,7 +26,7 @@ Configure it in `package.json`.
26
26
  "es6": true
27
27
  },
28
28
  "parserOptions": {
29
- "ecmaVersion": 2017,
29
+ "ecmaVersion": 2018,
30
30
  "sourceType": "module"
31
31
  },
32
32
  "plugins": [
@@ -53,7 +53,7 @@ Configure it in `package.json`.
53
53
  "unicorn/regex-shorthand": "error",
54
54
  "unicorn/prefer-spread": "error",
55
55
  "unicorn/error-message": "error",
56
- "unicorn/no-unsafe-regex": "error",
56
+ "unicorn/no-unsafe-regex": "off",
57
57
  "unicorn/prefer-add-event-listener": "error"
58
58
  }
59
59
  }
Binary file
@@ -4,13 +4,13 @@ const getDocsUrl = require('./utils/get-docs-url');
4
4
 
5
5
  // Matches `someObj.then([FunctionExpression | ArrowFunctionExpression])`
6
6
  function isLintablePromiseCatch(node) {
7
- const callee = node.callee;
7
+ const {callee} = node;
8
8
 
9
9
  if (callee.type !== 'MemberExpression') {
10
10
  return false;
11
11
  }
12
12
 
13
- const property = callee.property;
13
+ const {property} = callee;
14
14
 
15
15
  if (property.type !== 'Identifier' || property.name !== 'catch') {
16
16
  return false;
@@ -20,7 +20,7 @@ function isLintablePromiseCatch(node) {
20
20
  return false;
21
21
  }
22
22
 
23
- const arg0 = node.arguments[0];
23
+ const [arg0] = node.arguments;
24
24
 
25
25
  return arg0.type === 'FunctionExpression' || arg0.type === 'ArrowFunctionExpression';
26
26
  }
@@ -42,7 +42,7 @@ const create = context => {
42
42
  caughtErrorsIgnorePattern: '^_$'
43
43
  }, context.options[0]);
44
44
 
45
- const name = options.name;
45
+ const {name} = options;
46
46
  const caughtErrorsIgnorePattern = new RegExp(options.caughtErrorsIgnorePattern);
47
47
  const stack = [];
48
48
 
@@ -68,7 +68,7 @@ const create = context => {
68
68
  return {
69
69
  CallExpression: node => {
70
70
  if (isLintablePromiseCatch(node)) {
71
- const params = node.arguments[0].params;
71
+ const {params} = node.arguments[0];
72
72
 
73
73
  if (params.length > 0 && params[0].name === '_') {
74
74
  push(!astUtils.containsIdentifier('_', node.arguments[0].body));
@@ -115,7 +115,7 @@ module.exports = {
115
115
  create,
116
116
  meta: {
117
117
  docs: {
118
- url: getDocsUrl()
118
+ url: getDocsUrl(__filename)
119
119
  },
120
120
  schema
121
121
  }
@@ -18,10 +18,10 @@ const hasValidSuperClass = node => {
18
18
  return false;
19
19
  }
20
20
 
21
- let name = node.superClass.name;
21
+ let {name} = node.superClass;
22
22
 
23
23
  if (node.superClass.type === 'MemberExpression') {
24
- name = node.superClass.property.name;
24
+ ({name} = node.superClass.property);
25
25
  }
26
26
 
27
27
  return nameRegexp.test(name);
@@ -48,7 +48,7 @@ const customErrorDefinition = (context, node) => {
48
48
  return;
49
49
  }
50
50
 
51
- const name = node.id.name;
51
+ const {name} = node.id;
52
52
  const className = getClassName(name);
53
53
 
54
54
  if (name !== className) {
@@ -58,8 +58,7 @@ const customErrorDefinition = (context, node) => {
58
58
  });
59
59
  }
60
60
 
61
- const body = node.body.body;
62
-
61
+ const {body} = node.body;
63
62
  const constructor = body.find(x => x.kind === 'constructor');
64
63
 
65
64
  if (!constructor) {
@@ -132,7 +131,7 @@ module.exports = {
132
131
  create,
133
132
  meta: {
134
133
  docs: {
135
- url: getDocsUrl()
134
+ url: getDocsUrl(__filename)
136
135
  },
137
136
  fixable: 'code'
138
137
  }
@@ -91,7 +91,7 @@ module.exports = {
91
91
  create,
92
92
  meta: {
93
93
  docs: {
94
- url: getDocsUrl()
94
+ url: getDocsUrl(__filename)
95
95
  }
96
96
  }
97
97
  };
@@ -56,7 +56,7 @@ module.exports = {
56
56
  create,
57
57
  meta: {
58
58
  docs: {
59
- url: getDocsUrl()
59
+ url: getDocsUrl(__filename)
60
60
  },
61
61
  fixable: 'code'
62
62
  }
@@ -12,7 +12,8 @@ function reportError(context, node, message, fixDetails) {
12
12
  node,
13
13
  message,
14
14
  fix: fixDetails && (fixer => {
15
- return fixer.replaceText(node,
15
+ return fixer.replaceText(
16
+ node,
16
17
  `${context.getSourceCode().getText(fixDetails.node)} ${fixDetails.operator} ${fixDetails.value}`
17
18
  );
18
19
  })
@@ -21,7 +22,8 @@ function reportError(context, node, message, fixDetails) {
21
22
 
22
23
  function checkZeroType(context, node) {
23
24
  if (node.operator === '<' && node.right.value === 1) {
24
- reportError(context,
25
+ reportError(
26
+ context,
25
27
  node,
26
28
  'Zero `.length` should be compared with `=== 0`.',
27
29
  {
@@ -34,15 +36,17 @@ function checkZeroType(context, node) {
34
36
  }
35
37
 
36
38
  function checkNonZeroType(context, node, type) {
37
- const value = node.right.value;
38
- const operator = node.operator;
39
+ const {value} = node.right;
40
+ const {operator} = node;
39
41
 
40
42
  switch (type) {
41
43
  case 'greater-than':
42
- if ((operatorTypes.gte.indexOf(operator) !== -1 && value === 1) ||
43
- (operatorTypes.ne.indexOf(operator) !== -1 && value === 0)
44
+ if (
45
+ (operatorTypes.gte.includes(operator) && value === 1) ||
46
+ (operatorTypes.ne.includes(operator) && value === 0)
44
47
  ) {
45
- reportError(context,
48
+ reportError(
49
+ context,
46
50
  node,
47
51
  'Non-zero `.length` should be compared with `> 0`.',
48
52
  {
@@ -54,10 +58,12 @@ function checkNonZeroType(context, node, type) {
54
58
  }
55
59
  break;
56
60
  case 'greater-than-or-equal':
57
- if ((operatorTypes.gt.indexOf(operator) !== -1 && value === 0) ||
58
- (operatorTypes.ne.indexOf(operator) !== -1 && value === 0)
61
+ if (
62
+ (operatorTypes.gt.includes(operator) && value === 0) ||
63
+ (operatorTypes.ne.includes(operator) && value === 0)
59
64
  ) {
60
- reportError(context,
65
+ reportError(
66
+ context,
61
67
  node,
62
68
  'Non-zero `.length` should be compared with `>= 1`.',
63
69
  {
@@ -69,10 +75,12 @@ function checkNonZeroType(context, node, type) {
69
75
  }
70
76
  break;
71
77
  case 'not-equal':
72
- if ((operatorTypes.gt.indexOf(operator) !== -1 && value === 0) ||
73
- (operatorTypes.gte.indexOf(operator) !== -1 && value === 1)
78
+ if (
79
+ (operatorTypes.gt.includes(operator) && value === 0) ||
80
+ (operatorTypes.gte.includes(operator) && value === 1)
74
81
  ) {
75
- reportError(context,
82
+ reportError(
83
+ context,
76
84
  node,
77
85
  'Non-zero `.length` should be compared with `!== 0`.',
78
86
  {
@@ -128,6 +136,9 @@ const create = context => {
128
136
  return {
129
137
  IfStatement: node => {
130
138
  checkExpression(context, node.test);
139
+ },
140
+ ConditionalExpression: node => {
141
+ checkExpression(context, node.test);
131
142
  }
132
143
  };
133
144
  };
@@ -149,7 +160,7 @@ module.exports = {
149
160
  create,
150
161
  meta: {
151
162
  docs: {
152
- url: getDocsUrl()
163
+ url: getDocsUrl(__filename)
153
164
  },
154
165
  fixable: 'code',
155
166
  schema
@@ -116,7 +116,7 @@ module.exports = {
116
116
  create,
117
117
  meta: {
118
118
  docs: {
119
- url: getDocsUrl()
119
+ url: getDocsUrl(__filename)
120
120
  },
121
121
  schema
122
122
  }
@@ -26,7 +26,7 @@ module.exports = {
26
26
  create,
27
27
  meta: {
28
28
  docs: {
29
- url: getDocsUrl()
29
+ url: getDocsUrl(__filename)
30
30
  },
31
31
  fixable: 'code'
32
32
  }
@@ -36,7 +36,7 @@ const disallowNew = new Set([
36
36
  const create = context => {
37
37
  return {
38
38
  CallExpression: node => {
39
- const name = node.callee.name;
39
+ const {name} = node.callee;
40
40
 
41
41
  if (enforceNew.has(name)) {
42
42
  context.report({
@@ -47,7 +47,7 @@ const create = context => {
47
47
  }
48
48
  },
49
49
  NewExpression: node => {
50
- const name = node.callee.name;
50
+ const {name} = node.callee;
51
51
 
52
52
  if (disallowNew.has(name)) {
53
53
  context.report({
@@ -67,7 +67,7 @@ module.exports = {
67
67
  create,
68
68
  meta: {
69
69
  docs: {
70
- url: getDocsUrl()
70
+ url: getDocsUrl(__filename)
71
71
  },
72
72
  fixable: 'code'
73
73
  }
@@ -5,11 +5,12 @@ const disableRegex = /^eslint-disable(-next-line|-line)?($|(\s+(@[\w-]+\/[\w-]+\
5
5
 
6
6
  const create = context => ({
7
7
  Program: node => {
8
- node.comments.forEach(comment => {
8
+ for (const comment of node.comments) {
9
9
  const value = comment.value.trim();
10
10
  const res = disableRegex.exec(value);
11
11
 
12
- if (res && // It's a eslint-disable comment
12
+ if (
13
+ res && // It's a eslint-disable comment
13
14
  !res[2] // But it did not specify any rules
14
15
  ) {
15
16
  context.report({
@@ -24,7 +25,7 @@ const create = context => ({
24
25
  data: comment.loc.start
25
26
  });
26
27
  }
27
- });
28
+ }
28
29
  }
29
30
  });
30
31
 
@@ -32,7 +33,7 @@ module.exports = {
32
33
  create,
33
34
  meta: {
34
35
  docs: {
35
- url: getDocsUrl()
36
+ url: getDocsUrl(__filename)
36
37
  }
37
38
  }
38
39
  };
@@ -20,7 +20,7 @@ module.exports = {
20
20
  create,
21
21
  meta: {
22
22
  docs: {
23
- url: getDocsUrl()
23
+ url: getDocsUrl(__filename)
24
24
  },
25
25
  fixable: 'code'
26
26
  }
@@ -34,7 +34,7 @@ const fix = (context, node) => {
34
34
  const create = context => ({
35
35
  'CallExpression[callee.object.name!="Promise"]': node => {
36
36
  if (isIteratorMethod(node) && hasFunctionArgument(node)) {
37
- const arg = node.arguments[0];
37
+ const [arg] = node.arguments;
38
38
 
39
39
  context.report({
40
40
  node: arg,
@@ -49,7 +49,7 @@ module.exports = {
49
49
  create,
50
50
  meta: {
51
51
  docs: {
52
- url: getDocsUrl()
52
+ url: getDocsUrl(__filename)
53
53
  },
54
54
  fixable: 'code'
55
55
  }
@@ -29,7 +29,7 @@ module.exports = {
29
29
  create,
30
30
  meta: {
31
31
  docs: {
32
- url: getDocsUrl()
32
+ url: getDocsUrl(__filename)
33
33
  },
34
34
  fixable: 'code'
35
35
  }
@@ -25,7 +25,7 @@ module.exports = {
25
25
  create,
26
26
  meta: {
27
27
  docs: {
28
- url: getDocsUrl()
28
+ url: getDocsUrl(__filename)
29
29
  },
30
30
  fixable: 'code'
31
31
  }
@@ -12,7 +12,7 @@ const create = context => {
12
12
 
13
13
  return {
14
14
  CallExpression: node => {
15
- const callee = node.callee;
15
+ const {callee} = node;
16
16
 
17
17
  if (callee.type === 'MemberExpression' && callee.object.name === 'process') {
18
18
  if (callee.property.name === 'on' || callee.property.name === 'once') {
@@ -40,7 +40,7 @@ module.exports = {
40
40
  create,
41
41
  meta: {
42
42
  docs: {
43
- url: getDocsUrl()
43
+ url: getDocsUrl(__filename)
44
44
  }
45
45
  }
46
46
  };
@@ -32,7 +32,7 @@ const create = context => {
32
32
  let flags = null;
33
33
 
34
34
  if (hasRegExp) {
35
- pattern = args[0].regex.pattern;
35
+ ({pattern} = args[0].regex);
36
36
  flags = args[1] && args[1].type === 'Literal' ? args[1].value : args[0].regex.flags;
37
37
  } else {
38
38
  pattern = args[0].value;
@@ -53,7 +53,7 @@ module.exports = {
53
53
  create,
54
54
  meta: {
55
55
  docs: {
56
- url: getDocsUrl()
56
+ url: getDocsUrl(__filename)
57
57
  }
58
58
  }
59
59
  };
@@ -33,7 +33,7 @@ module.exports = {
33
33
  create,
34
34
  meta: {
35
35
  docs: {
36
- url: getDocsUrl()
36
+ url: getDocsUrl(__filename)
37
37
  },
38
38
  fixable: 'code'
39
39
  }
@@ -18,7 +18,7 @@ const fix = (fixer, sourceCode, assignmentNode, memberExpression) => {
18
18
  const isOnEvent = memberExpression => {
19
19
  if (memberExpression.type === 'MemberExpression') {
20
20
  const eventMethodName = getEventMethodName(memberExpression);
21
- if (eventMethodName.startsWith('on')) {
21
+ if (eventMethodName && eventMethodName.startsWith('on')) {
22
22
  return eventTypes.has(getEventTypeName(eventMethodName));
23
23
  }
24
24
  }
@@ -45,7 +45,7 @@ module.exports = {
45
45
  create,
46
46
  meta: {
47
47
  docs: {
48
- url: getDocsUrl()
48
+ url: getDocsUrl(__filename)
49
49
  },
50
50
  fixable: 'code'
51
51
  }
@@ -2,7 +2,7 @@
2
2
  const getDocsUrl = require('./utils/get-docs-url');
3
3
 
4
4
  const isArrayFrom = node => {
5
- const callee = node.callee;
5
+ const {callee} = node;
6
6
  return (
7
7
  callee.type === 'MemberExpression' &&
8
8
  callee.object.type === 'Identifier' &&
@@ -12,6 +12,8 @@ const isArrayFrom = node => {
12
12
  );
13
13
  };
14
14
 
15
+ const isArrayLike = arg => arg && arg.type !== 'ObjectExpression';
16
+
15
17
  const parseArgument = (context, arg) => {
16
18
  if (arg.type === 'Identifier') {
17
19
  return arg.name;
@@ -23,7 +25,7 @@ const parseArgument = (context, arg) => {
23
25
  const create = context => {
24
26
  return {
25
27
  CallExpression(node) {
26
- if (isArrayFrom(node)) {
28
+ if (isArrayFrom(node) && isArrayLike(node.arguments[0])) {
27
29
  context.report({
28
30
  node,
29
31
  message: 'Prefer the spread operator over `Array.from()`.',
@@ -51,7 +53,7 @@ module.exports = {
51
53
  create,
52
54
  meta: {
53
55
  docs: {
54
- url: getDocsUrl()
56
+ url: getDocsUrl(__filename)
55
57
  },
56
58
  fixable: 'code'
57
59
  }
@@ -11,7 +11,7 @@ const isSimpleString = string => doesNotContain(
11
11
  const create = context => {
12
12
  return {
13
13
  CallExpression(node) {
14
- const callee = node.callee;
14
+ const {callee} = node;
15
15
  const prop = callee.property;
16
16
 
17
17
  if (!(prop && callee.type === 'MemberExpression')) {
@@ -22,9 +22,9 @@ const create = context => {
22
22
 
23
23
  let regex;
24
24
  if (prop.name === 'test' && callee.object.regex) {
25
- regex = callee.object.regex;
25
+ ({regex} = callee.object);
26
26
  } else if (prop.name === 'match' && args && args[0] && args[0].regex) {
27
- regex = args[0].regex;
27
+ ({regex} = args[0]);
28
28
  } else {
29
29
  return;
30
30
  }
@@ -33,7 +33,7 @@ const create = context => {
33
33
  return;
34
34
  }
35
35
 
36
- const pattern = regex.pattern;
36
+ const {pattern} = regex;
37
37
  if (pattern.startsWith('^') && isSimpleString(pattern.slice(1))) {
38
38
  context.report({
39
39
  node,
@@ -53,7 +53,7 @@ module.exports = {
53
53
  create,
54
54
  meta: {
55
55
  docs: {
56
- url: getDocsUrl()
56
+ url: getDocsUrl(__filename)
57
57
  }
58
58
  }
59
59
  };
@@ -120,7 +120,7 @@ module.exports = {
120
120
  create,
121
121
  meta: {
122
122
  docs: {
123
- url: getDocsUrl()
123
+ url: getDocsUrl(__filename)
124
124
  },
125
125
  fixable: 'code'
126
126
  }
@@ -8,7 +8,7 @@ const create = context => {
8
8
  return {
9
9
  'Literal[regex]': node => {
10
10
  const oldPattern = node.regex.pattern;
11
- const flags = node.regex.flags;
11
+ const {flags} = node.regex;
12
12
 
13
13
  const newPattern = cleanRegexp(oldPattern, flags);
14
14
 
@@ -62,7 +62,7 @@ module.exports = {
62
62
  create,
63
63
  meta: {
64
64
  docs: {
65
- url: getDocsUrl()
65
+ url: getDocsUrl(__filename)
66
66
  },
67
67
  fixable: 'code'
68
68
  }
@@ -22,7 +22,7 @@ module.exports = {
22
22
  create,
23
23
  meta: {
24
24
  docs: {
25
- url: getDocsUrl()
25
+ url: getDocsUrl(__filename)
26
26
  },
27
27
  fixable: 'code'
28
28
  }
@@ -4,7 +4,7 @@ const pkg = require('../../package');
4
4
 
5
5
  const repoUrl = 'https://github.com/sindresorhus/eslint-plugin-unicorn';
6
6
 
7
- module.exports = ruleName => {
8
- ruleName = ruleName || path.basename(module.parent.filename, '.js');
7
+ module.exports = filename => {
8
+ const ruleName = path.basename(filename, '.js');
9
9
  return `${repoUrl}/blob/v${pkg.version}/docs/rules/${ruleName}.md`;
10
10
  };