Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dotty support #12

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,19 @@ developers := List(
)
)

crossScalaVersions := List("2.10.7", "2.11.12", "2.12.10", "2.13.1")
crossScalaVersions := List(
"2.10.7", "2.11.12", "2.12.10", "2.13.1",
"0.22.0", "0.23.0", "0.24.0-RC1"
)

/** Add src/main/scala-{2|3} to Compile / unmanagedSourceDirectories */
Compile / unmanagedSourceDirectories ++= {
val sourceDir = (Compile / sourceDirectory).value
CrossVersion.partialVersion(scalaVersion.value).map {
case (0 | 3, _) => sourceDir / "scala-3"
case (n, _) => sourceDir / s"scala-$n"
}
}

libraryDependencies ++= Seq(
"org.scalatest" %% "scalatest-core" % "3.2.0-M4",
Expand All @@ -33,6 +45,7 @@ libraryDependencies ++= Seq(
"org.scalatest" %% "scalatest-shouldmatchers" % "3.2.0-M4" % "test",
"junit" % "junit" % "4.12"
)
Test / scalacOptions ++= (if (isDotty.value) Seq("-language:implicitConversions") else Nil)

import scala.xml.{Node => XmlNode, NodeSeq => XmlNodeSeq, _}
import scala.xml.transform.{RewriteRule, RuleTransformer}
Expand Down
2 changes: 2 additions & 0 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.1.1")
addSbtPlugin("com.geirsson" % "sbt-ci-release" % "1.2.2")

addSbtPlugin("com.typesafe.sbt" % "sbt-osgi" % "0.9.4")

addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % "0.4.1")
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.scalatestplus.junit

import org.scalactic.{Prettifier, source}
import org.scalatest.{Assertion, Assertions}

