Skip to content

Commit 8744565

Browse files
authored
Verify only props matching the given TestSelectors (#1031)
* 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`. * Combine properties in test Previously, only the last property would be verified and the others would be ignored. This patch fixes the tests so that all properties are verified.
1 parent 38559e0 commit 8744565

File tree

2 files changed

+73
-2
lines changed

2 files changed

+73
-2
lines changed
Lines changed: 64 additions & 0 deletions
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.{all, 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") = all(
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") = all(
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

Lines changed: 9 additions & 2 deletions
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)