junit 5 rt: initial
authorAnna Kozlova <anna.kozlova@jetbrains.com>
Tue, 8 Mar 2016 16:29:48 +0000 (17:29 +0100)
committerAnna Kozlova <anna.kozlova@jetbrains.com>
Thu, 10 Mar 2016 10:21:45 +0000 (11:21 +0100)
14 files changed:
.idea/libraries/junit5_rt.xml [new file with mode: 0644]
.idea/modules.xml
build/scripts/layouts.gant
build/scripts/libLicenses.gant
plugins/junit/junit.iml
plugins/junit/src/com/intellij/execution/junit/TestMethod.java
plugins/junit/src/com/intellij/execution/junit/TestObject.java
plugins/junit5_rt/junit5_rt.iml [new file with mode: 0644]
plugins/junit5_rt/lib/junit-commons-5.0.0-ALPHA.jar [new file with mode: 0644]
plugins/junit5_rt/lib/junit-engine-api-5.0.0-ALPHA.jar [new file with mode: 0644]
plugins/junit5_rt/lib/junit-launcher-5.0.0-ALPHA.jar [new file with mode: 0644]
plugins/junit5_rt/src/com/intellij/junit5/JUnit5IdeaTestRunner.java [new file with mode: 0644]
plugins/junit5_rt/src/com/intellij/junit5/JUnit5TestExecutionListener.java [new file with mode: 0644]
plugins/junit5_rt/src/com/intellij/junit5/JUnit5TestRunnerUtil.java [new file with mode: 0644]

diff --git a/.idea/libraries/junit5_rt.xml b/.idea/libraries/junit5_rt.xml
new file mode 100644 (file)
index 0000000..5a0fe64
--- /dev/null
@@ -0,0 +1,11 @@
+<component name="libraryTable">
+  <library name="junit5_rt">
+    <CLASSES>
+      <root url="jar://$PROJECT_DIR$/plugins/junit5_rt/lib/junit-commons-5.0.0-ALPHA.jar!/" />
+      <root url="jar://$PROJECT_DIR$/plugins/junit5_rt/lib/junit-engine-api-5.0.0-ALPHA.jar!/" />
+      <root url="jar://$PROJECT_DIR$/plugins/junit5_rt/lib/junit-launcher-5.0.0-ALPHA.jar!/" />
+    </CLASSES>
+    <JAVADOC />
+    <SOURCES />
+  </library>
+</component>
\ No newline at end of file
index 15c4ae1ce18a1920c82d100d8f5346dae015bfc4..98246cf2ab4cbf722aa0110db008cca04d800f42 100644 (file)
       <module fileurl="file://$PROJECT_DIR$/java/jsp-openapi/jsp-openapi.iml" filepath="$PROJECT_DIR$/java/jsp-openapi/jsp-openapi.iml" group="java" />
       <module fileurl="file://$PROJECT_DIR$/java/jsp-spi/jsp-spi.iml" filepath="$PROJECT_DIR$/java/jsp-spi/jsp-spi.iml" group="java" />
       <module fileurl="file://$PROJECT_DIR$/plugins/junit/junit.iml" filepath="$PROJECT_DIR$/plugins/junit/junit.iml" group="plugins" />
+      <module fileurl="file://$PROJECT_DIR$/plugins/junit5_rt/junit5_rt.iml" filepath="$PROJECT_DIR$/plugins/junit5_rt/junit5_rt.iml" group="plugins" />
       <module fileurl="file://$PROJECT_DIR$/plugins/junit_rt/junit_rt.iml" filepath="$PROJECT_DIR$/plugins/junit_rt/junit_rt.iml" group="plugins" />
       <module fileurl="file://$PROJECT_DIR$/platform/lang-api/lang-api.iml" filepath="$PROJECT_DIR$/platform/lang-api/lang-api.iml" group="platform" />
       <module fileurl="file://$PROJECT_DIR$/platform/lang-impl/lang-impl.iml" filepath="$PROJECT_DIR$/platform/lang-impl/lang-impl.iml" group="platform" />