trait VersionSpecificAssertionsForJUnit extends Assertions {
import scala.language.experimental.macros

override def assert(condition: Boolean)(implicit prettifier: Prettifier, pos: source.Position): Assertion = macro AssertionsForJUnitMacro.assert

override def assert(condition: Boolean, clue: Any)(implicit prettifier: Prettifier, pos: source.Position): Assertion = macro AssertionsForJUnitMacro.assertWithClue

override def assume(condition: Boolean)(implicit prettifier: Prettifier, pos: source.Position): Assertion = macro AssertionsForJUnitMacro.assume

override def assume(condition: Boolean, clue: Any)(implicit prettifier: Prettifier, pos: source.Position): Assertion = macro AssertionsForJUnitMacro.assumeWithClue
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.scalatestplus.junit

import org.scalactic.{Prettifier, source}
import org.scalatest.Assertions
import org.scalatest.AssertionsMacro.transform
import org.scalatest.compatible.Assertion

import scala.quoted.{Expr, QuoteContext}

object AssertionsForJUnitMacro {
def assert(condition: Expr[Boolean], prettifier: Expr[Prettifier], pos: Expr[source.Position], clue: Expr[Any])(implicit qctx: QuoteContext): Expr[Assertion] =
transform('{AssertionsForJUnit.assertionsHelper.macroAssert}, condition, prettifier, pos, clue)

def assume(condition: Expr[Boolean], prettifier: Expr[Prettifier], pos: Expr[source.Position], clue: Expr[Any])(implicit qctx: QuoteContext): Expr[Assertion] =
transform('{AssertionsForJUnit.assertionsHelper.macroAssume}, condition, prettifier, pos, clue)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.scalatestplus.junit

import org.scalactic.{Prettifier, source}
import org.scalatest.{Assertions, AssertionsMacro}
import org.scalatest.compatible.Assertion

trait VersionSpecificAssertionsForJUnit extends Assertions {
// https://github.com/lampepfl/dotty/pull/8601#pullrequestreview-380646858
implicit object UseJUnitAssertions

inline def assert(inline condition: Boolean)(implicit prettifier: Prettifier, pos: source.Position, use: UseJUnitAssertions.type): Assertion =
${ AssertionsForJUnitMacro.assert('{condition}, '{prettifier}, '{pos}, '{""}) }

inline def assert(inline condition: Boolean, clue: Any)(implicit prettifier: Prettifier, pos: source.Position, use: UseJUnitAssertions.type): Assertion =
${ AssertionsForJUnitMacro.assert('{condition}, '{prettifier}, '{pos}, '{clue}) }

inline def assume(inline condition: Boolean)(implicit prettifier: Prettifier, pos: source.Position, use: UseJUnitAssertions.type): Assertion =
${ AssertionsForJUnitMacro.assume('{condition}, '{prettifier}, '{pos}, '{""}) }

inline def assume(inline condition: Boolean, clue: Any)(implicit prettifier: Prettifier, pos: source.Position, use: UseJUnitAssertions.type): Assertion =
${ AssertionsForJUnitMacro.assume('{condition}, '{prettifier}, '{pos}, '{clue}) }

}
18 changes: 7 additions & 11 deletions src/main/scala/org/scalatestplus/junit/AssertionsForJUnit.scala
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ import org.scalatest.exceptions.{StackDepthException, TestCanceledException}
*
* @author Bill Venners
*/
trait AssertionsForJUnit extends Assertions {
trait AssertionsForJUnit extends VersionSpecificAssertionsForJUnit {

private[org] override def newAssertionFailedException(optionalMessage: Option[String], optionalCause: Option[Throwable], pos: source.Position, differences: scala.collection.immutable.IndexedSeq[String]): Throwable = {
new JUnitTestFailedError(optionalMessage, optionalCause, pos, None)
Expand All @@ -116,16 +116,6 @@ trait AssertionsForJUnit extends Assertions {
}
}

import scala.language.experimental.macros

override def assert(condition: Boolean)(implicit prettifier: Prettifier, pos: source.Position): Assertion = macro AssertionsForJUnitMacro.assert

override def assert(condition: Boolean, clue: Any)(implicit prettifier: Prettifier, pos: source.Position): Assertion = macro AssertionsForJUnitMacro.assertWithClue

override def assume(condition: Boolean)(implicit prettifier: Prettifier, pos: source.Position): Assertion = macro AssertionsForJUnitMacro.assume

override def assume(condition: Boolean, clue: Any)(implicit prettifier: Prettifier, pos: source.Position): Assertion = macro AssertionsForJUnitMacro.assumeWithClue

/*
private[scalatest] override def newAssertionFailedException(optionalMessage: Option[Any], optionalCause: Option[Throwable], stackDepth: Int): Throwable = {

Expand Down Expand Up @@ -222,6 +212,9 @@ object AssertionsForJUnit extends AssertionsForJUnit {
Succeeded
}

def macroAssert(bool: Bool, clue: Any, pos: source.Position): Assertion =
macroAssert(bool, clue, bool.prettifier, pos)

/**
* Assume that the passed in <code>Bool</code> is <code>true</code>, else throw <code>TestCanceledException</code>.
*
Expand All @@ -236,6 +229,9 @@ object AssertionsForJUnit extends AssertionsForJUnit {
}
Succeeded
}

def macroAssume(bool: Bool, clue: Any, pos: source.Position): Assertion =
macroAssume(bool, clue, bool.prettifier, pos)
}

/**
Expand Down
6 changes: 3 additions & 3 deletions src/main/scala/org/scalatestplus/junit/JUnitHelper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import org.scalatest.{Suite, TagAnnotation}
private[junit] object JUnitHelper {

def mergeMap[A, B](ms: List[Map[A, B]])(f: (B, B) => B): Map[A, B] =
(Map[A, B]() /: (for (m <- ms; kv <- m) yield kv)) { (a, kv) =>
(for (m <- ms; kv <- m) yield kv).foldLeft(Map[A, B]()) { (a, kv) =>
a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv)
}

Expand All @@ -47,7 +47,7 @@ private[junit] object JUnitHelper {
val decodedTestText = scala.reflect.NameTransformer.decode(testText)
val formattedText =
if (includeIcon) {
val testSucceededIcon = Resources.testSucceededIconChar
val testSucceededIcon = Resources.testSucceededIconChar()
(" " * (if (level == 0) 0 else (level - 1))) + Resources.iconPlusShortName(testSucceededIcon, decodedTestText)
}
else {
Expand All @@ -59,7 +59,7 @@ private[junit] object JUnitHelper {
def checkForPublicNoArgConstructor(clazz: java.lang.Class[_]) = {

try {
val constructor = clazz.getConstructor(new Array[java.lang.Class[T] forSome { type T }](0): _*)
val constructor = clazz.getConstructor(new Array[java.lang.Class[_]](0): _*)

Modifier.isPublic(constructor.getModifiers)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class JUnitWrapperSuite(junitClassName: String, loader: ClassLoader) extends Sui
* @return number of expected test count
*/
override def expectedTestCount(filter: Filter): Int = {
getRequest.getRunner.getDescription.testCount
getRequest().getRunner.getDescription.testCount
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/org/scalatestplus/junit/MyRunListener.scala
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ import exceptions._
if (throwableOrNull != null)
throwableOrNull.toString
else
Resources.jUnitTestFailed
Resources.jUnitTestFailed()

val formatter = getIndentedTextForTest(testName, 1, true)
val payload =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ private[junit] class RunNotifierReporter(runNotifier: RunNotifier) extends Repor
case None => null // Yuck. Not sure if the exception passed to new Failure can be null, but it could be given this code. Usually throwable would be defined.
}
val possiblyEmptyMessage = messageOrThrowablesDetailMessage(message, throwable)
val description = Description.createSuiteDescription(Resources.runAborted + " " + possiblyEmptyMessage)
val description = Description.createSuiteDescription(Resources.runAborted() + " " + possiblyEmptyMessage)
runNotifier.fireTestFailure(new Failure(description, throwableOrNull)) // Best we can do in JUnit, as far as I know
runNotifier.fireTestFinished(description)

Expand Down
16 changes: 8 additions & 8 deletions src/test/scala/org/scalatestplus/junit/JUnitRunnerSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -105,15 +105,15 @@ package org.scalatestplus.junit {
test("a test failure is reported due to an exception thrown from " +
"beforeAll when JUnitRunner.run is called directly")
{
val runNotifier =
new RunNotifier {
var methodInvocationCount = 0
var passed: Option[Failure] = None
override def fireTestFailure(failure: Failure): Unit = {
methodInvocationCount += 1
passed = Some(failure)
}
class MyRunNotifier extends RunNotifier {
var methodInvocationCount = 0
var passed: Option[Failure] = None
override def fireTestFailure(failure: Failure): Unit = {
methodInvocationCount += 1
passed = Some(failure)
}
}
val runNotifier = new MyRunNotifier

(new JUnitRunner(classOf[KerblooeySuite])).run(runNotifier)

Expand Down
4 changes: 2 additions & 2 deletions src/test/scala/org/scalatestplus/junit/JUnitSuiteSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@
*/
package org.scalatestplus.junit {

import org.scalatest._
import org.scalatest._
import org.scalatest.events._

// Put fixture suites in a subpackage, so they won't be discovered by
// -m org.scalatest.junit when running the test target for this project.
package helpers {

import _root_.org.junit.Ignore
import _root_.org.junit.Test
import _root_.org.junit.Test

class HappySuite extends JUnitSuite {

Expand Down
102 changes: 48 additions & 54 deletions src/test/scala/org/scalatestplus/junit/RunNotifierSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,15 @@ class RunNotifierSuite extends funsuite.AnyFunSuite {
val ordinal = new Ordinal(99)

test("report(TestStarting) generates a fireTestStarted invocation") {

val runNotifier =
new RunNotifier {
var fireTestStartedInvocationCount = 0
var passedDesc: Option[Description] = None
override def fireTestStarted(description: Description): Unit = {
fireTestStartedInvocationCount += 1
passedDesc = Some(description)
}
class MyRunNotifier extends RunNotifier {
var fireTestStartedInvocationCount = 0
var passedDesc: Option[Description] = None
override def fireTestStarted(description: Description): Unit = {
fireTestStartedInvocationCount += 1
passedDesc = Some(description)
}
}
val runNotifier = new MyRunNotifier

import scala.language.reflectiveCalls

Expand All @@ -60,16 +59,15 @@ class RunNotifierSuite extends funsuite.AnyFunSuite {
}

test("report(TestFailed) generates a fireTestFailure invocation") {

val runNotifier =
new RunNotifier {
var methodInvocationCount = 0
var passed: Option[Failure] = None
override def fireTestFailure(failure: Failure): Unit = {
methodInvocationCount += 1
passed = Some(failure)
}
class MyRunNotifier extends RunNotifier {
var methodInvocationCount = 0
var passed: Option[Failure] = None
override def fireTestFailure(failure: Failure): Unit = {
methodInvocationCount += 1
passed = Some(failure)
}
}
val runNotifier = new MyRunNotifier

val reporter = new RunNotifierReporter(runNotifier)
val exception = new IllegalArgumentException
Expand All @@ -83,16 +81,15 @@ class RunNotifierSuite extends funsuite.AnyFunSuite {
}

test("report(TestSucceeded) generates a fireTestFinished invocation") {

val runNotifier =
new RunNotifier {
var methodInvocationCount = 0
var passed: Option[Description] = None
override def fireTestFinished(description: Description): Unit = {
methodInvocationCount += 1
passed = Some(description)
}
class MyRunNotifier extends RunNotifier {
var methodInvocationCount = 0
var passed: Option[Description] = None
override def fireTestFinished(description: Description): Unit = {
methodInvocationCount += 1
passed = Some(description)
}
}
val runNotifier = new MyRunNotifier

import scala.language.reflectiveCalls

Expand All @@ -104,16 +101,15 @@ class RunNotifierSuite extends funsuite.AnyFunSuite {
}

test("report(TestIgnored) generates a fireTestIgnored invocation") {

val runNotifier =
new RunNotifier {
var methodInvocationCount = 0
var passed: Option[Description] = None
override def fireTestIgnored(description: Description): Unit = {
methodInvocationCount += 1
passed = Some(description)
}
class MyRunNotifier extends RunNotifier {
var methodInvocationCount = 0
var passed: Option[Description] = None
override def fireTestIgnored(description: Description): Unit = {
methodInvocationCount += 1
passed = Some(description)
}
}
val runNotifier = new MyRunNotifier

import scala.language.reflectiveCalls

Expand All @@ -134,16 +130,15 @@ class RunNotifierSuite extends funsuite.AnyFunSuite {

// fireTestFailure is the best we could do given the RunNotifier interface
test("report(SuiteAborted) generates a fireTestFailure invocation") {

val runNotifier =
new RunNotifier {
var methodInvocationCount = 0
var passed: Option[Failure] = None
override def fireTestFailure(failure: Failure): Unit = {
methodInvocationCount += 1
passed = Some(failure)
}
class MyRunNotifier extends RunNotifier {
var methodInvocationCount = 0
var passed: Option[Failure] = None
override def fireTestFailure(failure: Failure): Unit = {
methodInvocationCount += 1
passed = Some(failure)
}
}
val runNotifier = new MyRunNotifier

import scala.language.reflectiveCalls

Expand All @@ -169,16 +164,15 @@ class RunNotifierSuite extends funsuite.AnyFunSuite {

// fireTestFailure is the best we could do given the RunNotifier interface
test("report(RunAborted) generates a fireTestFailure invocation") {

val runNotifier =
new RunNotifier {
var methodInvocationCount = 0
var passed: Option[Failure] = None
override def fireTestFailure(failure: Failure): Unit = {
methodInvocationCount += 1
passed = Some(failure)
}
class MyRunNotifier extends RunNotifier {
var methodInvocationCount = 0
var passed: Option[Failure] = None
override def fireTestFailure(failure: Failure): Unit = {
methodInvocationCount += 1
passed = Some(failure)
}
}
val runNotifier = new MyRunNotifier

val reporter = new RunNotifierReporter(runNotifier)
val exception = new IllegalArgumentException
Expand Down