summaryrefslogtreecommitdiffstats
path: root/tools/lint/eslint/eslint-plugin-mozilla/tests
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /tools/lint/eslint/eslint-plugin-mozilla/tests
parentInitial commit. (diff)
downloadfirefox-upstream.tar.xz
firefox-upstream.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/tests/avoid-Date-timing.js42
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/tests/avoid-removeChild.js46
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/tests/balanced-listeners.js89
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/tests/balanced-observers.js74
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/tests/consistent-if-bracing.js40
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/tests/mark-exported-symbols-as-used.js45
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/tests/no-arbitrary-setTimeout.js41
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/tests/no-compare-against-boolean-literals.js61
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/tests/no-define-cc-etc.js62
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/tests/no-throw-cr-literal.js62
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/tests/no-useless-parameters.js147
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/tests/no-useless-removeEventListener.js99
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/tests/no-useless-run-test.js124
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/tests/prefer-boolean-length-check.js97
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/tests/prefer-formatValues.js72
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/tests/reject-chromeutils-import-null.js42
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/tests/reject-importGlobalProperties.js46
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/tests/reject-relative-requires.js58
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/tests/reject-some-requires.js49
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/tests/rejects-requires-await.js32
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/tests/use-cc-etc.js55
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/tests/use-chromeutils-generateqi.js81
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/tests/use-chromeutils-import.js80
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/tests/use-default-preference-values.js41
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/tests/use-includes-instead-of-indexOf.js38
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/tests/use-ownerGlobal.js35
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/tests/use-returnValue.js39
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/tests/use-services.js40
28 files changed, 1737 insertions, 0 deletions
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/tests/avoid-Date-timing.js b/tools/lint/eslint/eslint-plugin-mozilla/tests/avoid-Date-timing.js
new file mode 100644
index 0000000000..597961e8cc
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/tests/avoid-Date-timing.js
@@ -0,0 +1,42 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+var rule = require("../lib/rules/avoid-Date-timing");
+var RuleTester = require("eslint").RuleTester;
+
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } });
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+function invalidCode(code, type, message) {
+ return { code, errors: [{ message, type }] };
+}
+
+ruleTester.run("avoid-Date-timing", rule, {
+ valid: [
+ "new Date('2017-07-11');",
+ "new Date(1499790192440);",
+ "new Date(2017, 7, 11);",
+ "Date.UTC(2017, 7);",
+ ],
+ invalid: [
+ invalidCode(
+ "Date.now();",
+ "CallExpression",
+ "use performance.now() instead of Date.now() for timing measurements"
+ ),
+ invalidCode(
+ "new Date();",
+ "NewExpression",
+ "use performance.now() instead of new Date() for timing measurements"
+ ),
+ ],
+});
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/tests/avoid-removeChild.js b/tools/lint/eslint/eslint-plugin-mozilla/tests/avoid-removeChild.js
new file mode 100644
index 0000000000..e6a146898d
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/tests/avoid-removeChild.js
@@ -0,0 +1,46 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+var rule = require("../lib/rules/avoid-removeChild");
+var RuleTester = require("eslint").RuleTester;
+
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } });
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+function invalidCode(code, message) {
+ if (!message) {
+ message =
+ "use element.remove() instead of " +
+ "element.parentNode.removeChild(element)";
+ }
+ return { code, errors: [{ message, type: "CallExpression" }] };
+}
+
+ruleTester.run("avoid-removeChild", rule, {
+ valid: [
+ "elt.remove();",
+ "elt.parentNode.parentNode.removeChild(elt2.parentNode);",
+ "elt.parentNode.removeChild(elt2);",
+ "elt.removeChild(elt2);",
+ ],
+ invalid: [
+ invalidCode("elt.parentNode.removeChild(elt);"),
+ invalidCode("elt.parentNode.parentNode.removeChild(elt.parentNode);"),
+ invalidCode("$(e).parentNode.removeChild($(e));"),
+ invalidCode("$('e').parentNode.removeChild($('e'));"),
+ invalidCode(
+ "elt.removeChild(elt.firstChild);",
+ "use element.firstChild.remove() instead of " +
+ "element.removeChild(element.firstChild)"
+ ),
+ ],
+});
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/tests/balanced-listeners.js b/tools/lint/eslint/eslint-plugin-mozilla/tests/balanced-listeners.js
new file mode 100644
index 0000000000..ca84e3474f
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/tests/balanced-listeners.js
@@ -0,0 +1,89 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+var rule = require("../lib/rules/balanced-listeners");
+var RuleTester = require("eslint").RuleTester;
+
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } });
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+function error(code, message) {
+ return {
+ code,
+ errors: [{ message, type: "Identifier" }],
+ };
+}
+
+ruleTester.run("balanced-listeners", rule, {
+ valid: [
+ "elt.addEventListener('event', handler);" +
+ "elt.removeEventListener('event', handler);",
+
+ "elt.addEventListener('event', handler, true);" +
+ "elt.removeEventListener('event', handler, true);",
+
+ "elt.addEventListener('event', handler, false);" +
+ "elt.removeEventListener('event', handler, false);",
+
+ "elt.addEventListener('event', handler);" +
+ "elt.removeEventListener('event', handler, false);",
+
+ "elt.addEventListener('event', handler, false);" +
+ "elt.removeEventListener('event', handler);",
+
+ "elt.addEventListener('event', handler, {capture: false});" +
+ "elt.removeEventListener('event', handler);",
+
+ "elt.addEventListener('event', handler);" +
+ "elt.removeEventListener('event', handler, {capture: false});",
+
+ "elt.addEventListener('event', handler, {capture: true});" +
+ "elt.removeEventListener('event', handler, true);",
+
+ "elt.addEventListener('event', handler, true);" +
+ "elt.removeEventListener('event', handler, {capture: true});",
+
+ "elt.addEventListener('event', handler, {once: true});",
+
+ "elt.addEventListener('event', handler, {once: true, capture: true});",
+ ],
+ invalid: [
+ error(
+ "elt.addEventListener('click', handler, false);",
+ "No corresponding 'removeEventListener(click)' was found."
+ ),
+
+ error(
+ "elt.addEventListener('click', handler, false);" +
+ "elt.removeEventListener('click', handler, true);",
+ "No corresponding 'removeEventListener(click)' was found."
+ ),
+
+ error(
+ "elt.addEventListener('click', handler, {capture: false});" +
+ "elt.removeEventListener('click', handler, true);",
+ "No corresponding 'removeEventListener(click)' was found."
+ ),
+
+ error(
+ "elt.addEventListener('click', handler, {capture: true});" +
+ "elt.removeEventListener('click', handler);",
+ "No corresponding 'removeEventListener(click)' was found."
+ ),
+
+ error(
+ "elt.addEventListener('click', handler, true);" +
+ "elt.removeEventListener('click', handler);",
+ "No corresponding 'removeEventListener(click)' was found."
+ ),
+ ],
+});
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/tests/balanced-observers.js b/tools/lint/eslint/eslint-plugin-mozilla/tests/balanced-observers.js
new file mode 100644
index 0000000000..e5f31fa969
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/tests/balanced-observers.js
@@ -0,0 +1,74 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+var rule = require("../lib/rules/balanced-observers");
+var RuleTester = require("eslint").RuleTester;
+
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } });
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+function error(code, message) {
+ return {
+ code,
+ errors: [{ message, type: "Identifier" }],
+ };
+}
+
+ruleTester.run("balanced-observers", rule, {
+ valid: [
+ "Services.obs.addObserver(observer, 'observable');" +
+ "Services.obs.removeObserver(observer, 'observable');",
+ "Services.prefs.addObserver('preference.name', otherObserver);" +
+ "Services.prefs.removeObserver('preference.name', otherObserver);",
+ ],
+ invalid: [
+ error(
+ // missing Services.obs.removeObserver
+ "Services.obs.addObserver(observer, 'observable');",
+ "No corresponding 'removeObserver(\"observable\")' was found."
+ ),
+
+ error(
+ // wrong observable name for Services.obs.removeObserver
+ "Services.obs.addObserver(observer, 'observable');" +
+ "Services.obs.removeObserver(observer, 'different-observable');",
+ "No corresponding 'removeObserver(\"observable\")' was found."
+ ),
+
+ error(
+ // missing Services.prefs.removeObserver
+ "Services.prefs.addObserver('preference.name', otherObserver);",
+ "No corresponding 'removeObserver(\"preference.name\")' was found."
+ ),
+
+ error(
+ // wrong observable name for Services.prefs.removeObserver
+ "Services.prefs.addObserver('preference.name', otherObserver);" +
+ "Services.prefs.removeObserver('other.preference', otherObserver);",
+ "No corresponding 'removeObserver(\"preference.name\")' was found."
+ ),
+
+ error(
+ // mismatch Services.prefs vs Services.obs
+ "Services.obs.addObserver(observer, 'observable');" +
+ "Services.prefs.removeObserver(observer, 'observable');",
+ "No corresponding 'removeObserver(\"observable\")' was found."
+ ),
+
+ error(
+ "Services.prefs.addObserver('preference.name', otherObserver);" +
+ // mismatch Services.prefs vs Services.obs
+ "Services.obs.removeObserver('preference.name', otherObserver);",
+ "No corresponding 'removeObserver(\"preference.name\")' was found."
+ ),
+ ],
+});
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/tests/consistent-if-bracing.js b/tools/lint/eslint/eslint-plugin-mozilla/tests/consistent-if-bracing.js
new file mode 100644
index 0000000000..b6b5b849b9
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/tests/consistent-if-bracing.js
@@ -0,0 +1,40 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+var rule = require("../lib/rules/consistent-if-bracing");
+var RuleTester = require("eslint").RuleTester;
+
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 8 } });
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+function invalidCode(code) {
+ return { code, errors: [{ messageId: "consistentIfBracing" }] };
+}
+
+ruleTester.run("consistent-if-bracing", rule, {
+ valid: [
+ "if (true) {1} else {0}",
+ "if (false) 1; else 0",
+ "if (true) {1} else if (true) {2} else {0}",
+ "if (true) {1} else if (true) {2} else if (true) {3} else {0}",
+ ],
+ invalid: [
+ invalidCode(`if (true) {1} else 0`),
+ invalidCode("if (true) 1; else {0}"),
+ invalidCode("if (true) {1} else if (true) 2; else {0}"),
+ invalidCode("if (true) 1; else if (true) {2} else {0}"),
+ invalidCode("if (true) {1} else if (true) 2; else {0}"),
+ invalidCode("if (true) {1} else if (true) {2} else 0"),
+ invalidCode("if (true) {1} else if (true) {2} else if (true) 3; else {0}"),
+ invalidCode("if (true) {if (true) 1; else {0}} else {0}"),
+ ],
+});
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/tests/mark-exported-symbols-as-used.js b/tools/lint/eslint/eslint-plugin-mozilla/tests/mark-exported-symbols-as-used.js
new file mode 100644
index 0000000000..d004650997
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/tests/mark-exported-symbols-as-used.js
@@ -0,0 +1,45 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+var rule = require("../lib/rules/mark-exported-symbols-as-used");
+var RuleTester = require("eslint").RuleTester;
+
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } });
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+function invalidCode(code, type, message) {
+ return { code, errors: [{ message, type }] };
+}
+
+ruleTester.run("mark-exported-symbols-as-used", rule, {
+ valid: [
+ "var EXPORTED_SYMBOLS = ['foo'];",
+ "this.EXPORTED_SYMBOLS = ['foo'];",
+ ],
+ invalid: [
+ invalidCode(
+ "let EXPORTED_SYMBOLS = ['foo'];",
+ "VariableDeclaration",
+ "EXPORTED_SYMBOLS cannot be declared via `let`. Use `var` or `this.EXPORTED_SYMBOLS =`"
+ ),
+ invalidCode(
+ "var EXPORTED_SYMBOLS = 'foo';",
+ "VariableDeclaration",
+ "Unexpected assignment of non-Array to EXPORTED_SYMBOLS"
+ ),
+ invalidCode(
+ "this.EXPORTED_SYMBOLS = 'foo';",
+ "AssignmentExpression",
+ "Unexpected assignment of non-Array to EXPORTED_SYMBOLS"
+ ),
+ ],
+});
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/tests/no-arbitrary-setTimeout.js b/tools/lint/eslint/eslint-plugin-mozilla/tests/no-arbitrary-setTimeout.js
new file mode 100644
index 0000000000..907b439b3c
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/tests/no-arbitrary-setTimeout.js
@@ -0,0 +1,41 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+var rule = require("../lib/rules/no-arbitrary-setTimeout");
+var RuleTester = require("eslint").RuleTester;
+
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } });
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+function wrapCode(code, filename = "xpcshell/test_foo.js") {
+ return { code, filename };
+}
+
+function invalidCode(code) {
+ let message =
+ "listen for events instead of setTimeout() with arbitrary delay";
+ let obj = wrapCode(code);
+ obj.errors = [{ message, type: "CallExpression" }];
+ return obj;
+}
+
+ruleTester.run("no-arbitrary-setTimeout", rule, {
+ valid: [
+ wrapCode("setTimeout(function() {}, 0);"),
+ wrapCode("setTimeout(function() {});"),
+ wrapCode("setTimeout(function() {}, 10);", "test_foo.js"),
+ ],
+ invalid: [
+ invalidCode("setTimeout(function() {}, 10);"),
+ invalidCode("setTimeout(function() {}, timeout);"),
+ ],
+});
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/tests/no-compare-against-boolean-literals.js b/tools/lint/eslint/eslint-plugin-mozilla/tests/no-compare-against-boolean-literals.js
new file mode 100644
index 0000000000..722e6b5dda
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/tests/no-compare-against-boolean-literals.js
@@ -0,0 +1,61 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+var rule = require("../lib/rules/no-compare-against-boolean-literals");
+var RuleTester = require("eslint").RuleTester;
+
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } });
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+function callError(message) {
+ return [{ message, type: "BinaryExpression" }];
+}
+
+const MESSAGE = "Don't compare for inexact equality against boolean literals";
+
+ruleTester.run("no-compare-against-boolean-literals", rule, {
+ valid: [`if (!foo) {}`, `if (!!foo) {}`],
+ invalid: [
+ {
+ code: `if (foo == true) {}`,
+ errors: callError(MESSAGE),
+ },
+ {
+ code: `if (foo != true) {}`,
+ errors: callError(MESSAGE),
+ },
+ {
+ code: `if (foo == false) {}`,
+ errors: callError(MESSAGE),
+ },
+ {
+ code: `if (foo != false) {}`,
+ errors: callError(MESSAGE),
+ },
+ {
+ code: `if (true == foo) {}`,
+ errors: callError(MESSAGE),
+ },
+ {
+ code: `if (true != foo) {}`,
+ errors: callError(MESSAGE),
+ },
+ {
+ code: `if (false == foo) {}`,
+ errors: callError(MESSAGE),
+ },
+ {
+ code: `if (false != foo) {}`,
+ errors: callError(MESSAGE),
+ },
+ ],
+});
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/tests/no-define-cc-etc.js b/tools/lint/eslint/eslint-plugin-mozilla/tests/no-define-cc-etc.js
new file mode 100644
index 0000000000..735c7f4654
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/tests/no-define-cc-etc.js
@@ -0,0 +1,62 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+var rule = require("../lib/rules/no-define-cc-etc");
+var RuleTester = require("eslint").RuleTester;
+
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 9 } });
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+function invalidCode(code, varNames) {
+ if (!Array.isArray(varNames)) {
+ varNames = [varNames];
+ }
+ return {
+ code,
+ errors: varNames.map(name => {
+ return {
+ message: `${name} is now defined in global scope, a separate definition is no longer necessary.`,
+ type: "VariableDeclarator",
+ };
+ }),
+ };
+}
+
+ruleTester.run("no-define-cc-etc", rule, {
+ valid: [
+ "var Cm = Components.manager;",
+ "const CC = Components.Constructor;",
+ "var {Constructor: CC, manager: Cm} = Components;",
+ "const {Constructor: CC, manager: Cm} = Components;",
+ "foo.Cc.test();",
+ "const {bar, ...foo} = obj;",
+ ],
+ invalid: [
+ invalidCode("var Cc;", "Cc"),
+ invalidCode("let Cc;", "Cc"),
+ invalidCode("let Ci;", "Ci"),
+ invalidCode("let Cr;", "Cr"),
+ invalidCode("let Cu;", "Cu"),
+ invalidCode("var Cc = Components.classes;", "Cc"),
+ invalidCode("const {classes: Cc} = Components;", "Cc"),
+ invalidCode("let {classes: Cc, manager: Cm} = Components", "Cc"),
+ invalidCode("const Cu = Components.utils;", "Cu"),
+ invalidCode("var Ci = Components.interfaces, Cc = Components.classes;", [
+ "Ci",
+ "Cc",
+ ]),
+ invalidCode("var {'interfaces': Ci, 'classes': Cc} = Components;", [
+ "Ci",
+ "Cc",
+ ]),
+ ],
+});
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/tests/no-throw-cr-literal.js b/tools/lint/eslint/eslint-plugin-mozilla/tests/no-throw-cr-literal.js
new file mode 100644
index 0000000000..6750213e72
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/tests/no-throw-cr-literal.js
@@ -0,0 +1,62 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+var rule = require("../lib/rules/no-throw-cr-literal");
+var RuleTester = require("eslint").RuleTester;
+
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } });
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+function invalidCode(code, output, messageId) {
+ return {
+ code,
+ output,
+ errors: [{ messageId, type: "ThrowStatement" }],
+ };
+}
+
+ruleTester.run("no-throw-cr-literal", rule, {
+ valid: [
+ 'throw Components.Exception("", Cr.NS_ERROR_NOT_IMPLEMENTED);',
+ 'throw Components.Exception("", Components.results.NS_ERROR_UNEXPECTED);',
+ 'function t() { throw Components.Exception("", Cr.NS_ERROR_NO_CONTENT); }',
+ // We don't handle combined values, regular no-throw-literal catches them
+ 'throw Components.results.NS_ERROR_UNEXPECTED + "whoops";',
+ ],
+ invalid: [
+ invalidCode(
+ "throw Cr.NS_ERROR_NO_INTERFACE;",
+ 'throw Components.Exception("", Cr.NS_ERROR_NO_INTERFACE);',
+ "bareCR"
+ ),
+ invalidCode(
+ "throw Components.results.NS_ERROR_ABORT;",
+ 'throw Components.Exception("", Components.results.NS_ERROR_ABORT);',
+ "bareComponentsResults"
+ ),
+ invalidCode(
+ "function t() { throw Cr.NS_ERROR_NULL_POINTER; }",
+ 'function t() { throw Components.Exception("", Cr.NS_ERROR_NULL_POINTER); }',
+ "bareCR"
+ ),
+ invalidCode(
+ "throw new Error(Cr.NS_ERROR_ABORT);",
+ 'throw Components.Exception("", Cr.NS_ERROR_ABORT);',
+ "newErrorCR"
+ ),
+ invalidCode(
+ "throw new Error(Components.results.NS_ERROR_ABORT);",
+ 'throw Components.Exception("", Components.results.NS_ERROR_ABORT);',
+ "newErrorComponentsResults"
+ ),
+ ],
+});
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/tests/no-useless-parameters.js b/tools/lint/eslint/eslint-plugin-mozilla/tests/no-useless-parameters.js
new file mode 100644
index 0000000000..0c9b12f6eb
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/tests/no-useless-parameters.js
@@ -0,0 +1,147 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+var rule = require("../lib/rules/no-useless-parameters");
+var RuleTester = require("eslint").RuleTester;
+
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } });
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+function callError(message) {
+ return [{ message, type: "CallExpression" }];
+}
+
+ruleTester.run("no-useless-parameters", rule, {
+ valid: [
+ "Services.prefs.clearUserPref('browser.search.custom');",
+ "Services.removeObserver('notification name', {});",
+ "Services.io.newURI('http://example.com');",
+ "Services.io.newURI('http://example.com', 'utf8');",
+ "elt.addEventListener('click', handler);",
+ "elt.addEventListener('click', handler, true);",
+ "elt.addEventListener('click', handler, {once: true});",
+ "elt.removeEventListener('click', handler);",
+ "elt.removeEventListener('click', handler, true);",
+ "Services.obs.addObserver(this, 'topic', true);",
+ "Services.obs.addObserver(this, 'topic');",
+ "Services.prefs.addObserver('branch', this, true);",
+ "Services.prefs.addObserver('branch', this);",
+ "array.appendElement(elt);",
+ "Services.obs.notifyObservers(obj, 'topic', 'data');",
+ "Services.obs.notifyObservers(obj, 'topic');",
+ "window.getComputedStyle(elt);",
+ "window.getComputedStyle(elt, ':before');",
+ ],
+ invalid: [
+ {
+ code: "Services.prefs.clearUserPref('browser.search.custom', false);",
+ output: "Services.prefs.clearUserPref('browser.search.custom');",
+ errors: callError("clearUserPref takes only 1 parameter."),
+ },
+ {
+ code: "Services.prefs.clearUserPref('browser.search.custom',\n false);",
+ output: "Services.prefs.clearUserPref('browser.search.custom');",
+ errors: callError("clearUserPref takes only 1 parameter."),
+ },
+ {
+ code: "Services.removeObserver('notification name', {}, false);",
+ output: "Services.removeObserver('notification name', {});",
+ errors: callError("removeObserver only takes 2 parameters."),
+ },
+ {
+ code: "Services.removeObserver('notification name', {}, true);",
+ output: "Services.removeObserver('notification name', {});",
+ errors: callError("removeObserver only takes 2 parameters."),
+ },
+ {
+ code: "Services.io.newURI('http://example.com', null, null);",
+ output: "Services.io.newURI('http://example.com');",
+ errors: callError("newURI's last parameters are optional."),
+ },
+ {
+ code: "Services.io.newURI('http://example.com', 'utf8', null);",
+ output: "Services.io.newURI('http://example.com', 'utf8');",
+ errors: callError("newURI's last parameters are optional."),
+ },
+ {
+ code: "Services.io.newURI('http://example.com', null);",
+ output: "Services.io.newURI('http://example.com');",
+ errors: callError("newURI's last parameters are optional."),
+ },
+ {
+ code: "Services.io.newURI('http://example.com', '', '');",
+ output: "Services.io.newURI('http://example.com');",
+ errors: callError("newURI's last parameters are optional."),
+ },
+ {
+ code: "Services.io.newURI('http://example.com', '');",
+ output: "Services.io.newURI('http://example.com');",
+ errors: callError("newURI's last parameters are optional."),
+ },
+ {
+ code: "elt.addEventListener('click', handler, false);",
+ output: "elt.addEventListener('click', handler);",
+ errors: callError(
+ "addEventListener's third parameter can be omitted when it's false."
+ ),
+ },
+ {
+ code: "elt.removeEventListener('click', handler, false);",
+ output: "elt.removeEventListener('click', handler);",
+ errors: callError(
+ "removeEventListener's third parameter can be omitted when it's" +
+ " false."
+ ),
+ },
+ {
+ code: "Services.obs.addObserver(this, 'topic', false);",
+ output: "Services.obs.addObserver(this, 'topic');",
+ errors: callError(
+ "addObserver's third parameter can be omitted when it's false."
+ ),
+ },
+ {
+ code: "Services.prefs.addObserver('branch', this, false);",
+ output: "Services.prefs.addObserver('branch', this);",
+ errors: callError(
+ "addObserver's third parameter can be omitted when it's false."
+ ),
+ },
+ {
+ code: "array.appendElement(elt, false);",
+ output: "array.appendElement(elt);",
+ errors: callError(
+ "appendElement's second parameter can be omitted when it's false."
+ ),
+ },
+ {
+ code: "Services.obs.notifyObservers(obj, 'topic', null);",
+ output: "Services.obs.notifyObservers(obj, 'topic');",
+ errors: callError("notifyObservers's third parameter can be omitted."),
+ },
+ {
+ code: "Services.obs.notifyObservers(obj, 'topic', '');",
+ output: "Services.obs.notifyObservers(obj, 'topic');",
+ errors: callError("notifyObservers's third parameter can be omitted."),
+ },
+ {
+ code: "window.getComputedStyle(elt, null);",
+ output: "window.getComputedStyle(elt);",
+ errors: callError("getComputedStyle's second parameter can be omitted."),
+ },
+ {
+ code: "window.getComputedStyle(elt, '');",
+ output: "window.getComputedStyle(elt);",
+ errors: callError("getComputedStyle's second parameter can be omitted."),
+ },
+ ],
+});
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/tests/no-useless-removeEventListener.js b/tools/lint/eslint/eslint-plugin-mozilla/tests/no-useless-removeEventListener.js
new file mode 100644
index 0000000000..9f59c78d05
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/tests/no-useless-removeEventListener.js
@@ -0,0 +1,99 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+var rule = require("../lib/rules/no-useless-removeEventListener");
+var RuleTester = require("eslint").RuleTester;
+
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } });
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+function invalidCode(code) {
+ let message =
+ "use {once: true} instead of removeEventListener " +
+ "as the first instruction of the listener";
+ return { code, errors: [{ message, type: "CallExpression" }] };
+}
+
+ruleTester.run("no-useless-removeEventListener", rule, {
+ valid: [
+ // Listeners that aren't a function are always valid.
+ "elt.addEventListener('click', handler);",
+ "elt.addEventListener('click', handler, true);",
+ "elt.addEventListener('click', handler, {once: true});",
+
+ // Should not fail on empty functions.
+ "elt.addEventListener('click', function() {});",
+
+ // Should not reject when removing a listener for another event.
+ "elt.addEventListener('click', function listener() {" +
+ " elt.removeEventListener('keypress', listener);" +
+ "});",
+
+ // Should not reject when there's another instruction before
+ // removeEventListener.
+ "elt.addEventListener('click', function listener() {" +
+ " elt.focus();" +
+ " elt.removeEventListener('click', listener);" +
+ "});",
+
+ // Should not reject when wantsUntrusted is true.
+ "elt.addEventListener('click', function listener() {" +
+ " elt.removeEventListener('click', listener);" +
+ "}, false, true);",
+
+ // Should not reject when there's a literal and a variable
+ "elt.addEventListener('click', function listener() {" +
+ " elt.removeEventListener(eventName, listener);" +
+ "});",
+
+ // Should not reject when there's 2 different variables
+ "elt.addEventListener(event1, function listener() {" +
+ " elt.removeEventListener(event2, listener);" +
+ "});",
+
+ // Should not fail if this is a different type of event listener function.
+ "myfunc.addEventListener(listener);",
+ ],
+ invalid: [
+ invalidCode(
+ "elt.addEventListener('click', function listener() {" +
+ " elt.removeEventListener('click', listener);" +
+ "});"
+ ),
+ invalidCode(
+ "elt.addEventListener('click', function listener() {" +
+ " elt.removeEventListener('click', listener, true);" +
+ "}, true);"
+ ),
+ invalidCode(
+ "elt.addEventListener('click', function listener() {" +
+ " elt.removeEventListener('click', listener);" +
+ "}, {once: true});"
+ ),
+ invalidCode(
+ "elt.addEventListener('click', function listener() {" +
+ " /* Comment */" +
+ " elt.removeEventListener('click', listener);" +
+ "});"
+ ),
+ invalidCode(
+ "elt.addEventListener('click', function() {" +
+ " elt.removeEventListener('click', arguments.callee);" +
+ "});"
+ ),
+ invalidCode(
+ "elt.addEventListener(eventName, function listener() {" +
+ " elt.removeEventListener(eventName, listener);" +
+ "});"
+ ),
+ ],
+});
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/tests/no-useless-run-test.js b/tools/lint/eslint/eslint-plugin-mozilla/tests/no-useless-run-test.js
new file mode 100644
index 0000000000..3541467143
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/tests/no-useless-run-test.js
@@ -0,0 +1,124 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+var rule = require("../lib/rules/no-useless-run-test");
+var RuleTester = require("eslint").RuleTester;
+
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } });
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+function invalidCode(code, output) {
+ let message =
+ "Useless run_test function - only contains run_next_test; whole function can be removed";
+ return { code, output, errors: [{ message, type: "FunctionDeclaration" }] };
+}
+
+ruleTester.run("no-useless-run-test", rule, {
+ valid: [
+ "function run_test() {}",
+ "function run_test() {let args = 1; run_next_test();}",
+ "function run_test() {fakeCall(); run_next_test();}",
+ ],
+ invalid: [
+ // Single-line case.
+ invalidCode("function run_test() { run_next_test(); }", ""),
+ // Multiple-line cases
+ invalidCode(
+ `
+function run_test() {
+ run_next_test();
+}`,
+ ``
+ ),
+ invalidCode(
+ `
+foo();
+function run_test() {
+ run_next_test();
+}
+`,
+ `
+foo();
+`
+ ),
+ invalidCode(
+ `
+foo();
+function run_test() {
+ run_next_test();
+}
+bar();
+`,
+ `
+foo();
+bar();
+`
+ ),
+ invalidCode(
+ `
+foo();
+
+function run_test() {
+ run_next_test();
+}
+
+bar();`,
+ `
+foo();
+
+bar();`
+ ),
+ invalidCode(
+ `
+foo();
+
+function run_test() {
+ run_next_test();
+}
+
+// A comment
+bar();
+`,
+ `
+foo();
+
+// A comment
+bar();
+`
+ ),
+ invalidCode(
+ `
+foo();
+
+/**
+ * A useful comment.
+ */
+function run_test() {
+ run_next_test();
+}
+
+// A comment
+bar();
+`,
+ `
+foo();
+
+/**
+ * A useful comment.
+ */
+
+// A comment
+bar();
+`
+ ),
+ ],
+});
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/tests/prefer-boolean-length-check.js b/tools/lint/eslint/eslint-plugin-mozilla/tests/prefer-boolean-length-check.js
new file mode 100644
index 0000000000..daf3c6f3d9
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/tests/prefer-boolean-length-check.js
@@ -0,0 +1,97 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+var rule = require("../lib/rules/prefer-boolean-length-check");
+var RuleTester = require("eslint").RuleTester;
+
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } });
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+function invalidError() {
+ let message = "Prefer boolean length check";
+ return [{ message, type: "BinaryExpression" }];
+}
+
+ruleTester.run("check-length", rule, {
+ valid: [
+ "if (foo.length && foo.length) {}",
+ "if (!foo.length) {}",
+ "if (foo.value == 0) {}",
+ "if (foo.value > 0) {}",
+ "if (0 == foo.value) {}",
+ "if (0 < foo.value) {}",
+ "var a = !!foo.length",
+ "function bar() { return !!foo.length }",
+ ],
+ invalid: [
+ {
+ code: "if (foo.length == 0) {}",
+ output: "if (!foo.length) {}",
+ errors: invalidError(),
+ },
+ {
+ code: "if (foo.length > 0) {}",
+ output: "if (foo.length) {}",
+ errors: invalidError(),
+ },
+ {
+ code: "if (0 < foo.length) {}",
+ output: "if (foo.length) {}",
+ errors: invalidError(),
+ },
+ {
+ code: "if (0 == foo.length) {}",
+ output: "if (!foo.length) {}",
+ errors: invalidError(),
+ },
+ {
+ code: "if (foo && foo.length == 0) {}",
+ output: "if (foo && !foo.length) {}",
+ errors: invalidError(),
+ },
+ {
+ code: "if (foo.bar.length == 0) {}",
+ output: "if (!foo.bar.length) {}",
+ errors: invalidError(),
+ },
+ {
+ code: "var a = foo.length>0",
+ output: "var a = !!foo.length",
+ errors: invalidError(),
+ },
+ {
+ code: "function bar() { return foo.length>0 }",
+ output: "function bar() { return !!foo.length }",
+ errors: invalidError(),
+ },
+ {
+ code: "if (foo && bar.length>0) {}",
+ output: "if (foo && bar.length) {}",
+ errors: invalidError(),
+ },
+ {
+ code: "while (foo && bar.length>0) {}",
+ output: "while (foo && bar.length) {}",
+ errors: invalidError(),
+ },
+ {
+ code: "x = y && bar.length > 0",
+ output: "x = y && !!bar.length",
+ errors: invalidError(),
+ },
+ {
+ code: "function bar() { return x && foo.length > 0}",
+ output: "function bar() { return x && !!foo.length}",
+ errors: invalidError(),
+ },
+ ],
+});
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/tests/prefer-formatValues.js b/tools/lint/eslint/eslint-plugin-mozilla/tests/prefer-formatValues.js
new file mode 100644
index 0000000000..0883130f17
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/tests/prefer-formatValues.js
@@ -0,0 +1,72 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+var rule = require("../lib/rules/prefer-formatValues");
+var RuleTester = require("eslint").RuleTester;
+
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } });
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+function error(line, column = undefined) {
+ return {
+ message:
+ "prefer to use a single document.l10n.formatValues call instead " +
+ "of multiple calls to document.l10n.formatValue or document.l10n.formatValues",
+ type: "CallExpression",
+ line,
+ column,
+ };
+}
+
+ruleTester.run("check-length", rule, {
+ valid: [
+ "document.l10n.formatValue('foobar');",
+ "document.l10n.formatValues(['foobar', 'foobaz']);",
+ `if (foo) {
+ document.l10n.formatValue('foobar');
+ } else {
+ document.l10n.formatValue('foobaz');
+ }`,
+ `document.l10n.formatValue('foobaz');
+ if (foo) {
+ document.l10n.formatValue('foobar');
+ }`,
+ `if (foo) {
+ document.l10n.formatValue('foobar');
+ }
+ document.l10n.formatValue('foobaz');`,
+ `if (foo) {
+ document.l10n.formatValue('foobar');
+ }
+ document.l10n.formatValues(['foobaz']);`,
+ ],
+ invalid: [
+ {
+ code: `document.l10n.formatValue('foobar');
+ document.l10n.formatValue('foobaz');`,
+ errors: [error(1, 1), error(2, 14)],
+ },
+ {
+ code: `document.l10n.formatValue('foobar');
+ if (foo) {
+ document.l10n.formatValue('foobiz');
+ }
+ document.l10n.formatValue('foobaz');`,
+ errors: [error(1, 1), error(5, 14)],
+ },
+ {
+ code: `document.l10n.formatValues('foobar');
+ document.l10n.formatValue('foobaz');`,
+ errors: [error(1, 1), error(2, 14)],
+ },
+ ],
+});
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/tests/reject-chromeutils-import-null.js b/tools/lint/eslint/eslint-plugin-mozilla/tests/reject-chromeutils-import-null.js
new file mode 100644
index 0000000000..6584f728ac
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/tests/reject-chromeutils-import-null.js
@@ -0,0 +1,42 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+var rule = require("../lib/rules/reject-chromeutils-import-null");
+var RuleTester = require("eslint").RuleTester;
+
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 8 } });
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+function invalidError() {
+ let message =
+ "ChromeUtils.import should not be called with (..., null) to " +
+ "retrieve the JSM global object. Rely on explicit exports instead.";
+ return [{ message, type: "CallExpression" }];
+}
+
+ruleTester.run("reject-chromeutils-import-null", rule, {
+ valid: ['ChromeUtils.import("resource://some/path/to/My.jsm")'],
+ invalid: [
+ {
+ code: 'ChromeUtils.import("resource://some/path/to/My.jsm", null)',
+ errors: invalidError(),
+ },
+ {
+ code: `
+ChromeUtils.import(
+ "resource://some/path/to/My.jsm",
+ null
+);`,
+ errors: invalidError(),
+ },
+ ],
+});
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/tests/reject-importGlobalProperties.js b/tools/lint/eslint/eslint-plugin-mozilla/tests/reject-importGlobalProperties.js
new file mode 100644
index 0000000000..04c0e0408b
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/tests/reject-importGlobalProperties.js
@@ -0,0 +1,46 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+var rule = require("../lib/rules/reject-importGlobalProperties");
+var RuleTester = require("eslint").RuleTester;
+
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 8 } });
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+ruleTester.run("reject-importGlobalProperties", rule, {
+ valid: [
+ {
+ code: "Cu.something();",
+ },
+ {
+ options: ["allownonwebidl"],
+ code: "Cu.importGlobalProperties(['fetch'])",
+ },
+ ],
+ invalid: [
+ {
+ code: "Cu.importGlobalProperties(['fetch'])",
+ options: ["everything"],
+ errors: [{ messageId: "unexpectedCall" }],
+ },
+ {
+ code: "Cu.importGlobalProperties(['TextEncoder'])",
+ options: ["everything"],
+ errors: [{ messageId: "unexpectedCall" }],
+ },
+ {
+ code: "Cu.importGlobalProperties(['TextEncoder'])",
+ options: ["allownonwebidl"],
+ errors: [{ messageId: "unexpectedCallWebIdl" }],
+ },
+ ],
+});
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/tests/reject-relative-requires.js b/tools/lint/eslint/eslint-plugin-mozilla/tests/reject-relative-requires.js
new file mode 100644
index 0000000000..19f30559ec
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/tests/reject-relative-requires.js
@@ -0,0 +1,58 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+var rule = require("../lib/rules/reject-relative-requires");
+var RuleTester = require("eslint").RuleTester;
+
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 8 } });
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+function invalidError() {
+ let message = "relative paths are not allowed with require()";
+ return [{ message, type: "CallExpression" }];
+}
+
+ruleTester.run("reject-relative-requires", rule, {
+ valid: [
+ 'require("devtools/absolute/path")',
+ 'require("resource://gre/modules/SomeModule.jsm")',
+ 'loader.lazyRequireGetter(this, "path", "devtools/absolute/path", true)',
+ 'loader.lazyRequireGetter(this, "Path", "devtools/absolute/path")',
+ ],
+ invalid: [
+ {
+ code: 'require("./relative/path")',
+ errors: invalidError(),
+ },
+ {
+ code: 'require("../parent/folder/path")',
+ errors: invalidError(),
+ },
+ {
+ code: 'loader.lazyRequireGetter(this, "path", "./relative/path", true)',
+ errors: invalidError(),
+ },
+ {
+ code:
+ 'loader.lazyRequireGetter(this, "path", "../parent/folder/path", true)',
+ errors: invalidError(),
+ },
+ {
+ code: 'loader.lazyRequireGetter(this, "path", "./relative/path")',
+ errors: invalidError(),
+ },
+ {
+ code: 'loader.lazyRequireGetter(this, "path", "../parent/folder/path")',
+ errors: invalidError(),
+ },
+ ],
+});
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/tests/reject-some-requires.js b/tools/lint/eslint/eslint-plugin-mozilla/tests/reject-some-requires.js
new file mode 100644
index 0000000000..b56dd2cf96
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/tests/reject-some-requires.js
@@ -0,0 +1,49 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+var rule = require("../lib/rules/reject-some-requires");
+var RuleTester = require("eslint").RuleTester;
+
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 8 } });
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+function requirePathError(path) {
+ const message = `require(${path}) is not allowed`;
+ return [{ message, type: "CallExpression" }];
+}
+
+const DEVTOOLS_FORBIDDEN_PATH = "^(resource://)?devtools/forbidden";
+
+ruleTester.run("reject-some-requires", rule, {
+ valid: [
+ {
+ code: 'require("devtools/not-forbidden/path")',
+ options: [DEVTOOLS_FORBIDDEN_PATH],
+ },
+ {
+ code: 'require("resource://devtools/not-forbidden/path")',
+ options: [DEVTOOLS_FORBIDDEN_PATH],
+ },
+ ],
+ invalid: [
+ {
+ code: 'require("devtools/forbidden/path")',
+ errors: requirePathError("devtools/forbidden/path"),
+ options: [DEVTOOLS_FORBIDDEN_PATH],
+ },
+ {
+ code: 'require("resource://devtools/forbidden/path")',
+ errors: requirePathError("resource://devtools/forbidden/path"),
+ options: [DEVTOOLS_FORBIDDEN_PATH],
+ },
+ ],
+});
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/tests/rejects-requires-await.js b/tools/lint/eslint/eslint-plugin-mozilla/tests/rejects-requires-await.js
new file mode 100644
index 0000000000..ea6273a8ee
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/tests/rejects-requires-await.js
@@ -0,0 +1,32 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+var rule = require("../lib/rules/rejects-requires-await");
+var RuleTester = require("eslint").RuleTester;
+
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 8 } });
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+function invalidCode(code, messageId) {
+ return { code, errors: [{ messageId: "rejectRequiresAwait" }] };
+}
+
+ruleTester.run("reject-requires-await", rule, {
+ valid: [
+ "async() => { await Assert.rejects(foo, /assertion/) }",
+ "async() => { await Assert.rejects(foo, /assertion/, 'msg') }",
+ ],
+ invalid: [
+ invalidCode("Assert.rejects(foo)"),
+ invalidCode("Assert.rejects(foo, 'msg')"),
+ ],
+});
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/tests/use-cc-etc.js b/tools/lint/eslint/eslint-plugin-mozilla/tests/use-cc-etc.js
new file mode 100644
index 0000000000..7ad729d22b
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/tests/use-cc-etc.js
@@ -0,0 +1,55 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+var rule = require("../lib/rules/use-cc-etc");
+var RuleTester = require("eslint").RuleTester;
+
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } });
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+function invalidCode(code, originalName, newName) {
+ return {
+ code,
+ errors: [
+ {
+ message: `Use ${newName} rather than ${originalName}`,
+ type: "MemberExpression",
+ },
+ ],
+ };
+}
+
+ruleTester.run("use-cc-etc", rule, {
+ valid: ["Components.Constructor();", "let x = Components.foo;"],
+ invalid: [
+ invalidCode(
+ "let foo = Components.classes['bar'];",
+ "Components.classes",
+ "Cc"
+ ),
+ invalidCode(
+ "let bar = Components.interfaces.bar;",
+ "Components.interfaces",
+ "Ci"
+ ),
+ invalidCode(
+ "Components.results.NS_ERROR_ILLEGAL_INPUT;",
+ "Components.results",
+ "Cr"
+ ),
+ invalidCode(
+ "Components.utils.reportError('fake');",
+ "Components.utils",
+ "Cu"
+ ),
+ ],
+});
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/tests/use-chromeutils-generateqi.js b/tools/lint/eslint/eslint-plugin-mozilla/tests/use-chromeutils-generateqi.js
new file mode 100644
index 0000000000..26c6b350bc
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/tests/use-chromeutils-generateqi.js
@@ -0,0 +1,81 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+var rule = require("../lib/rules/use-chromeutils-generateqi");
+var RuleTester = require("eslint").RuleTester;
+
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } });
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+function callError(message) {
+ return [{ message, type: "CallExpression" }];
+}
+function error(message, type) {
+ return [{ message, type }];
+}
+
+const MSG_NO_JS_QUERY_INTERFACE =
+ "Please use ChromeUtils.generateQI rather than manually creating " +
+ "JavaScript QueryInterface functions";
+
+const MSG_NO_XPCOMUTILS_GENERATEQI =
+ "Please use ChromeUtils.generateQI instead of XPCOMUtils.generateQI";
+
+/* globals nsIFlug */
+function QueryInterface(iid) {
+ if (
+ iid.equals(Ci.nsISupports) ||
+ iid.equals(Ci.nsIMeh) ||
+ iid.equals(nsIFlug) ||
+ iid.equals(Ci.amIFoo)
+ ) {
+ return this;
+ }
+ throw Components.Exception("", Cr.NS_ERROR_NO_INTERFACE);
+}
+
+ruleTester.run("use-chromeutils-generateqi", rule, {
+ valid: [
+ `X.prototype.QueryInterface = ChromeUtils.generateQI(["nsIMeh"]);`,
+ `X.prototype = { QueryInterface: ChromeUtils.generateQI(["nsIMeh"]) }`,
+ ],
+ invalid: [
+ {
+ code: `X.prototype.QueryInterface = XPCOMUtils.generateQI(["nsIMeh"]);`,
+ output: `X.prototype.QueryInterface = ChromeUtils.generateQI(["nsIMeh"]);`,
+ errors: callError(MSG_NO_XPCOMUTILS_GENERATEQI),
+ },
+ {
+ code: `X.prototype = { QueryInterface: XPCOMUtils.generateQI(["nsIMeh"]) };`,
+ output: `X.prototype = { QueryInterface: ChromeUtils.generateQI(["nsIMeh"]) };`,
+ errors: callError(MSG_NO_XPCOMUTILS_GENERATEQI),
+ },
+ {
+ code: `X.prototype = { QueryInterface: ${QueryInterface} };`,
+ output: `X.prototype = { QueryInterface: ChromeUtils.generateQI(["nsIMeh", "nsIFlug", "amIFoo"]) };`,
+ errors: error(MSG_NO_JS_QUERY_INTERFACE, "Property"),
+ },
+ {
+ code: `X.prototype = { ${String(QueryInterface).replace(
+ /^function /,
+ ""
+ )} };`,
+ output: `X.prototype = { QueryInterface: ChromeUtils.generateQI(["nsIMeh", "nsIFlug", "amIFoo"]) };`,
+ errors: error(MSG_NO_JS_QUERY_INTERFACE, "Property"),
+ },
+ {
+ code: `X.prototype.QueryInterface = ${QueryInterface};`,
+ output: `X.prototype.QueryInterface = ChromeUtils.generateQI(["nsIMeh", "nsIFlug", "amIFoo"]);`,
+ errors: error(MSG_NO_JS_QUERY_INTERFACE, "AssignmentExpression"),
+ },
+ ],
+});
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/tests/use-chromeutils-import.js b/tools/lint/eslint/eslint-plugin-mozilla/tests/use-chromeutils-import.js
new file mode 100644
index 0000000000..635c436233
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/tests/use-chromeutils-import.js
@@ -0,0 +1,80 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+var rule = require("../lib/rules/use-chromeutils-import");
+var RuleTester = require("eslint").RuleTester;
+
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } });
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+function callError(message) {
+ return [{ message, type: "CallExpression" }];
+}
+
+const MESSAGE_IMPORT = "Please use ChromeUtils.import instead of Cu.import";
+const MESSAGE_DEFINE =
+ "Please use ChromeUtils.defineModuleGetter instead of " +
+ "XPCOMUtils.defineLazyModuleGetter";
+
+ruleTester.run("use-chromeutils-import", rule, {
+ valid: [
+ `ChromeUtils.import("resource://gre/modules/Service.jsm");`,
+ `ChromeUtils.import("resource://gre/modules/Service.jsm", this);`,
+ `ChromeUtils.defineModuleGetter(this, "Services",
+ "resource://gre/modules/Service.jsm");`,
+ `XPCOMUtils.defineLazyModuleGetter(this, "Services",
+ "resource://gre/modules/Service.jsm",
+ "Foo");`,
+ `XPCOMUtils.defineLazyModuleGetter(this, "Services",
+ "resource://gre/modules/Service.jsm",
+ undefined, preServicesLambda);`,
+ {
+ options: [{ allowCu: true }],
+ code: `Cu.import("resource://gre/modules/Service.jsm");`,
+ },
+ ],
+ invalid: [
+ {
+ code: `Cu.import("resource://gre/modules/Services.jsm");`,
+ output: `ChromeUtils.import("resource://gre/modules/Services.jsm");`,
+ errors: callError(MESSAGE_IMPORT),
+ },
+ {
+ code: `Cu.import("resource://gre/modules/Services.jsm", this);`,
+ output: `ChromeUtils.import("resource://gre/modules/Services.jsm", this);`,
+ errors: callError(MESSAGE_IMPORT),
+ },
+ {
+ code: `Components.utils.import("resource://gre/modules/Services.jsm");`,
+ output: `ChromeUtils.import("resource://gre/modules/Services.jsm");`,
+ errors: callError(MESSAGE_IMPORT),
+ },
+ {
+ code: `Components.utils.import("resource://gre/modules/Services.jsm");`,
+ output: `ChromeUtils.import("resource://gre/modules/Services.jsm");`,
+ errors: callError(MESSAGE_IMPORT),
+ },
+ {
+ options: [{ allowCu: true }],
+ code: `Components.utils.import("resource://gre/modules/Services.jsm", this);`,
+ output: `ChromeUtils.import("resource://gre/modules/Services.jsm", this);`,
+ errors: callError(MESSAGE_IMPORT),
+ },
+ {
+ code: `XPCOMUtils.defineLazyModuleGetter(this, "Services",
+ "resource://gre/modules/Services.jsm");`,
+ output: `ChromeUtils.defineModuleGetter(this, "Services",
+ "resource://gre/modules/Services.jsm");`,
+ errors: callError(MESSAGE_DEFINE),
+ },
+ ],
+});
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/tests/use-default-preference-values.js b/tools/lint/eslint/eslint-plugin-mozilla/tests/use-default-preference-values.js
new file mode 100644
index 0000000000..f4ad001a08
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/tests/use-default-preference-values.js
@@ -0,0 +1,41 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+var rule = require("../lib/rules/use-default-preference-values");
+var RuleTester = require("eslint").RuleTester;
+
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } });
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+function invalidCode(code) {
+ let message = "provide a default value instead of using a try/catch block";
+ return { code, errors: [{ message, type: "TryStatement" }] };
+}
+
+let types = ["Bool", "Char", "Float", "Int"];
+let methods = types.map(type => "get" + type + "Pref");
+
+ruleTester.run("use-default-preference-values", rule, {
+ valid: [].concat(
+ methods.map(m => "blah = branch." + m + "('blah', true);"),
+ methods.map(m => "blah = branch." + m + "('blah');"),
+ methods.map(
+ m => "try { canThrow(); blah = branch." + m + "('blah'); } catch(e) {}"
+ )
+ ),
+
+ invalid: [].concat(
+ methods.map(m =>
+ invalidCode("try { blah = branch." + m + "('blah'); } catch(e) {}")
+ )
+ ),
+});
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/tests/use-includes-instead-of-indexOf.js b/tools/lint/eslint/eslint-plugin-mozilla/tests/use-includes-instead-of-indexOf.js
new file mode 100644
index 0000000000..cb1810b305
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/tests/use-includes-instead-of-indexOf.js
@@ -0,0 +1,38 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+var rule = require("../lib/rules/use-includes-instead-of-indexOf");
+var RuleTester = require("eslint").RuleTester;
+
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } });
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+function invalidCode(code) {
+ let message = "use .includes instead of .indexOf";
+ return { code, errors: [{ message, type: "BinaryExpression" }] };
+}
+
+ruleTester.run("use-includes-instead-of-indexOf", rule, {
+ valid: [
+ "let a = foo.includes(bar);",
+ "let a = foo.indexOf(bar) > 0;",
+ "let a = foo.indexOf(bar) != 0;",
+ ],
+ invalid: [
+ invalidCode("let a = foo.indexOf(bar) >= 0;"),
+ invalidCode("let a = foo.indexOf(bar) != -1;"),
+ invalidCode("let a = foo.indexOf(bar) !== -1;"),
+ invalidCode("let a = foo.indexOf(bar) == -1;"),
+ invalidCode("let a = foo.indexOf(bar) === -1;"),
+ invalidCode("let a = foo.indexOf(bar) < 0;"),
+ ],
+});
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/tests/use-ownerGlobal.js b/tools/lint/eslint/eslint-plugin-mozilla/tests/use-ownerGlobal.js
new file mode 100644
index 0000000000..b08bdf1632
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/tests/use-ownerGlobal.js
@@ -0,0 +1,35 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+var rule = require("../lib/rules/use-ownerGlobal");
+var RuleTester = require("eslint").RuleTester;
+
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } });
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+function invalidCode(code) {
+ let message = "use .ownerGlobal instead of .ownerDocument.defaultView";
+ return { code, errors: [{ message, type: "MemberExpression" }] };
+}
+
+ruleTester.run("use-ownerGlobal", rule, {
+ valid: [
+ "aEvent.target.ownerGlobal;",
+ "this.DOMPointNode.ownerGlobal.getSelection();",
+ "windowToMessageManager(node.ownerGlobal);",
+ ],
+ invalid: [
+ invalidCode("aEvent.target.ownerDocument.defaultView;"),
+ invalidCode("this.DOMPointNode.ownerDocument.defaultView.getSelection();"),
+ invalidCode("windowToMessageManager(node.ownerDocument.defaultView);"),
+ ],
+});
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/tests/use-returnValue.js b/tools/lint/eslint/eslint-plugin-mozilla/tests/use-returnValue.js
new file mode 100644
index 0000000000..81952452e4
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/tests/use-returnValue.js
@@ -0,0 +1,39 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+var rule = require("../lib/rules/use-returnValue");
+var RuleTester = require("eslint").RuleTester;
+
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } });
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+function invalidCode(code, methodName) {
+ let message = `{Array/String}.${methodName} doesn't modify the instance in-place`;
+ return { code, errors: [{ message, type: "ExpressionStatement" }] };
+}
+
+ruleTester.run("use-returnValue", rule, {
+ valid: [
+ "a = foo.concat(bar)",
+ "b = bar.concat([1,3,4])",
+ "c = baz.concat()",
+ "d = qux.join(' ')",
+ "e = quux.slice(1)",
+ ],
+ invalid: [
+ invalidCode("foo.concat(bar)", "concat"),
+ invalidCode("bar.concat([1,3,4])", "concat"),
+ invalidCode("baz.concat()", "concat"),
+ invalidCode("qux.join(' ')", "join"),
+ invalidCode("quux.slice(1)", "slice"),
+ ],
+});
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/tests/use-services.js b/tools/lint/eslint/eslint-plugin-mozilla/tests/use-services.js
new file mode 100644
index 0000000000..b8d5338fc4
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/tests/use-services.js
@@ -0,0 +1,40 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+var rule = require("../lib/rules/use-services");
+var RuleTester = require("eslint").RuleTester;
+
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } });
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+function invalidCode(code, name) {
+ let message = `Use Services.${name} rather than getService().`;
+ return { code, errors: [{ message, type: "CallExpression" }] };
+}
+
+ruleTester.run("use-services", rule, {
+ valid: [
+ 'Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator)',
+ 'Components.classes["@mozilla.org/uuid-generator;1"].getService(Components.interfaces.nsIUUIDGenerator)',
+ "Services.wm.addListener()",
+ ],
+ invalid: [
+ invalidCode(
+ 'Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);',
+ "wm"
+ ),
+ invalidCode(
+ 'Components.classes["@mozilla.org/toolkit/app-startup;1"].getService(Components.interfaces.nsIAppStartup);',
+ "startup"
+ ),
+ ],
+});