Skip to content

Commit

Permalink
support scala-native Scala 3 build
Browse files Browse the repository at this point in the history
  • Loading branch information
xuwei-k committed Jan 22, 2022
1 parent ae799c7 commit b69352c
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 31 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ jobs:
java: temurin@8
scala: 2.13.8
platform: js
- workers: 1
os: ubuntu-latest
java: temurin@8
scala: 3.1.0
platform: native
- workers: 1
os: ubuntu-latest
java: temurin@8
Expand Down
14 changes: 11 additions & 3 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ ThisBuild / githubWorkflowBuildMatrixInclusions ++=
}

ThisBuild / githubWorkflowBuildMatrixInclusions ++=
crossScalaVersions.value.filter(_.startsWith("2.")) map { scala =>
crossScalaVersions.value.filterNot(_ == Scala30) map { scala =>
MatrixInclude(
Map(
"os" -> PrimaryOS,
Expand Down Expand Up @@ -253,10 +253,18 @@ lazy val jvm = project.in(file("jvm"))
lazy val native = project.in(file("native"))
.settings(sharedSettings: _*)
.settings(
scalaVersion := Scala212,
crossScalaVersions := Seq(Scala212, Scala213),
// TODO: re-enable MiMa for native once published
mimaPreviousArtifacts := Set(),
publish / skip := CrossVersion.partialVersion(scalaVersion.value) == Some((3, 0)),
Compile / doc / scalacOptions --= {
// TODO remove this workaround
// https://github.com/scala-native/scala-native/issues/2503
if (scalaBinaryVersion.value == "3") {
(Compile / doc / scalacOptions).value.filter(_.contains("-Xplugin"))
} else {
Nil
}
},
libraryDependencies ++= Seq(
"org.scala-native" %%% "test-interface" % nativeVersion
)
Expand Down
2 changes: 1 addition & 1 deletion project/plugin.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def printAndDie(msg: String): Nothing = {
sys.error(msg)
}

addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.4.2")
addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.4.3")

addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.4.3")

Expand Down
55 changes: 28 additions & 27 deletions src/main/scala/org/scalacheck/ScalaCheckFramework.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ private abstract class ScalaCheckRunner extends Runner {

def deserializeTask(task: String, deserializer: String => TaskDef): BaseTask = {
val taskDef = deserializer(task)
val countTestSelectors = taskDef.selectors.toSeq.count {
val countTestSelectors = taskDef.selectors().toSeq.count {
case _:TestSelector => true
case _ => false
}
Expand All @@ -37,7 +37,7 @@ private abstract class ScalaCheckRunner extends Runner {
}

def serializeTask(task: Task, serializer: TaskDef => String) =
serializer(task.taskDef)
serializer(task.taskDef())

def tasks(taskDefs: Array[TaskDef]): Array[Task] = {
val isForked = taskDefs.exists(_.fingerprint().getClass.getName.contains("ForkMain"))
Expand All @@ -47,13 +47,14 @@ private abstract class ScalaCheckRunner extends Runner {
protected def sbtSetup(loader: ClassLoader): Parameters => Parameters =
_.withTestCallback(new Test.TestCallback {}).withCustomClassLoader(Some(loader))

abstract class BaseTask(override val taskDef: TaskDef) extends Task {
val tags: Array[String] = Array()
abstract class BaseTask(_taskDef: TaskDef) extends Task {
override def taskDef(): TaskDef = _taskDef
def tags(): Array[String] = Array()

val loaded: Either[Prop, Properties] = {
val fp = taskDef.fingerprint.asInstanceOf[SubclassFingerprint]
val obj = if (fp.isModule) Platform.loadModule(taskDef.fullyQualifiedName,loader)
else Platform.newInstance(taskDef.fullyQualifiedName, loader, Seq())(Seq())
val fp = taskDef().fingerprint().asInstanceOf[SubclassFingerprint]
val obj = if (fp.isModule()) Platform.loadModule(taskDef().fullyQualifiedName(),loader)
else Platform.newInstance(taskDef().fullyQualifiedName(), loader, Seq())(Seq())
obj match {
case props: Properties => Right(props)
case prop: Prop => Left(prop)
Expand All @@ -80,7 +81,7 @@ private abstract class ScalaCheckRunner extends Runner {
def log(loggers: Array[Logger], ok: Boolean, msg: String) =
loggers foreach { l =>
val logstr =
if(!l.ansiCodesSupported) msg
if(!l.ansiCodesSupported()) msg
else s"${if (ok) Console.GREEN else Console.RED}$msg${Console.RESET}"
l.info(logstr)
}
Expand All @@ -93,8 +94,8 @@ private abstract class ScalaCheckRunner extends Runner {
def rootTask(td: TaskDef): BaseTask = new BaseTask(td) {
def execute(handler: EventHandler, loggers: Array[Logger]): Array[Task] =
props.map(_._1).toSet.toArray map { name =>
checkPropTask(new TaskDef(td.fullyQualifiedName, td.fingerprint,
td.explicitlySpecified, Array(new TestSelector(name)))
checkPropTask(new TaskDef(td.fullyQualifiedName(), td.fingerprint(),
td.explicitlySpecified(), Array(new TestSelector(name)))
, single = true)
}
}
Expand All @@ -105,9 +106,9 @@ private abstract class ScalaCheckRunner extends Runner {

if (single) {
val mprops: Map[String, Prop] = props.toMap
self.taskDef.selectors.foreach {
self.taskDef().selectors().foreach {
case ts: TestSelector =>
val name = ts.testName
val name = ts.testName()
mprops.get(name).foreach { prop =>
executeInternal(prop, name, handler, loggers, propertyFilter)
}
Expand All @@ -129,29 +130,29 @@ private abstract class ScalaCheckRunner extends Runner {
val result = Test.check(params, prop)

val event = new Event {
val status = result.status match {
def status() = result.status match {
case Test.Passed => Status.Success
case _: Test.Proved => Status.Success
case _: Test.Failed => Status.Failure
case Test.Exhausted => Status.Failure
case _: Test.PropException => Status.Error
}
val throwable = result.status match {
def throwable() = result.status match {
case Test.PropException(_, e, _) => new OptionalThrowable(e)
case _: Test.Failed => new OptionalThrowable(
new Exception(pretty(result, Params(0)))
)
case _ => new OptionalThrowable()
}
val fullyQualifiedName = self.taskDef.fullyQualifiedName
val selector = new TestSelector(name)
val fingerprint = self.taskDef.fingerprint
val duration = -1L
def fullyQualifiedName() = self.taskDef().fullyQualifiedName()
def selector() = new TestSelector(name)
def fingerprint() = self.taskDef().fingerprint()
def duration() = -1L
}

handler.handle(event)

event.status match {
event.status() match {
case Status.Success => successCount.incrementAndGet()
case Status.Error => errorCount.incrementAndGet()
case Status.Skipped => errorCount.incrementAndGet()
Expand All @@ -166,7 +167,7 @@ private abstract class ScalaCheckRunner extends Runner {
args.grouped(2).filter(twos => verbosityOpts(twos.head))
.toSeq.headOption.map(_.last).map(_.toInt).getOrElse(0)
val s = if (result.passed) "+" else "!"
val n = if (name.isEmpty) self.taskDef.fullyQualifiedName else name
val n = if (name.isEmpty) self.taskDef().fullyQualifiedName() else name
val logMsg = s"$s $n: ${pretty(result, Params(verbosity))}"
log(loggers, result.passed, logMsg)
}
Expand All @@ -179,13 +180,13 @@ final class ScalaCheckFramework extends Framework {
private def mkFP(mod: Boolean, cname: String, noArgCons: Boolean = true) =
new SubclassFingerprint {
def superclassName(): String = cname
val isModule = mod
def isModule() = mod
def requireNoArgConstructor(): Boolean = noArgCons
}

val name = "ScalaCheck"
def name() = "ScalaCheck"

def fingerprints: Array[Fingerprint] = Array(
def fingerprints(): Array[Fingerprint] = Array(
mkFP(false, "org.scalacheck.Properties"),
mkFP(false, "org.scalacheck.Prop"),
mkFP(true, "org.scalacheck.Properties"),
Expand All @@ -197,7 +198,7 @@ final class ScalaCheckFramework extends Framework {
): Runner = new ScalaCheckRunner {

val args = _args
val remoteArgs = _remoteArgs
def remoteArgs() = _remoteArgs
val loader = _loader
val (prms,unknownArgs) = Test.CmdLineParser.parseParams(args)
val applyCmdParams = prms.andThen(sbtSetup(loader))
Expand All @@ -212,7 +213,7 @@ final class ScalaCheckFramework extends Framework {
None
}

def done = if (testCount.get > 0) {
def done() = if (testCount.get > 0) {
val heading = if (testCount.get == successCount.get) "Passed" else "Failed"
s"$heading: Total $testCount, " +
s"Failed $failureCount, Errors $errorCount, Passed $successCount" +
Expand All @@ -226,7 +227,7 @@ final class ScalaCheckFramework extends Framework {
_loader: ClassLoader, send: String => Unit
): Runner = new ScalaCheckRunner {
val args = _args
val remoteArgs = _remoteArgs
def remoteArgs() = _remoteArgs
val loader = _loader

val (prms,unknownArgs) = Test.CmdLineParser.parseParams(args)
Expand All @@ -239,7 +240,7 @@ final class ScalaCheckFramework extends Framework {

def receiveMessage(msg: String) = None

def done = {
def done() = {
send(s"d$testCount,$successCount,$failureCount,$errorCount")
""
}
Expand Down

0 comments on commit b69352c

Please sign in to comment.