Skip to content

Commit

Permalink
Merge pull request #108 from kpodsiad/test-selector
Browse files Browse the repository at this point in the history
Take into account `TaskDef`s with `TestSelector`s
  • Loading branch information
eed3si9n authored Dec 29, 2021
2 parents 320b678 + a13b847 commit f8c6372
Show file tree
Hide file tree
Showing 8 changed files with 173 additions and 7 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,7 @@ target
/\.manager/
/\.idea/
/\.idea_modules/
.metals/
.bloop/
.bsp/
.vscode/
37 changes: 31 additions & 6 deletions src/main/java/com/novocode/junit/JUnitRunner.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import org.junit.runner.notification.RunListener;
import sbt.testing.Runner;
import sbt.testing.Task;
import sbt.testing.Selector;
import sbt.testing.TestSelector;
import sbt.testing.TaskDef;

import java.util.*;
Expand Down Expand Up @@ -77,15 +79,38 @@ else if(s.startsWith("-D") && s.contains("=")) {
@Override
public Task[] tasks(TaskDef[] taskDefs) {
used = true;
int length = taskDefs.length;
Task[] tasks = new Task[length];
for (int i = 0; i < length; i++) {
TaskDef taskDef = taskDefs[i];
tasks[i] = new JUnitTask(this, settings, taskDef);
}
Task[] tasks = Arrays
.stream(taskDefs)
.map(taskDef -> {
RunSettings alteredSettings = alterRunSettings(this.settings, taskDef.selectors());
return new JUnitTask(this, alteredSettings, taskDef);
})
.toArray(Task[]::new);
return tasks;
}

/**
* Alter default RunSettings depending on the passed selectors.
* If selectors contains only elements of type TestSelector, then default settings are altered to include only test
* names from these selectors. This allows to run particular test cases within given test class.
* testFilter is treated as a regular expression, hence joining is done via '|'.
*/
private RunSettings alterRunSettings(RunSettings defaultSettings, Selector[] selectors) {
boolean onlyTestSelectors = Arrays.stream(selectors).allMatch(selector -> selector instanceof TestSelector);
if (onlyTestSelectors) {
String testFilter = Arrays
.stream(selectors)
.map(selector -> ((TestSelector) selector).testName())
.collect(Collectors.joining("|"));
// if already provided testFilter is not empty add to it | (regex or operator)
String currentFilter = defaultSettings.testFilter.length() > 0 ? defaultSettings.testFilter + "|" : "";
String newFilter = currentFilter + testFilter;
return defaultSettings.withTestFilter(newFilter);
}

return defaultSettings;
}

private RunListener createRunListener(String runListenerClassName) {
if(runListenerClassName != null) {
try {
Expand Down
11 changes: 10 additions & 1 deletion src/main/java/com/novocode/junit/RunSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,15 @@ class RunSettings {
this.testFilter = testFilter;
}

public RunSettings withTestFilter(String newTestFilter) {
String ignoreRunners = String.join(",", this.ignoreRunners);
return new RunSettings(
this.color, this.decodeScalaNames, this.quiet, this.verbosity, this.summary, this.logAssert,
ignoreRunners, this.logExceptionClass, this.sysprops, this.globPatterns, this.includeCategories,
this.excludeCategories, newTestFilter
);
}

String decodeName(String name) {
return decodeScalaNames ? decodeScalaName(name) : name;
}
Expand Down Expand Up @@ -108,7 +117,7 @@ String buildErrorMessage(Throwable t) {

private String buildColoredName(Description desc, String c1, String c2, String c3) {
StringBuilder b = new StringBuilder();

String cn = decodeName(desc.getClassName());
int pos1 = cn.indexOf('$');
int pos2 = pos1 == -1 ? cn.lastIndexOf('.') : cn.lastIndexOf('.', pos1);
Expand Down
6 changes: 6 additions & 0 deletions src/sbt-test/simple/check-test-selector/build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
name := "test-project"

scalaVersion := "2.13.7"

libraryDependencies += "com.github.sbt" % "junit-interface" % sys.props("plugin.version") % "test"
libraryDependencies += "org.scala-sbt" % "test-agent" % "1.5.5" % Test
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sbt.version=1.6.1
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import com.novocode.junit.JUnitFramework
import com.novocode.junit.JUnitFingerprint

import org.junit.Test
import org.junit.Assert._

import sbt.testing._
import scala.collection.mutable.ArrayBuffer

/**
* Check if TestSelector's are correctly handled by JUnitRunner.
* Execute prepared TaskDef's using manually created instances of sbt.testing.{Framework and Runner}.
*/
class CheckTestSelector {
val framework = new JUnitFramework();
val runner = framework.runner(
Array.empty[String],
Array.empty[String],
this.getClass().getClassLoader()
);

private def getEventHandler(): (ArrayBuffer[String], EventHandler) = {
val executedItems = new scala.collection.mutable.ArrayBuffer[String]
val eventHandler = new EventHandler {
override def handle(event: Event) =
if (event.status() == Status.Success) {
executedItems.addOne(event.fullyQualifiedName())
}
}
(executedItems, eventHandler)
}

private def getTaskDefs(selectors: Array[Selector]): Array[TaskDef] = {
Array(
new TaskDef("a.b.MyTestSuite", new JUnitFingerprint(), false, selectors)
)
}

@Test
def runAllViaSuiteSelector() {
val selectors = Array[Selector](
new SuiteSelector
)
val taskDefs = Array(
new TaskDef("a.b.MyTestSuite", new JUnitFingerprint(), false, selectors)
)

val tasks = runner.tasks(taskDefs)
assertEquals(tasks.size, 1)
val task = tasks(0)

val (executedItems, eventHandler) = getEventHandler()

task.execute(eventHandler, Nil.toArray)
assertArrayEquals(
Array[Object]("a.b.MyTestSuite.testBar", "a.b.MyTestSuite.testFoo"),
executedItems.toArray[Object]
)
}

@Test
def runAllViaTestSelectors() {
val selectors = Array[Selector](
new TestSelector("testFoo"),
new TestSelector("testBar")
)
val taskDefs = getTaskDefs(selectors)

val tasks = runner.tasks(taskDefs)
assertEquals(tasks.size, 1)
val task = tasks(0)

val (executedItems, eventHandler) = getEventHandler()

task.execute(eventHandler, Nil.toArray)
assertArrayEquals(
Array[Object]("a.b.MyTestSuite.testBar", "a.b.MyTestSuite.testFoo"),
executedItems.toArray[Object]
)
}

@Test
def runOnlyOne() {
val selectors = Array[Selector](
new TestSelector("testFoo")
)
val taskDefs = getTaskDefs(selectors)

val tasks = runner.tasks(taskDefs)
assertEquals(tasks.size, 1)
val task = tasks(0)

val (executedItems, eventHandler) = getEventHandler()

task.execute(eventHandler, Nil.toArray)
assertArrayEquals(
Array[Object]("a.b.MyTestSuite.testFoo"),
executedItems.toArray[Object]
)

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package a.b

import org.junit.Test
import org.junit.Assert.assertEquals

class MyTestSuite {

@Test
def testFoo(): Unit = {
assertEquals("Test should pass", true, true)
}

@Test
def testBar(): Unit = {
assertEquals("Test should pass", true, true)
}
}
2 changes: 2 additions & 0 deletions src/sbt-test/simple/check-test-selector/test
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# make sure the unit test passes
> test

0 comments on commit f8c6372

Please sign in to comment.