Run ESLint tests in PRESUBMIT if changes in eslint_rules folder

Ensures that if a CL touches files in scripts/eslint_rules, we will run
the tests as part of the PRESUBMIT. We have so many rules now and rely
on them to enforce a lot, so it's important we ensure they don't get
broken; currently they are never run on CQ at all so it's easily to
accidentally break it and not realise.


Bug: None
Change-Id: Ic56166404f56787b60eb18b5b375c61dc00ba1df
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/3151806
Commit-Queue: Jack Franklin <jacktfranklin@chromium.org>
Auto-Submit: Jack Franklin <jacktfranklin@chromium.org>
Reviewed-by: Tim van der Lippe <tvanderlippe@chromium.org>
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index 5c885c3..2be65f7 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -200,6 +200,35 @@
 
     return _ExecuteSubProcess(input_api, output_api, ['git', 'cl', 'format', '--js'], [], results)
 
+
+def _CheckDevToolsRunESLintTests(input_api, output_api):
+    # Check for changes in the eslint_rules directory, and run the eslint rules
+    # tests if so.
+    # We don't do this on every CL as most do not touch the rules, but if we do
+    # change them we need to make sure all the tests are passing.
+    eslint_rules_dir_path = input_api.os_path.join(
+        input_api.PresubmitLocalPath(), 'scripts', 'eslint_rules')
+    eslint_rules_affected_files = _getAffectedFiles(input_api,
+                                                    [eslint_rules_dir_path],
+                                                    [], [])
+
+    if (len(eslint_rules_affected_files) == 0):
+        return []
+
+    mocha_path = input_api.os_path.join(input_api.PresubmitLocalPath(),
+                                        'node_modules', '.bin', 'mocha')
+    eslint_tests_path = input_api.os_path.join(eslint_rules_dir_path, 'tests',
+                                               '*_test.js')
+
+    results = [output_api.PresubmitNotifyResult('ESLint rules unit tests')]
+    results.extend(
+        # The dot reporter is more concise which is useful to not get LOADS of
+        # output when just one test fails.
+        _checkWithNodeScript(input_api, output_api, mocha_path,
+                             ['--reporter', 'dot', eslint_tests_path]))
+    return results
+
+
 def _CheckDevToolsStyleJS(input_api, output_api):
     results = [output_api.PresubmitNotifyResult('JS style check:')]
     lint_path = input_api.os_path.join(input_api.PresubmitLocalPath(),
@@ -516,6 +545,7 @@
     results.extend(_CheckJSON(input_api, output_api))
     results.extend(_CheckDevToolsStyleJS(input_api, output_api))
     results.extend(_CheckDevToolsStyleCSS(input_api, output_api))
+    results.extend(_CheckDevToolsRunESLintTests(input_api, output_api))
     results.extend(_CheckDevToolsNonJSFileLicenseHeaders(
         input_api, output_api))