import scala.tools.nsc.Settings
import scala.tools.nsc.interpreter.{ ILoop, replProps }
import scala.tools.partest._
object Test extends StoreReporterDirectTest {
def code = ???
lazy val headerLength = replProps.welcome.lines.size
lazy val promptLength = replProps.prompt.lines.size - 1 // extra newlines
def compileCode(code: String, jarFileName: String) = {
val classpath = List(sys.props("partest.lib"), testOutput.path) mkString sys.props("path.separator")
compileString(newCompiler("-cp", classpath, "-d", s"${testOutput.path}/$jarFileName"))(code)
}
def app1 = """
package test
object Test extends App {
def test(): Unit = {
println("testing...")
}
}"""
def app2 = """
package test
object Test extends App {
def test(): Unit = {
println("testing differently...")
}
}"""
def app3 = """
package test
object Test3 extends App {
def test(): Unit = {
println("new object in existing package")
}
}"""
def app6 = """
package test6
class A extends Test { println("created test6.A") }
class Z extends Test { println("created test6.Z") }
trait Test"""
def test1(): Unit = {
val jar = "test1.jar"
compileCode(app1, jar)
val codeToRun = s"""
|:require ${testOutput.path}/$jar
|test.Test.test()
|""".stripMargin.trim
val output = ILoop.run(codeToRun, settings)
var lines = output.lines.drop(headerLength)
lines = lines drop promptLength
val added = lines.next
assert (
added.contains("Added") && added.contains("test1.jar"),
s"[${added}] in [${output.lines.mkString("/")}]"
)
lines = lines drop promptLength
val r = lines.next
assert(r.contains("testing..."), r)
}
def test2(): Unit = {
// should reject jars with conflicting entries
val jar1 = "test1.jar"
val jar2 = "test2.jar"
compileCode(app2, jar2)
val codeToRun = s"""
|:require ${testOutput.path}/$jar1
|:require ${testOutput.path}/$jar2
|""".stripMargin.trim
val output = ILoop.run(codeToRun, settings)
var lines = output.lines.drop(headerLength)
lines = lines drop promptLength
val added = lines.next
assert(added.contains("Added") && added.contains("test1.jar"), added)
lines = lines drop promptLength
val msg = lines.next
assert(msg.contains("test2.jar") && msg.contains("contains a classfile that already exists on the classpath: test.Test$"), msg)
}
def test3(): Unit = {
// should accept jars with overlapping packages, but no conflicts
val jar1 = "test1.jar"
val jar3 = "test3.jar"
compileCode(app3, jar3)
val codeToRun = s"""
|:require ${testOutput.path}/$jar1
|:require ${testOutput.path}/$jar3
|test.Test3.test()
|""".stripMargin.trim
val output = ILoop.run(codeToRun, settings)
var lines = output.lines.drop(headerLength)
lines = lines drop promptLength
val added = lines.next
assert(added.contains("Added") && added.contains("test1.jar"), added)
lines = lines drop (2 * promptLength + 1)
val r = lines.next
assert(r.contains("new object in existing package"), r)
}
def test4(): Unit = {
// twice the same jar should be rejected
val jar1 = "test1.jar"
val codeToRun = s"""
|:require ${testOutput.path}/$jar1
|:require ${testOutput.path}/$jar1
|""".stripMargin.trim
val output = ILoop.run(codeToRun, settings)
var lines = output.lines.drop(headerLength)
lines = lines drop promptLength
val added = lines.next
assert(added.contains("Added") && added.contains("test1.jar"), added)
lines = lines drop promptLength
val msg = lines.next
assert(msg.contains("test1.jar") && msg.contains("contains a classfile that already exists on the classpath: test.Test$"), msg)
}
def test5(): Unit = {
val codeToRun = ":require /does/not/exist.jar"
val output = ILoop.run(codeToRun, settings)
assert(!output.contains("NullPointerException"), output)
assert(output.contains("Cannot load '/does/not/exist.jar'"), output)
}
def test6(): Unit = {
// Avoid java.lang.NoClassDefFoundError triggered by the old approach of using a Java
// classloader to parse .class files in order to read their names.
val jar = "test6.jar"
compileCode(app6, jar)
val codeToRun = s"""
|:require ${testOutput.path}/$jar
|import test6._; new A; new Z
|""".stripMargin.trim
val output = ILoop.run(codeToRun, settings)
assert(output.contains("created test6.A"), output)
assert(output.contains("created test6.Z"), output)
}
def show(): Unit = {
test1()
test2()
test3()
test4()
test5()
test6()
}
}