diff --git a/junit-plugin/src/main/scala/scala/scalanative/junit/plugin/ScalaNativeJUnitPlugin.scala b/junit-plugin/src/main/scala/scala/scalanative/junit/plugin/ScalaNativeJUnitPlugin.scala index c2e41a2c90..88fdb998de 100644 --- a/junit-plugin/src/main/scala/scala/scalanative/junit/plugin/ScalaNativeJUnitPlugin.scala +++ b/junit-plugin/src/main/scala/scala/scalanative/junit/plugin/ScalaNativeJUnitPlugin.scala @@ -53,13 +53,14 @@ class ScalaNativeJUnitPlugin(val global: Global) extends NscPlugin { } private object Names { - val beforeClass: TermName = newTermName("beforeClass") - val afterClass: TermName = newTermName("afterClass") - val before: TermName = newTermName("before") - val after: TermName = newTermName("after") - val tests: TermName = newTermName("tests") - val invokeTest: TermName = newTermName("invokeTest") - val newInstance: TermName = newTermName("newInstance") + val beforeClass: TermName = newTermName("beforeClass") + val afterClass: TermName = newTermName("afterClass") + val before: TermName = newTermName("before") + val after: TermName = newTermName("after") + val testClassMetadata: TermName = newTermName("testClassMetadata") + val tests: TermName = newTermName("tests") + val invokeTest: TermName = newTermName("invokeTest") + val newInstance: TermName = newTermName("newInstance") val instance: TermName = newTermName("instance") val name: TermName = newTermName("name") @@ -68,6 +69,9 @@ class ScalaNativeJUnitPlugin(val global: Global) extends NscPlugin { private lazy val BootstrapperClass = getRequiredClass("scala.scalanative.junit.Bootstrapper") + private lazy val TestClassMetadataClass = + getRequiredClass("scala.scalanative.junit.TestClassMetadata") + private lazy val TestMetadataClass = getRequiredClass("scala.scalanative.junit.TestMetadata") @@ -140,6 +144,7 @@ class ScalaNativeJUnitPlugin(val global: Global) extends NscPlugin { JUnitAnnots.AfterClass), genCallOnParam(bootSym, Names.before, testClass, JUnitAnnots.Before), genCallOnParam(bootSym, Names.after, testClass, JUnitAnnots.After), + genTestMetadata(bootSym, testClass), genTests(bootSym, testMethods), genInvokeTest(bootSym, testClass, testMethods), genNewInstance(bootSym, testClass) @@ -197,8 +202,25 @@ class ScalaNativeJUnitPlugin(val global: Global) extends NscPlugin { typer.typedDefDef(newDefDef(sym, Block(calls: _*))()) } + private def genTestMetadata(owner: ClassSymbol, + testClass: ClassSymbol): DefDef = { + val sym = owner.newMethodSymbol(Names.testClassMetadata) + + sym.setInfoAndEnter( + MethodType(Nil, typeRef(NoType, TestClassMetadataClass, Nil)) + ) + + val ignored = testClass.hasAnnotation(JUnitAnnots.Ignore) + val isIgnored = Literal(Constant(ignored)) + + val rhs = New(TestClassMetadataClass, isIgnored) + + typer.typedDefDef(newDefDef(sym, rhs)()) + } + private def genTests(owner: ClassSymbol, tests: Scope): DefDef = { val sym = owner.newMethodSymbol(Names.tests) + sym.setInfoAndEnter( MethodType(Nil, typeRef(NoType, ArrayClass, List(TestMetadataClass.tpe)))) @@ -209,10 +231,11 @@ class ScalaNativeJUnitPlugin(val global: Global) extends NscPlugin { test.getAnnotation(JUnitAnnots.Test).get.args: _*) val name = Literal(Constant(test.name.toString)) - val ignored = Literal( - Constant(test.hasAnnotation(JUnitAnnots.Ignore))) - New(TestMetadataClass, name, ignored, reifiedAnnot) + val testIgnored = test.hasAnnotation(JUnitAnnots.Ignore) + val isIgnored = Literal(Constant(testIgnored)) + + New(TestMetadataClass, name, isIgnored, reifiedAnnot) } val rhs = ArrayValue(TypeTree(TestMetadataClass.tpe), metadata.toList) diff --git a/junit-runtime/src/main/scala/scala/scalanative/junit/Bootstrapper.scala b/junit-runtime/src/main/scala/scala/scalanative/junit/Bootstrapper.scala index ba5a63e972..915bab451d 100644 --- a/junit-runtime/src/main/scala/scala/scalanative/junit/Bootstrapper.scala +++ b/junit-runtime/src/main/scala/scala/scalanative/junit/Bootstrapper.scala @@ -21,6 +21,7 @@ trait Bootstrapper { def before(instance: AnyRef): Unit def after(instance: AnyRef): Unit + def testClassMetadata(): TestClassMetadata def tests(): Array[TestMetadata] def invokeTest(instance: AnyRef, name: String): Future[Try[Unit]] @@ -39,3 +40,14 @@ final class TestMetadata( val ignored: Boolean, val annotation: org.junit.Test ) + +/** Scala Native interal JUnit test class metadata + * + * This class is public due to implementation details. Only the junit compiler + * plugin may create instances of it. + * + * Relying on this class directly is unspecified behavior. + */ +final class TestClassMetadata( + val ignored: Boolean +) diff --git a/junit-runtime/src/main/scala/scala/scalanative/junit/JUnitTask.scala b/junit-runtime/src/main/scala/scala/scalanative/junit/JUnitTask.scala index 0314bf7768..d93c433f72 100644 --- a/junit-runtime/src/main/scala/scala/scalanative/junit/JUnitTask.scala +++ b/junit-runtime/src/main/scala/scala/scalanative/junit/JUnitTask.scala @@ -33,29 +33,36 @@ private[junit] final class JUnitTask(val taskDef: TaskDef, var total = 0 @tailrec - def runTests(tests: List[TestMetadata]): Try[Unit] = { + def runTests(tests: List[TestMetadata], + testClass: TestClassMetadata): Try[Unit] = { val (nextIgnored, other) = tests.span(_.ignored) - nextIgnored.foreach(t => reporter.reportIgnored(Some(t.name))) - ignored += nextIgnored.size + if (testClass.ignored) { + reporter.reportIgnored(None) + ignored += 1 + Success(()) + } else { + nextIgnored.foreach(t => reporter.reportIgnored(Some(t.name))) + ignored += nextIgnored.size - other match { - case t :: ts => - total += 1 + other match { + case t :: ts => + total += 1 - val fc = executeTestMethod(bootstrapper, t, reporter) - failed += fc - runTests(ts) + val fc = executeTestMethod(bootstrapper, t, reporter) + failed += fc + runTests(ts, testClass) - case Nil => - Success(()) + case Nil => + Success(()) + } } } val result = runTestLifecycle { Success(()) } { _ => catchAll(bootstrapper.beforeClass()) } { _ => - runTests(bootstrapper.tests().toList) + runTests(bootstrapper.tests().toList, bootstrapper.testClassMetadata()) } { _ => catchAll(bootstrapper.afterClass()) } val (errors, timeInSeconds) = result diff --git a/junit-test/outputs/scala/scalanative/junit/IgnoreAllTestAssertions_.txt b/junit-test/outputs/scala/scalanative/junit/IgnoreAllTestAssertions_.txt new file mode 100644 index 0000000000..81b1d1f9f6 --- /dev/null +++ b/junit-test/outputs/scala/scalanative/junit/IgnoreAllTestAssertions_.txt @@ -0,0 +1,5 @@ +ldTest run started +liTest scala.scalanative.junit.IgnoreAllTest ignored +e3scala.scalanative.junit.IgnoreAllTest +ldTest run finished: 0 failed, 1 ignored, 0 total,