DEV: Add qunit filter parameter support to Ember CLI tests route

DEV: Add qunit filter parameter support to Ember CLI tests route

This adds support for qunit_skip_core, qunit_skip_plugins and qunit_single_plugin parameters on the Ember CLI /tests route using the addModuleExcludeMatcher API. Legacy support is maintained for the /qunit route.

diff --git a/app/assets/javascripts/discourse/tests/setup-tests.js b/app/assets/javascripts/discourse/tests/setup-tests.js
index 12f9309..c88e08e 100644
--- a/app/assets/javascripts/discourse/tests/setup-tests.js
+++ b/app/assets/javascripts/discourse/tests/setup-tests.js
@@ -256,38 +256,61 @@ function setupTestsCommon(application, container, config) {
     server = null;
   });
 
-  // Load ES6 tests
-  function getUrlParameter(name) {
-    name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
-    let regex = new RegExp("[\\?&]" + name + "=([^&#]*)");
-    let results = regex.exec(location.search);
-    return results === null
-      ? ""
-      : decodeURIComponent(results[1].replace(/\+/g, " "));
+  if (getUrlParameter("qunit_disable_auto_start") === "1") {
+    QUnit.config.autostart = false;
   }
 
-  let skipCore = getUrlParameter("qunit_skip_core") === "1";
-  let pluginPath = getUrlParameter("qunit_single_plugin")
-    ? "/" + getUrlParameter("qunit_single_plugin") + "/"
-    : "/plugins/";
+  let skipCore =
+    getUrlParameter("qunit_single_plugin") ||
+    getUrlParameter("qunit_skip_core") === "1";
 
-  if (getUrlParameter("qunit_disable_auto_start") === "1") {
-    QUnit.config.autostart = false;
+  let singlePlugin = getUrlParameter("qunit_single_plugin");
+  let skipPlugins = !singlePlugin && getUrlParameter("qunit_skip_plugins");
+
+  if (skipCore && !getUrlParameter("qunit_skip_core")) {
+    replaceUrlParameter("qunit_skip_core", "1");
   }
 
-  Object.keys(requirejs.entries).forEach(function (entry) {
-    let isTest = /\-test/.test(entry);
-    let regex = new RegExp(pluginPath);
-    let isPlugin = regex.test(entry);
+  if (!skipPlugins && getUrlParameter("qunit_skip_plugins")) {
+    replaceUrlParameter("qunit_skip_plugins", null);
+  }
 
-    if (!isTest) {
-      return;
+  const shouldLoadModule = (name) => {
+    if (!/\-test/.test(name)) {
+      return false;
     }
 
-    if (!skipCore || isPlugin) {
-      require(entry, null, null, true);
+    const isPlugin = name.match(/\/plugins\//);
+    const isCore = !isPlugin;
+    const pluginName = name.match(/\/plugins\/([\w-]+)\//)?.[1];
+
+    if (skipCore && isCore) {
+      return false;
+    } else if (skipPlugins && isPlugin) {
+      return false;
+    } else if (singlePlugin && singlePlugin !== pluginName) {
+      return false;
     }
-  });
+    return true;
+  };
+
+  try {
+    // Ember CLI
+    const emberCliTestLoader = require("ember-cli-test-loader/test-support/index");
+    emberCliTestLoader.addModuleExcludeMatcher(
+      (name) => !shouldLoadModule(name)
+    );
+  } catch (e) {
+    if (!String(e).indexOf("Could not find module")) {
+      throw e;
+    }
+    // Legacy
+    Object.keys(requirejs.entries).forEach(function (entry) {
+      if (shouldLoadModule(entry)) {
+        require(entry, null, null, true);
+      }
+    });
+  }
 
   // forces 0 as duration for all jquery animations
   jQuery.fx.off = true;
@@ -311,3 +334,18 @@ export default function setupTests(config) {
   app = createApplication(config, settings);
   setupTestsCommon(app, app.__container__, config);
 }
+
+function getUrlParameter(name) {
+  const queryParams = new URLSearchParams(window.location.search);
+  return queryParams.get(name);
+}
+
+function replaceUrlParameter(name, value) {
+  const queryParams = new URLSearchParams(window.location.search);
+  if (value === null) {
+    queryParams.delete(name);
+  } else {
+    queryParams.set(name, value);
+  }
+  window.location = "?" + queryParams.toString();
+}

GitHub sha: 402162e18ae8fc211e6cff21d65f74a61e2c87a2

This commit appears in #14401 which was approved by eviltrout. It was merged by davidtaylorhq.