Skip to content

Commit 7fca8d7

Browse files
authored
Merge pull request #145 from dwijnand/junit
Cut dependency on ScalaTest
2 parents df1dfe5 + 92de414 commit 7fca8d7

File tree

5 files changed

+113
-142
lines changed

5 files changed

+113
-142
lines changed

build.sbt

+2-11
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
val scalaMajorVersion = SettingKey[Int]("scalaMajorVersion")
22

3-
// so we can set this from automated builds and also depending on Scala version
4-
lazy val scalaTestVersion = settingKey[String]("The version of ScalaTest to use.")
5-
63
// copied from Roman Janusz's Silencer plugin (https://github.com/ghik/silencer/)
74
val saveTestClasspath = taskKey[File](
85
"Saves test classpath to a file so that it can be used by embedded scalac in tests")
@@ -21,7 +18,8 @@ lazy val `genjavadoc-plugin` = (project in file("plugin"))
2118
.settings(
2219
libraryDependencies ++= Seq(
2320
"org.scala-lang" % "scala-compiler" % scalaVersion.value,
24-
"org.scalatest" %% "scalatest" % scalaTestVersion.value % "test"
21+
"junit" % "junit" % "4.12" % Test,
22+
"com.novocode" % "junit-interface" % "0.11" % Test
2523
),
2624
saveTestClasspath := {
2725
val result = (classDirectory in Test).value / "embeddedcp"
@@ -71,13 +69,6 @@ lazy val defaults = Seq(
7169
}
7270
},
7371
scalaMajorVersion := CrossVersion.partialVersion(scalaVersion.value).get._2.toInt,
74-
scalaTestVersion := {
75-
scalaMajorVersion.value match {
76-
case 13 => "3.0.6-SNAP1" // the version available for 2.13.0-M4
77-
case 12 => "3.0.4"
78-
case _ => "2.1.3"
79-
}
80-
},
8172
resolvers += Resolver.mavenLocal,
8273
publishTo := {
8374
if (version.value endsWith "-SNAPSHOT") Some("snapshots" at "https://oss.sonatype.org/content/repositories/snapshots")

plugin/src/test/scala/com/typesafe/genjavadoc/BasicSpec.scala

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
package com.typesafe.genjavadoc
22

3-
import org.scalatest.Matchers
4-
import org.scalatest.WordSpec
5-
63
import util._
74

85
import scala.sys.process._
@@ -16,7 +13,7 @@ object BasicSpec {
1613
}
1714

1815
/** Test basic behaviour of genjavadoc with standard settings */
19-
class BasicSpec extends WordSpec with Matchers with CompilerSpec {
16+
class BasicSpec extends CompilerSpec {
2017

2118
override def sources = BasicSpec.sources
2219
override def expectedPath: String = {
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
package com.typesafe.genjavadoc
22

3-
import org.scalatest.{Matchers, WordSpec}
4-
import org.scalatest.matchers.{MatchResult, Matcher}
53
import java.net.URLClassLoader
64
import java.lang.reflect.Modifier
75

6+
import org.junit.Test
7+
import org.junit.Assert._
8+
89
import util._
910

1011
object SignatureSpec {
@@ -44,119 +45,114 @@ object SignatureSpec {
4445

4546
}
4647

47-
class SignatureSpec extends WordSpec with Matchers {
48+
class SignatureSpec {
4849

4950
import SignatureSpec._
5051

51-
"The generated java files" must {
52-
53-
"contain the same methods and classes as the original Scala files" in {
54-
val doc = IO.tempDir("java")
55-
val docPath = doc.getAbsolutePath
52+
@Test def `the generated java files contain the same methods and classes as the original Scala files`(): Unit = {
53+
val doc = IO.tempDir("java")
54+
val docPath = doc.getAbsolutePath
5655

57-
val scalac = new GenJavadocCompiler(Seq(
58-
s"genjavadoc:out=$docPath",
59-
"genjavadoc:suppressSynthetic=false"
60-
))
56+
val scalac = new GenJavadocCompiler(Seq(
57+
s"genjavadoc:out=$docPath",
58+
"genjavadoc:suppressSynthetic=false"
59+
))
6160

62-
val javaSources = expectedClasses.map{cls =>
63-
docPath + "/" + cls.replace(".", "/") + ".java"
64-
}
65-
val javac = new JavaCompiler
66-
67-
scalac.compile(BasicSpec.sources)
68-
javac.compile(javaSources)
69-
70-
val scalaCL = new URLClassLoader(Array(scalac.target.getAbsoluteFile.toURI.toURL), classOf[List[_]].getClassLoader)
71-
val javaCL = new URLClassLoader(Array(javac.target.getAbsoluteFile.toURI.toURL), classOf[List[_]].getClassLoader)
72-
73-
val accProtLvl = Map(1 -> 1, 2 -> 3, 4 -> 2)
74-
75-
/*
76-
* This translation is necessary for the evil hack that allows things
77-
* nested in nested objects to be accepted by Javadoc: while the emitted
78-
* Java code compiles, the name mangling of javac and scalac differs for
79-
* such nestings, which means that it is impossible to express the Scalac
80-
* generated byte-code in valid Java source. To make things compile
81-
* nonetheless we just accept that the types here are nonsense, but they
82-
* are not usable from Java anyway.
83-
*/
84-
val exception = "(akka.rk.buh.is.it.A\\$[C1D]+\\$)\\$"
85-
val replacemnt = "$1"
86-
87-
def check(jn: String): Unit = {
88-
val jc: Class[_] = javaCL.loadClass(jn)
89-
val sc: Class[_] = scalaCL.loadClass(jn.replaceAll(exception, replacemnt))
90-
91-
def matchJava(j: Set[String]) = Matcher { (s: Traversable[String])
92-
MatchResult(s == j,
93-
s"Scala: \n" +
61+
val javaSources = expectedClasses.map{cls =>
62+
docPath + "/" + cls.replace(".", "/") + ".java"
63+
}
64+
val javac = new JavaCompiler
65+
66+
scalac.compile(BasicSpec.sources)
67+
javac.compile(javaSources)
68+
69+
val scalaCL = new URLClassLoader(Array(scalac.target.getAbsoluteFile.toURI.toURL), classOf[List[_]].getClassLoader)
70+
val javaCL = new URLClassLoader(Array(javac.target.getAbsoluteFile.toURI.toURL), classOf[List[_]].getClassLoader)
71+
72+
val accProtLvl = Map(1 -> 1, 2 -> 3, 4 -> 2)
73+
74+
/*
75+
* This translation is necessary for the evil hack that allows things
76+
* nested in nested objects to be accepted by Javadoc: while the emitted
77+
* Java code compiles, the name mangling of javac and scalac differs for
78+
* such nestings, which means that it is impossible to express the Scalac
79+
* generated byte-code in valid Java source. To make things compile
80+
* nonetheless we just accept that the types here are nonsense, but they
81+
* are not usable from Java anyway.
82+
*/
83+
val exception = "(akka.rk.buh.is.it.A\\$[C1D]+\\$)\\$"
84+
val replacement = "$1"
85+
86+
def check(jn: String): Unit = {
87+
val jc: Class[_] = javaCL.loadClass(jn)
88+
val sc: Class[_] = scalaCL.loadClass(jn.replaceAll(exception, replacement))
89+
90+
def matchJava(s: Set[String], j: Set[String]) = {
91+
val msg = s"Scala: \n" +
9492
s" ${s.mkString("\n ")} \n" +
9593
s"did not match Java: \n" +
9694
s" ${j.mkString("\n ")}\n" +
97-
s"(in $jc)",
98-
s"$s matched $j (in $jc)")
99-
}
100-
101-
val jm = getMethods(jc, filter = false)
102-
val sm = getMethods(sc, filter = true)
103-
printIfNotEmpty(sm -- jm, "missing methods:")
104-
printIfNotEmpty(jm -- sm, "extraneous methods:")
105-
sm should matchJava(jm)
106-
107-
val jsub = getClasses(jc, filter = false)
108-
val ssub = getClasses(sc, filter = true)
109-
printIfNotEmpty(ssub.keySet -- jsub.keySet, "missing classes:")
110-
printIfNotEmpty(jsub.keySet -- ssub.keySet, "extraneous classes:")
111-
ssub.keySet should matchJava(jsub.keySet)
112-
113-
for (n ssub.keys) {
114-
val js = jsub(n)
115-
val ss = ssub(n)
116-
117-
def beEqual[T: Manifest](t: T) = Matcher { (u: T) MatchResult(u == t, s"$u was not equal $t (in $n)", s"$u was equal $t (in $n)") }
118-
def beAtLeast(t: Int) = Matcher { (u: Int) MatchResult(u >= t, s"$u was < $t (in $n)", s"$u was >= $t (in $n)") }
119-
120-
(js.getModifiers & ~15) should beEqual(ss.getModifiers & ~15)
121-
(ss.getModifiers & 8) should beAtLeast(js.getModifiers & 8) // older Scala versions (2.10) were more STATIC ...
122-
accProtLvl(js.getModifiers & 7) should beAtLeast(accProtLvl(ss.getModifiers & 7))
123-
js.getInterfaces.toList.map(_.getName) should beEqual(ss.getInterfaces.toList.map(_.getName))
124-
js.isInterface should beEqual(ss.isInterface)
125-
if (!js.isInterface())
126-
js.getSuperclass.getName should beEqual(ss.getSuperclass.getName)
127-
check(js.getName)
128-
}
95+
s"(in $jc)"
96+
assertEquals(msg, s, j)
12997
}
13098

131-
def printIfNotEmpty(s: Set[String], msg: String): Unit = if (s.nonEmpty) {
132-
println(msg)
133-
s.toList.sorted foreach println
134-
}
135-
136-
def getMethods(c: Class[_], filter: Boolean): Set[String] = {
137-
c.getDeclaredMethods.filterNot(x filter && (defaultFilteredStrings.exists { s => x.getName.contains(s) }
138-
|| javaKeywords.contains(x.getName)
139-
|| x.getName == "$init$" // These synthetic methods show up in 2.12.0-M4+ even though they are not in the generated Java sources
140-
|| (filter && Modifier.isStatic(x.getModifiers) && x.getName.endsWith("$")) // These synthetic static methods appear since 2.12.0-M5+ as companions to default methods
141-
|| startsWithNumber.findFirstIn(x.getName).isDefined))
142-
.map(_.toGenericString)
143-
.map(_.replace("default ", "abstract ")) // Scala 2.12.0-M4+ creates default methods for trait method implementations. We treat them as abstract for now.
144-
.map(_.replaceAll(exception, replacemnt))
145-
.toSet
99+
val jm = getMethods(jc, filter = false)
100+
val sm = getMethods(sc, filter = true)
101+
printIfNotEmpty(sm -- jm, "missing methods:")
102+
printIfNotEmpty(jm -- sm, "extraneous methods:")
103+
matchJava(sm, jm)
104+
105+
val jsub = getClasses(jc, filter = false)
106+
val ssub = getClasses(sc, filter = true)
107+
printIfNotEmpty(ssub.keySet -- jsub.keySet, "missing classes:")
108+
printIfNotEmpty(jsub.keySet -- ssub.keySet, "extraneous classes:")
109+
matchJava(ssub.keySet, jsub.keySet)
110+
111+
for (n ssub.keys) {
112+
val js = jsub(n)
113+
val ss = ssub(n)
114+
115+
def beEqual[T](u: T, t: T) = assertEquals(s"$u was not equal $t (in $n)", t, u)
116+
def beAtLeast(u: Int, t: Int) = assertTrue(s"$u was < $t (in $n)", u >= t)
117+
118+
beEqual(js.getModifiers & ~15, ss.getModifiers & ~15)
119+
beAtLeast(ss.getModifiers & 8, js.getModifiers & 8) // older Scala versions (2.10) were more STATIC ...
120+
beAtLeast(accProtLvl(js.getModifiers & 7), accProtLvl(ss.getModifiers & 7))
121+
beEqual(js.getInterfaces.toList.map(_.getName), ss.getInterfaces.toList.map(_.getName))
122+
beEqual(js.isInterface, ss.isInterface)
123+
if (!js.isInterface())
124+
beEqual(js.getSuperclass.getName, ss.getSuperclass.getName)
125+
check(js.getName)
146126
}
127+
}
147128

148-
def getClasses(c: Class[_], filter: Boolean): Map[String, Class[_]] = {
149-
c.getDeclaredClasses.collect {
150-
case x if (!filter || !(x.getName contains "anon")) => x.getName.replaceAll(exception, replacemnt) -> x
151-
}.toMap
152-
}
129+
def printIfNotEmpty(s: Set[String], msg: String): Unit = if (s.nonEmpty) {
130+
println(msg)
131+
s.toList.sorted foreach println
132+
}
153133

134+
def getMethods(c: Class[_], filter: Boolean): Set[String] = {
135+
c.getDeclaredMethods.filterNot(x filter && (defaultFilteredStrings.exists { s => x.getName.contains(s) }
136+
|| javaKeywords.contains(x.getName)
137+
|| x.getName == "$init$" // These synthetic methods show up in 2.12.0-M4+ even though they are not in the generated Java sources
138+
|| (filter && Modifier.isStatic(x.getModifiers) && x.getName.endsWith("$")) // These synthetic static methods appear since 2.12.0-M5+ as companions to default methods
139+
|| startsWithNumber.findFirstIn(x.getName).isDefined))
140+
.map(_.toGenericString)
141+
.map(_.replace("default ", "abstract ")) // Scala 2.12.0-M4+ creates default methods for trait method implementations. We treat them as abstract for now.
142+
.map(_.replaceAll(exception, replacement))
143+
.toSet
144+
}
154145

155-
for (className <- expectedClasses) {
156-
check(className)
157-
}
146+
def getClasses(c: Class[_], filter: Boolean): Map[String, Class[_]] = {
147+
c.getDeclaredClasses.collect {
148+
case x if (!filter || !(x.getName contains "anon")) => x.getName.replaceAll(exception, replacement) -> x
149+
}.toMap
158150
}
159151

152+
153+
for (className <- expectedClasses) {
154+
check(className)
155+
}
160156
}
161157

162158
}

plugin/src/test/scala/com/typesafe/genjavadoc/StrictVisibilityTest.scala

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
package com.typesafe.genjavadoc
22

3-
import org.scalatest.Matchers
4-
import org.scalatest.WordSpec
5-
63
import util._
74

85
/** Test behaviour of genjavadoc with strict visibility enabled */
9-
class StrictVisibilitySpec extends WordSpec with Matchers with CompilerSpec {
6+
class StrictVisibilitySpec extends CompilerSpec {
107

118
override def sources = Seq("src/test/resources/input/strict_visibility/test.scala")
129
override def expectedPath: String = "src/test/resources/expected_output/strict_visibility"

plugin/src/test/scala/com/typesafe/genjavadoc/util/CompilerSpec.scala

+14-24
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,11 @@ import java.io.InputStreamReader
55
import java.io.BufferedReader
66
import java.io.File
77

8-
import org.scalatest.Matchers
9-
import org.scalatest.WordSpec
8+
import org.junit.Test
9+
import org.junit.Assert._
1010

11-
12-
/** Utility trait for testing compiler bahaviour. */
13-
trait CompilerSpec { self: WordSpec with Matchers =>
11+
/** Utility trait for testing compiler behaviour. */
12+
trait CompilerSpec {
1413

1514
/** Sources to compile. */
1615
def sources: Seq[String]
@@ -21,32 +20,21 @@ trait CompilerSpec { self: WordSpec with Matchers =>
2120
/** Extra plugin arguments. */
2221
def extraSettings: Seq[String] = Seq.empty
2322

24-
private def configInfo: String = if (extraSettings.isEmpty) {
25-
"default settings"
26-
} else {
27-
extraSettings.mkString(",")
28-
}
29-
30-
("GenJavadoc with " + configInfo) must {
23+
@Test def compileSourcesAndGenerateExpectedOutput(): Unit = {
3124
val doc = IO.tempDir("java")
3225
val docPath = doc.getAbsolutePath
3326
val defaultSettings = Seq(s"out=$docPath", "suppressSynthetic=false")
3427
val scalac = new GenJavadocCompiler((defaultSettings ++ extraSettings).map{ kv =>
3528
s"genjavadoc:$kv"
3629
})
3730

38-
"compile Scala sources" in {
39-
scalac.compile(sources)
40-
assert(!scalac.reporter.hasErrors, "Scala compiler reported errors.")
41-
}
42-
43-
"generate the expected output" in {
44-
lines(run(".", "diff", "-wurN",
45-
"-I", "^ *//", // comment lines
46-
"-I", "^ *private java\\.lang\\.Object readResolve", // since Scala 2.12.0-M3, these methods are emitted in a later compiler phase
47-
expectedPath, docPath)) foreach println
48-
}
31+
scalac.compile(sources)
32+
assertFalse("Scala compiler reported errors", scalac.reporter.hasErrors)
4933

34+
lines(run(".", "diff", "-wurN",
35+
"-I", "^ *//", // comment lines
36+
"-I", "^ *private java\\.lang\\.Object readResolve", // since Scala 2.12.0-M3, these methods are emitted in a later compiler phase
37+
expectedPath, docPath)) foreach println
5038
}
5139

5240
private def run(dir: String, cmd: String*): Process = {
@@ -55,7 +43,9 @@ trait CompilerSpec { self: WordSpec with Matchers =>
5543

5644
private def lines(proc: Process) = {
5745
val b = new BufferedReader(new InputStreamReader(proc.getInputStream()))
58-
Iterator.continually(b.readLine).takeWhile(_ != null || { proc.waitFor(); assert(proc.exitValue == 0); false })
46+
Iterator.continually(b.readLine).takeWhile(
47+
_ != null || { proc.waitFor(); assert(proc.exitValue == 0); false }
48+
)
5949
}
6050

6151

0 commit comments

Comments
 (0)