index e7cc2e2458d857ec53c687009905373ef7fd24fa..5e1552b348837cbf11d2052ccb5d80a2a998dff8 100644 (file)
@@ -472,6 +472,12 @@ public def layoutCommunityPlugins(String home, boolean maySkipAndroidPlugin = fa
       jar("junit-rt.jar") {
         module("junit_rt")
       }
+      jar("junit5-rt.jar") {
+        module("junit5_rt")
+      }
+      fileset(dir: "$home/plugins/junit5_rt/lib") {
+        include(name: "*.jar")
+      }
     }
 
     pluginDir("ByteCodeViewer") {
index 3f0eaf561e28ce6e07d311250a9e0d001588cebb..846d9ee3f0b72dfde718cdb08da244fdf38a4734 100644 (file)
@@ -244,6 +244,7 @@ libraryLicense(name: "jsr305", libraryName: "jsr305", version: "snapshot", licen
 libraryLicense(name: "Jsr305", version: "1.3.9", license: "New BSD", url: "http://code.google.com/p/jsr-305/", licenseUrl: "http://opensource.org/licenses/BSD-3-Clause")
 libraryLicense(name: "JUnit", libraryName: "JUnit3", version: "3.8.1", license: "CPL 1.0", url: "http://junit.org/")
 libraryLicense(name: "JUnit", libraryName: "JUnit4", version: "4.11", license: "CPL 1.0", url: "http://junit.org/")
+libraryLicense(name: "junit5_rt", libraryName: "junit5_rt", version: "5.0.0", license: "Eclipse Public License 1.0", url: "http://junit.org/")
 libraryLicense(name: "jzlib", libraryName: "jzlib", version: "1.1.1", license: "BSD", url: "http://www.jcraft.com/jzlib/", licenseUrl: "http://www.jcraft.com/jzlib/LICENSE.txt")
 libraryLicense(name: "Kryo", libraryName: "Kryo", version: "2.22", license: "New BSD License", url: "https://github.com/EsotericSoftware/kryo", licenseUrl: "https://github.com/EsotericSoftware/kryo/blob/master/license.txt")
 libraryLicense(name: "kXML2", libraryName: "kxml2", version: "2.3.0", license: "BSD", url: "http://sourceforge.net/projects/kxml/")
index 4b114db22d86fc5cd2801feff96b6bb872cc3747..103c9789465b3afc9c9436d67ce4610544c74e2a 100644 (file)
@@ -22,6 +22,7 @@
     <orderEntry type="module" module-name="smRunner" exported="" />
     <orderEntry type="module" module-name="testFramework-java" scope="TEST" />
     <orderEntry type="module" module-name="debugger-impl" />
+    <orderEntry type="module" module-name="junit5_rt" />
   </component>
   <component name="copyright">
     <Base>
index 3b68c8fb60f80246af07968c9601f05f3abf0c48..2808eab23761894d843c8f666467c8721918ea8f 100644 (file)
@@ -51,7 +51,7 @@ class TestMethod extends TestObject {
 
   protected void addJUnit3Parameter(JavaParameters javaParameters, final JUnitConfiguration.Data data, Project project) throws ExecutionException {
     final PsiClass psiClass = JavaExecutionUtil.findMainClass(project, data.getMainClassName(), GlobalSearchScope.allScope(project));
-    if (psiClass == null || JUnitUtil.isJUnit4TestClass(psiClass)) {
+    if (psiClass == null || JUnitUtil.isJUnit4TestClass(psiClass) || JUnitUtil.isJUnit5(psiClass)) {
       return;
     }
     final String methodName = data.getMethodName();
index a48926d974943cf17a9c84cc46906df94531eadc..2a25b1a0145f26b31dccfa88e76c59a401dd1c99 100644 (file)
@@ -40,10 +40,12 @@ import com.intellij.execution.testframework.*;
 import com.intellij.execution.ui.ConsoleViewContentType;
 import com.intellij.execution.util.JavaParametersUtil;
 import com.intellij.execution.util.ProgramParametersUtil;
+import com.intellij.junit5.JUnit5IdeaTestRunner;
 import com.intellij.openapi.Disposable;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.module.Module;
 import com.intellij.openapi.module.ModuleUtilCore;
+import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Disposer;
 import com.intellij.openapi.util.Getter;
 import com.intellij.openapi.util.Key;
@@ -51,6 +53,7 @@ import com.intellij.openapi.util.io.FileUtil;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vfs.CharsetToolkit;
 import com.intellij.psi.*;
+import com.intellij.psi.search.GlobalSearchScope;
 import com.intellij.refactoring.listeners.RefactoringElementListener;
 import com.intellij.rt.execution.junit.IDEAJUnitListener;
 import com.intellij.rt.execution.junit.JUnitStarter;
@@ -155,6 +158,13 @@ public abstract class TestObject extends JavaTestFrameworkRunnableState<JUnitCon
         LOG.error(e);
       }
     }
+
+    final Project project = getConfiguration().getProject();
+    if (JUnitUtil.isJUnit5(GlobalSearchScope.allScope(project), project)) {
+      javaParameters.getProgramParametersList().add(JUnitStarter.JUNIT5_PARAMETER);
+      javaParameters.getClassPath().add(PathUtil.getJarPathForClass(JUnit5IdeaTestRunner.class));
+    }
+    
     return javaParameters;
   }
 
diff --git a/plugins/junit5_rt/junit5_rt.iml b/plugins/junit5_rt/junit5_rt.iml
new file mode 100644 (file)
index 0000000..f37ea82
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="module" module-name="junit_rt" />
+    <orderEntry type="module" module-name="java-runtime" />
+    <orderEntry type="library" name="junit5_rt" level="project" />
+  </component>
+</module>
\ No newline at end of file
diff --git a/plugins/junit5_rt/lib/junit-commons-5.0.0-ALPHA.jar b/plugins/junit5_rt/lib/junit-commons-5.0.0-ALPHA.jar
new file mode 100644 (file)
index 0000000..0e94185
Binary files /dev/null and b/plugins/junit5_rt/lib/junit-commons-5.0.0-ALPHA.jar differ
diff --git a/plugins/junit5_rt/lib/junit-engine-api-5.0.0-ALPHA.jar b/plugins/junit5_rt/lib/junit-engine-api-5.0.0-ALPHA.jar
new file mode 100644 (file)
index 0000000..3346eba
Binary files /dev/null and b/plugins/junit5_rt/lib/junit-engine-api-5.0.0-ALPHA.jar differ
diff --git a/plugins/junit5_rt/lib/junit-launcher-5.0.0-ALPHA.jar b/plugins/junit5_rt/lib/junit-launcher-5.0.0-ALPHA.jar
new file mode 100644 (file)
index 0000000..f881f91
Binary files /dev/null and b/plugins/junit5_rt/lib/junit-launcher-5.0.0-ALPHA.jar differ
diff --git a/plugins/junit5_rt/src/com/intellij/junit5/JUnit5IdeaTestRunner.java b/plugins/junit5_rt/src/com/intellij/junit5/JUnit5IdeaTestRunner.java
new file mode 100644 (file)
index 0000000..9a42956
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2000-2016 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.junit5;
+
+import com.intellij.rt.execution.junit.IdeaTestRunner;
+import com.intellij.rt.execution.junit.segments.OutputObjectRegistry;
+import org.junit.gen5.launcher.Launcher;
+import org.junit.gen5.launcher.TestDiscoveryRequest;
+import org.junit.gen5.launcher.TestPlan;
+import org.junit.gen5.launcher.main.LauncherFactory;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class JUnit5IdeaTestRunner implements IdeaTestRunner {
+  private JUnit5TestExecutionListener myListener;
+
+  @Override
+  public int startRunnerWithArgs(String[] args, ArrayList listeners, String name, int count, boolean sendTree) {
+    Launcher launcher = LauncherFactory.create();
+    launcher.registerTestExecutionListeners(myListener);
+    final TestDiscoveryRequest discoveryRequest = JUnit5TestRunnerUtil.buildRequest(args, name, false);
+    final TestPlan testPlan = launcher.discover(discoveryRequest);
+    myListener.sendTree(testPlan);
+    launcher.execute(discoveryRequest);
+
+    return 0;
+  }
+
+  @Override
+  public void setStreams(Object segmentedOut, Object segmentedErr, int lastIdx) {
+    myListener = new JUnit5TestExecutionListener(System.out);
+  }
+
+  @Override
+  public OutputObjectRegistry getRegistry() {
+    return null;
+  }
+
+  //forked mode todo not supported
+  
+  @Override
+  public Object getTestToStart(String[] args, String name) {
+    return null;
+  }
+
+  @Override
+  public List getChildTests(Object description) {
+    return Collections.emptyList();
+  }
+
+  @Override
+  public String getStartDescription(Object child) {
+    return null;
+  }
+
+  @Override
+  public String getTestClassName(Object child) {
+    return child.toString();
+  }
+}
diff --git a/plugins/junit5_rt/src/com/intellij/junit5/JUnit5TestExecutionListener.java b/plugins/junit5_rt/src/com/intellij/junit5/JUnit5TestExecutionListener.java
new file mode 100644 (file)
index 0000000..26e8edf
--- /dev/null
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2000-2016 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.junit5;
+
+import com.intellij.rt.execution.junit.ComparisonFailureData;
+import com.intellij.rt.execution.junit.MapSerializerUtil;
+import org.junit.gen5.engine.TestExecutionResult;
+import org.junit.gen5.engine.support.descriptor.JavaSource;
+import org.junit.gen5.launcher.TestExecutionListener;
+import org.junit.gen5.launcher.TestIdentifier;
+import org.junit.gen5.launcher.TestPlan;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+
+public class JUnit5TestExecutionListener implements TestExecutionListener {
+  private final PrintStream myPrintStream;
+  private TestPlan myTestPlan;
+  private long myCurrentTestStart;
+  
+  public JUnit5TestExecutionListener() {
+    this(System.out);
+  }
+
+  public JUnit5TestExecutionListener(PrintStream printStream) {
+    myPrintStream = printStream;
+    myPrintStream.println("##teamcity[enteredTheMatrix]");
+  }
+
+  @Override
+  public void testPlanExecutionStarted(TestPlan testPlan) {
+    myTestPlan = testPlan;
+  }
+
+  @Override
+  public void testPlanExecutionFinished(TestPlan testPlan) {
+    myTestPlan = null;
+  }
+
+  @Override
+  public void executionSkipped(TestIdentifier testIdentifier, String reason) {
+    testIgnored(testIdentifier, reason);
+  }
+
+  private void testIgnored(TestIdentifier testIdentifier, String reason) {
+    if (testIdentifier.isTest()) {
+      executionStarted(testIdentifier);
+      Map<String, String> attrs = new HashMap<>();
+      if (reason != null) {
+        attrs.put("message", reason);
+      }
+      attrs.put("name", testIdentifier.getDisplayName());
+      attrs.put("id", testIdentifier.getUniqueId().toString());
+      myPrintStream.println(MapSerializerUtil.asString(MapSerializerUtil.TEST_IGNORED, attrs));
+      
+      testFinished(testIdentifier, System.currentTimeMillis() - myCurrentTestStart);
+    }
+    else {
+      myTestPlan.getDescendants(testIdentifier).forEach(identifier -> testIgnored(identifier, reason));
+    }
+  }
+
+  @Override
+  public void executionStarted(TestIdentifier testIdentifier) {
+    if (testIdentifier.isTest()) {
+      myPrintStream.println("\n##teamcity[testStarted" + idAndName(testIdentifier) + "\']");
+      myCurrentTestStart = System.currentTimeMillis();
+    }
+    else {
+      myPrintStream.println("##teamcity[testSuiteStarted" + idAndName(testIdentifier) + "\']");
+    }
+  }
+
+  private static String idAndName(TestIdentifier testIdentifier) {
+    return idAndName(testIdentifier, testIdentifier.getDisplayName());
+  }
+
+  private static String idAndName(TestIdentifier testIdentifier, String displayName) {
+    return " id=\'" + testIdentifier.getUniqueId().toString() + "\' name=\'" + escapeName(displayName);
+  }
+
+  @Override
+  public void executionFinished(TestIdentifier testIdentifier, TestExecutionResult testExecutionResult) {
+    final String displayName = testIdentifier.getDisplayName();
+    if (testIdentifier.isTest()) {
+      final TestExecutionResult.Status status = testExecutionResult.getStatus();
+      final long duration = System.currentTimeMillis() - myCurrentTestStart;
+      final Optional<Throwable> throwableOptional = testExecutionResult.getThrowable();
+      if (status == TestExecutionResult.Status.FAILED) {
+        testFailure(throwableOptional, MapSerializerUtil.TEST_FAILED, testIdentifier, duration);
+      }
+      else if (status == TestExecutionResult.Status.ABORTED) {
+        testFailure(throwableOptional, MapSerializerUtil.TEST_IGNORED, testIdentifier, duration);
+      }
+      testFinished(testIdentifier, duration);
+    }
+    else {
+      myPrintStream.println("##teamcity[testSuiteFinished " + idAndName(testIdentifier, displayName) + "\']");
+    }
+  }
+
+  private void testFinished(TestIdentifier testIdentifier, long duration) {
+    myPrintStream.println("\n##teamcity[testFinished" + idAndName(testIdentifier) + (duration > 0 ? "\' duration=\'" + Long.toString(duration) : "") + "\']");
+  }
+  
+  private void testFailure(Optional<Throwable> failure, String messageName, TestIdentifier testIdentifier, long duration) {
+    final Map<String, String> attrs = new HashMap<>();
+    attrs.put("name", testIdentifier.getDisplayName());
+    attrs.put("id", testIdentifier.getUniqueId().toString());
+    if (duration > 0) {
+      attrs.put("duration", Long.toString(duration));
+    }
+    try {
+      if (failure.isPresent()) {
+        final Throwable ex = failure.get();
+        final StringWriter stringWriter = new StringWriter();
+        final PrintWriter writer = new PrintWriter(stringWriter);
+        ex.printStackTrace(writer);
+        ComparisonFailureData.registerSMAttributes(null, stringWriter.toString(), ex.getMessage(), attrs, ex);
+      }
+    }
+    finally {
+      myPrintStream.println("\n" + MapSerializerUtil.asString(messageName, attrs));
+    }
+  }
+
+
+  public void sendTree(TestPlan testPlan) {
+    for (TestIdentifier root : testPlan.getRoots()) {
+      sendTreeUnderRoot(testPlan, root);
+    }
+    myPrintStream.println("##teamcity[treeEnded]");
+  }
+
+  private void sendTreeUnderRoot(TestPlan testPlan, TestIdentifier root) {
+    final String idAndName = idAndName(root);
+    if (root.isContainer()) {
+      myPrintStream.println("##teamcity[suiteTreeStarted" + idAndName + "\' locationHint=\'java:suite://" + escapeName(getClassName(root)) + "\']");
+      for (TestIdentifier childIdentifier : testPlan.getChildren(root)) {
+        sendTreeUnderRoot(testPlan, childIdentifier);
+      }
+      myPrintStream.println("##teamcity[suiteTreeEnded" + idAndName + "\']");
+    }
+    else if (root.isTest()) {
+      myPrintStream.println("##teamcity[suiteTreeNode " + idAndName + "\' locationHint=\'java:test://" + escapeName(getClassName(root) + "." + getMethodName(root)) + "\']");
+    }
+  }
+
+
+  private static String escapeName(String str) {
+    return MapSerializerUtil.escapeStr(str, MapSerializerUtil.STD_ESCAPER);
+  }
+
+  private static String getClassName(TestIdentifier description) {
+    Optional<JavaSource> javaSource = getJavaSource(description);
+    return javaSource.map(source -> {
+      final Optional<Class<?>> javaClass = source.getJavaClass();
+      return javaClass.isPresent() ? javaClass.get().getName() : null;
+    }).orElse(null);
+  }
+
+  private static String getMethodName(TestIdentifier testIdentifier) {
+    return getJavaSource(testIdentifier).map((source) -> source.getJavaMethodName().orElse(null)).orElse(null);
+  }
+
+  private static Optional<JavaSource> getJavaSource(TestIdentifier testIdentifier) {
+    return testIdentifier.getSource().filter(JavaSource.class::isInstance).map(JavaSource.class::cast);
+  }
+  
+}
diff --git a/plugins/junit5_rt/src/com/intellij/junit5/JUnit5TestRunnerUtil.java b/plugins/junit5_rt/src/com/intellij/junit5/JUnit5TestRunnerUtil.java
new file mode 100644 (file)
index 0000000..0d72bf0
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2000-2016 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.junit5;
+
+import org.junit.gen5.engine.discovery.NameBasedSelector;
+import org.junit.gen5.launcher.TestDiscoveryRequest;
+import org.junit.gen5.launcher.main.TestDiscoveryRequestBuilder;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class JUnit5TestRunnerUtil {
+  
+  public static TestDiscoveryRequest buildRequest(String[] suiteClassNames, final String name, boolean notForked) {
+    if (suiteClassNames.length == 0) {
+      return null;
+    }
+
+    final TestDiscoveryRequestBuilder builder = TestDiscoveryRequestBuilder.request();
+    final List<String> lines = new ArrayList<>();
+
+
+    if (suiteClassNames.length == 1 && suiteClassNames[0].charAt(0) == '@') {
+      // all tests in the package specified
+      try {
+        BufferedReader reader = new BufferedReader(new FileReader(suiteClassNames[0].substring(1)));
+        try {
+          final String packageName = reader.readLine();
+          if (packageName == null) return null;
+
+          //todo category?
+          final String categoryName = reader.readLine();
+          String line;
+
+          while ((line = reader.readLine()) != null) {
+            lines.add(line);
+          }
+          //todo set package name
+          String suiteName = packageName.length() == 0 ? "<default package>" : packageName;
+        }
+        finally {
+          reader.close();
+        }
+      }
+      catch (IOException e) {
+        e.printStackTrace();
+        System.exit(1);
+      }
+    }
+    else {
+      Collections.addAll(lines, suiteClassNames);
+    }
+
+    final List<String> mappedLines = lines.stream().map(line -> line.replaceFirst(",", "#")).collect(Collectors.toList());
+    return builder.select(NameBasedSelector.forNames(mappedLines)).build();
+  }
+
+}