Skip to content

Commit 038fd54

Browse files
committed
Verify only props matching the given TestSelectors
Previously, ScalaCheck ignored the selectors that it receives as input in the "root task". This prevented users from running only a subset of properties in a specification by passing their `TestSelector` to ScalaCheck in a `TaskDef`. This patch fixes this by having the root task program the execution of only the requested properties if the `TaskDef` contains only `TestSelector`s. ScalaCheck's behavior remains unchanged if the `TaskDef` contains any other kind of `Selector`.
1 parent ec41b4c commit 038fd54

File tree

2 files changed

+73
-2
lines changed

2 files changed

+73
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* ScalaCheck
3+
* Copyright (c) 2007-2021 Rickard Nilsson. All rights reserved.
4+
* http://www.scalacheck.org
5+
*
6+
* This software is released under the terms of the Revised BSD License.
7+
* There is NO WARRANTY. See the file LICENSE for the full text.
8+
*/
9+
10+
package org.scalacheck
11+
12+
import org.scalacheck.Prop.proved
13+
import sbt.testing.{Selector, SuiteSelector, TaskDef, TestSelector}
14+
15+
object ScalaCheckFrameworkSpecification extends Properties("ScalaCheckFramework") {
16+
17+
private val firstProp = "ScalaCheckFrameworkHelper.first prop"
18+
private val secondProp = "ScalaCheckFrameworkHelper.second prop"
19+
private val thirdProp = "ScalaCheckFrameworkHelper.third prop"
20+
21+
property("all props with SuiteSelector") = {
22+
getPropNamesForSelectors(List(new SuiteSelector)) == List(firstProp, secondProp, thirdProp)
23+
getPropNamesForSelectors(List(new SuiteSelector, new TestSelector(firstProp))) == List(
24+
firstProp,
25+
secondProp,
26+
thirdProp)
27+
getPropNamesForSelectors(List(new SuiteSelector, new TestSelector("no matches"))) == List(
28+
firstProp,
29+
secondProp,
30+
thirdProp)
31+
}
32+
33+
property("only matching props with TestSelector") = {
34+
getPropNamesForSelectors(List(new TestSelector(firstProp))) == List(firstProp)
35+
getPropNamesForSelectors(List(new TestSelector(secondProp))) == List(secondProp)
36+
getPropNamesForSelectors(List(new TestSelector(firstProp), new TestSelector(thirdProp))) == List(
37+
firstProp,
38+
thirdProp)
39+
getPropNamesForSelectors(List(new TestSelector("no matches"))) == Nil
40+
}
41+
42+
private def getPropNamesForSelectors(selectors: List[Selector]): List[String] = {
43+
val framework = new ScalaCheckFramework()
44+
val runner = framework.runner(Array.empty, Array.empty, getClass.getClassLoader).asInstanceOf[ScalaCheckRunner]
45+
val taskDef = new TaskDef(
46+
classOf[ScalaCheckFrameworkSpecificationHelper].getName,
47+
framework.fingerprints()(0),
48+
true,
49+
selectors.toArray)
50+
val baseTask = runner.rootTask(taskDef)
51+
val newTasks = baseTask.execute(null, null)
52+
val propNames = for {
53+
task <- newTasks
54+
selector <- task.taskDef().selectors()
55+
} yield selector.asInstanceOf[TestSelector].testName()
56+
propNames.toList
57+
}
58+
}
59+
60+
class ScalaCheckFrameworkSpecificationHelper extends Properties("ScalaCheckFrameworkHelper") {
61+
property("first prop") = proved
62+
property("second prop") = proved
63+
property("third prop") = proved
64+
}

core/shared/src/main/scala/org/scalacheck/ScalaCheckFramework.scala

+9-2
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,14 @@ private abstract class ScalaCheckRunner extends Runner {
9292
}
9393

9494
def rootTask(td: TaskDef): BaseTask = new BaseTask(td) {
95-
def execute(handler: EventHandler, loggers: Array[Logger]): Array[Task] =
96-
props.map(_._1).toSet.toArray map { name =>
95+
def execute(handler: EventHandler, loggers: Array[Logger]): Array[Task] = {
96+
// If the task contains only `TestSelector`s, then run only these props instead of the whole suite.
97+
val propFilter: String => Boolean =
98+
if (td.selectors().forall(_.isInstanceOf[TestSelector]))
99+
td.selectors().collect { case ts: TestSelector => ts.testName() }.toSet
100+
else
101+
Function.const(true)
102+
props.map(_._1).toSet.filter(propFilter).toArray map { name =>
97103
checkPropTask(
98104
new TaskDef(
99105
td.fullyQualifiedName(),
@@ -102,6 +108,7 @@ private abstract class ScalaCheckRunner extends Runner {
102108
Array(new TestSelector(name))),
103109
single = true)
104110
}
111+
}
105112
}
106113

107114
def checkPropTask(taskDef: TaskDef, single: Boolean): BaseTask = new BaseTask(taskDef) { self =>

0 commit comments

Comments
 (0)