Skip to content

Commit 89e62cc

Browse files
authored
feat(lint): type-safe equality operator when comparing literals
For comparing (non empty) strings, we can use === reliably (instead of ==).
1 parent 029436f commit 89e62cc

40 files changed

+484
-414
lines changed

.eslint/eqeqeq-rule.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
const eslint = require('eslint');
2+
const ruleComposer = require('eslint-rule-composer');
3+
4+
const rule = new eslint.Linter().getRules().get('eqeqeq');
5+
6+
module.exports = ruleComposer.filterReports(
7+
rule,
8+
(problem) => {
9+
if (problem.node.type === 'BinaryExpression'
10+
&& (problem.node.operator === '==' || problem.node.operator === '!=')
11+
&& problem.node.right.type === 'Literal'
12+
) {
13+
return problem;
14+
}
15+
16+
return false;
17+
}
18+
);

.eslint/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
module.exports = {
22
rules: {
3+
eqeqeq: require('./eqeqeq-rule'),
34
'no-extra-parens': require('./no-extra-parens-rule'),
45
},
56
configs: {
@@ -8,6 +9,8 @@ module.exports = {
89
'@internal/eslint-plugin',
910
],
1011
rules: {
12+
// fixes only variable == (or !=) literal expression
13+
'@internal/eqeqeq': ['error', 'always'],
1114
// https://github.com/eslint/eslint/issues/16626
1215
// https://github.com/airbnb/javascript/blob/eslint-config-airbnb-v19.0.4/packages/eslint-config-airbnb-base/rules/errors.js#L66
1316
'@internal/no-extra-parens': ['error', 'all', {

.eslintrc.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ module.exports = {
8585
'unicorn/prefer-array-some': 'off', // https://github.com/sindresorhus/eslint-plugin-unicorn/issues/2007
8686
'unicorn/prefer-module': 'off',
8787
'unicorn/prevent-abbreviations': 'off',
88-
'unicorn/switch-case-braces': ['error', 'avoid'],
8988
'wrap-iife': ['error', 'inside'],
9089

9190
// TODO rules to be removed/fixed in v2.10.0 as fixes are not compatible with IE11
@@ -113,7 +112,7 @@ module.exports = {
113112
'vars-on-top': 'off',
114113

115114
// TODO rules with a lot of errors to be fixed manually, fix in a separate PR
116-
eqeqeq: 'off', // about 300 errors to be fixed manually
115+
eqeqeq: 'off', // about 20 errors to be fixed manually
117116
'global-require': 'off', // about 30 errors to be fixed manually
118117
'no-shadow': 'off', // about 220 errors to be fixed manually
119118
'no-shadow-restricted-names': 'off', // TODO https://github.com/fomantic/Fomantic-UI/pull/2604

src/definitions/behaviors/api.js

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
'use strict';
1313

1414
function isWindow(obj) {
15-
return obj != null && obj === obj.window;
15+
return obj !== null && obj === obj.window;
1616
}
1717

1818
function isFunction(obj) {
@@ -117,7 +117,7 @@
117117
$module
118118
.on(triggerEvent + eventNamespace, module.event.trigger)
119119
;
120-
} else if (settings.on == 'now') {
120+
} else if (settings.on === 'now') {
121121
module.debug('Querying API endpoint immediately');
122122
module.query();
123123
}
@@ -296,7 +296,7 @@
296296
},
297297
loading: function () {
298298
return module.request
299-
? module.request.state() == 'pending'
299+
? module.request.state() === 'pending'
300300
: false;
301301
},
302302
abortedRequest: function (xhr) {
@@ -334,13 +334,13 @@
334334
return module.cancelled || false;
335335
},
336336
successful: function () {
337-
return module.request && module.request.state() == 'resolved';
337+
return module.request && module.request.state() === 'resolved';
338338
},
339339
failure: function () {
340-
return module.request && module.request.state() == 'rejected';
340+
return module.request && module.request.state() === 'rejected';
341341
},
342342
complete: function () {
343-
return module.request && (module.request.state() == 'resolved' || module.request.state() == 'rejected');
343+
return module.request && (module.request.state() === 'resolved' || module.request.state() === 'rejected');
344344
},
345345
},
346346

@@ -478,7 +478,7 @@
478478
while (nameKeys.length > 0) {
479479
var k = nameKeys.pop();
480480

481-
if (k == '' && !Array.isArray(value)) { // foo[]
481+
if (k === '' && !Array.isArray(value)) { // foo[]
482482
value = build([], pushes[pushKey]++, value);
483483
} else if (settings.regExp.fixed.test(k)) { // foo[n]
484484
value = build([], k, value);
@@ -525,7 +525,7 @@
525525
event: {
526526
trigger: function (event) {
527527
module.query();
528-
if (event.type == 'submit' || event.type == 'click') {
528+
if (event.type === 'submit' || event.type === 'click') {
529529
event.preventDefault();
530530
}
531531
},
@@ -614,15 +614,15 @@
614614
response = module.get.responseFromXHR(xhr),
615615
errorMessage = module.get.errorFromRequest(response, status, httpMessage)
616616
;
617-
if (status == 'aborted') {
617+
if (status === 'aborted') {
618618
module.debug('XHR Aborted (Most likely caused by page navigation or CORS Policy)', status, httpMessage);
619619
settings.onAbort.call(context, status, $module, xhr);
620620

621621
return true;
622622
}
623-
if (status == 'invalid') {
623+
if (status === 'invalid') {
624624
module.debug('JSON did not pass success test. A server-side error has most likely occurred', response);
625-
} else if (status == 'error') {
625+
} else if (status === 'error') {
626626
if (xhr !== undefined) {
627627
module.debug('XHR produced a server error', status, httpMessage);
628628
// make sure we have an error to display to console
@@ -829,12 +829,12 @@
829829
return data;
830830
},
831831
event: function () {
832-
if (isWindow(element) || settings.on == 'now') {
832+
if (isWindow(element) || settings.on === 'now') {
833833
module.debug('API called without element, no events attached');
834834

835835
return false;
836836
}
837-
if (settings.on == 'auto') {
837+
if (settings.on === 'auto') {
838838
if ($module.is('input')) {
839839
return element.oninput !== undefined
840840
? 'input'
@@ -1004,17 +1004,17 @@
10041004
query = query.split(/[ .]/);
10051005
maxDepth = query.length - 1;
10061006
$.each(query, function (depth, value) {
1007-
var camelCaseValue = depth != maxDepth
1007+
var camelCaseValue = depth !== maxDepth
10081008
? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
10091009
: query
10101010
;
1011-
if ($.isPlainObject(object[camelCaseValue]) && (depth != maxDepth)) {
1011+
if ($.isPlainObject(object[camelCaseValue]) && (depth !== maxDepth)) {
10121012
object = object[camelCaseValue];
10131013
} else if (object[camelCaseValue] !== undefined) {
10141014
found = object[camelCaseValue];
10151015

10161016
return false;
1017-
} else if ($.isPlainObject(object[value]) && (depth != maxDepth)) {
1017+
} else if ($.isPlainObject(object[value]) && (depth !== maxDepth)) {
10181018
object = object[value];
10191019
} else if (object[value] !== undefined) {
10201020
found = object[value];

0 commit comments

Comments
 (0)