Skip to content

Commit

Permalink
Add unit test for test discovery
Browse files Browse the repository at this point in the history
  • Loading branch information
Kamil Podsiadlo committed Dec 3, 2021
1 parent db5c049 commit 495e0bf
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 1 deletion.
5 changes: 4 additions & 1 deletion tests/unit/src/main/scala/tests/QuickBuild.scala
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,10 @@ case class QuickBuild(
object QuickBuild {
val supportedTestFrameworks: Map[String, C.TestFramework] = Map(
"org.scalatest::scalatest" -> Config.TestFramework.ScalaTest,
"com.lihaoyi::utest" -> Config.TestFramework(List("utest.runner.Framework"))
"com.lihaoyi::utest" -> Config.TestFramework(
List("utest.runner.Framework")
),
"org.scalameta::munit" -> Config.TestFramework.munit
)

/**
Expand Down
37 changes: 37 additions & 0 deletions tests/unit/src/main/scala/tests/TestingServer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import scala.meta.internal.metals.WindowStateDidChangeParams
import scala.meta.internal.metals.debug.Stoppage
import scala.meta.internal.metals.debug.TestDebugger
import scala.meta.internal.metals.findfiles._
import scala.meta.internal.metals.testProvider.TestDiscovery
import scala.meta.internal.mtags.Semanticdbs
import scala.meta.internal.parsing.Trees
import scala.meta.internal.semanticdb.Scala.Symbols
Expand Down Expand Up @@ -799,6 +800,42 @@ final class TestingServer(
}
}

def testClasses(filename: String): Future[List[TestDiscovery]] = {
val path = toPath(filename)
var retries = 5
val testClasses = Promise[List[TestDiscovery]]()
val handler = { refreshCount: Int =>
if (refreshCount > 0)
Thread.sleep(300)
executeCommand(ServerCommands.DiscoverTests)
.asInstanceOf[Future[ju.List[TestDiscovery]]]
.map(_.asScala.toList)
.foreach { r =>
if (r.exists(_.discovered.asScala.exists(_.nonEmpty))) {
testClasses.trySuccess(r)
} else if (retries > 0) {
retries -= 1
server.compilations.compileFile(path)
} else {
val error =
s"Could not fetch any test classes in $refreshCount tries"
testClasses.tryFailure(new NoSuchElementException(error))
}
}
}

Thread.sleep(300)
for {
_ <- server
.didFocus(path.toURI.toString)
.asScala // model is refreshed only for focused document
_ = client.refreshModelHandler = handler
// first compilation, to trigger the handler
_ <- server.compilations.compileFile(path)
classes <- testClasses.future
} yield classes
}

def codeLenses(filename: String, printCommand: Boolean = false)(
maxRetries: Int
): Future[String] = {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package tests

import scala.concurrent.Future

import scala.meta.internal.metals.MetalsEnrichments._
import scala.meta.internal.metals.ServerCommands
import scala.meta.internal.metals.testProvider.TestDiscovery
import scala.meta.internal.metals.testProvider.TestDiscoveryResult

class DiscoverTestClassesSuite extends BaseLspSuite("discoverTests") {

test("test-classes") {
for {
_ <- Future.successful(cleanWorkspace())
_ <- initialize(s"""|/metals.json
|{
| "app": {
| "libraryDependencies" : [ "org.scalameta::munit:0.7.29", "org.scalatest::scalatest:3.2.1" ],
| "scalaVersion": "2.13.6"
| }
|}
|/app/src/main/scala/foo/bar/MyTestSuite.scala
|package foo.bar
|abstract class AbstractTestSuite1 extends munit.FunSuite
|
|class MunitTestSuite extends AbstractTestSuite1 {
| test("foo") {}
|}
|""".stripMargin)
_ <- server.server.compilations.compilationFinished(
workspace.resolve("app/src/main/scala/foo/bar/MyTestSuite.scala")
)
_ <- server.executeCommand(ServerCommands.CascadeCompile)
_ <- server.didOpen("app/src/main/scala/foo/bar/MyTestSuite.scala")
_ <- server.didSave("app/src/main/scala/foo/bar/MyTestSuite.scala")(
identity
)
res <- server.testClasses("app/src/main/scala/foo/bar/MyTestSuite.scala")
} yield {
val obtained = res.map(TestDiscoveryWrapper(_))
val expected = List(
TestDiscoveryWrapper(
"app",
List(
TestDiscoveryResultWrapper.Package(
"foo",
List(
TestDiscoveryResultWrapper.Package(
"bar",
List(
TestDiscoveryResultWrapper.TestClass(
"foo.bar.MunitTestSuite",
"MunitTestSuite"
)
)
)
)
)
)
)
)

assertEquals(expected, obtained)
}
}
}

final case class TestDiscoveryWrapper(
targetName: String,
discovered: List[TestDiscoveryResultWrapper]
)
object TestDiscoveryWrapper {
def apply(discovery: TestDiscovery): TestDiscoveryWrapper =
TestDiscoveryWrapper(
discovery.targetName,
discovery.discovered.asScala
.map(x => TestDiscoveryResultWrapper(x))
.toList
)
}

sealed trait TestDiscoveryResultWrapper
object TestDiscoveryResultWrapper {
def apply(result: TestDiscoveryResult): TestDiscoveryResultWrapper =
result match {
case pkg: TestDiscoveryResult.Package => Package(pkg)
case test: TestDiscoveryResult.TestClass => TestClass(test)
}
final case class Package private (
prefix: String,
children: List[TestDiscoveryResultWrapper]
) extends TestDiscoveryResultWrapper
object Package {
def apply(pkg: TestDiscoveryResult.Package): Package =
Package(
pkg.prefix,
pkg.children.asScala.map(TestDiscoveryResultWrapper(_)).toList
)
}

final case class TestClass private (
fullyQualifiedName: String,
className: String
) extends TestDiscoveryResultWrapper
object TestClass {
def apply(test: TestDiscoveryResult.TestClass): TestClass =
TestClass(test.fullyQualifiedName, test.className)
}
}

0 comments on commit 495e0bf

Please sign in to comment.