aboutsummaryrefslogblamecommitdiff
path: root/compiler/test/dotty/tools/dotc/repl/TestREPL.scala
blob: c5557b86e985d6555573436754dd0d566b2a2ad2 (plain) (tree)
1
2
3
4
5
6
7
8
9

                  
            
 
                            
                         
                                          

                                              
 







                                                                                            

                                             
                                      
 


                                                     


                                                   
                                                                                


                               
 
                                                                                        
                                       
                                              
                             

                                      
                              



                                                                              
                                             


                                                                

                             
       
                             
     




                              
                                                                 
                                                                  
                                                                         
                         


                                                


                   
 




















                                                                                      
package dotty
package tools.dotc
package repl

import core.Contexts.Context
import collection.mutable
import java.io.{StringWriter, PrintStream}
import dotty.tools.io.{ PlainFile, Directory }
import org.junit.Test

/** A subclass of REPL used for testing.
 *  It takes a transcript of a REPL session in `script`. The transcript
 *  starts with the first input prompt `scala> ` and ends with `scala> :quit` and a newline.
 *  Invoking `process()` on the `TestREPL` runs all input lines and
 *  collects then interleaved with REPL output in a string writer `out`.
 *  Invoking `check()` checks that the collected output matches the original
 *  `script`.
 */
class TestREPL(script: String) extends REPL {

  private val out = new StringWriter()

  override lazy val config = new REPL.Config {
    override val output = new NewLinePrintWriter(out)

    override def context(ctx: Context) = {
      val fresh = ctx.fresh
      fresh.setSetting(ctx.settings.color, "never")
      fresh.setSetting(ctx.settings.classpath, Jars.dottyReplDeps.mkString(":"))
      fresh.initialize()(fresh)
      fresh
    }

    override def input(in: Interpreter)(implicit ctx: Context) = new InteractiveReader {
      val lines = script.lines.buffered
      def readLine(prompt: String): String = {
        val line = lines.next
        val buf = new StringBuilder
        if (line.startsWith(prompt)) {
          output.println(line)
          buf append line.drop(prompt.length)
          while (lines.hasNext && lines.head.startsWith(continuationPrompt)) {
            val continued = lines.next
            output.println(continued)
            buf append System.lineSeparator()
            buf append continued.drop(continuationPrompt.length)
          }
          buf.toString
        }
        else readLine(prompt)
      }
      val interactive = false
    }
  }

  def check() = {
    out.close()
    val printed = out.toString
    val transcript = printed.drop(printed.indexOf(config.prompt))
    if (transcript.toString.lines.toList != script.lines.toList) {
      println("input differs from transcript (copy is repl.transcript):")
      println(transcript)
      val s = new PrintStream("repl.transcript")
      s.print(transcript)
      s.close()
      assert(false)
    }
  }
}

class REPLTests {
  def replFile(prefix: String, fileName: String): Unit = {
    val path = s"$prefix$fileName"
    val f = new PlainFile(path)
    val repl = new TestREPL(new String(f.toCharArray))
    repl.process(Array[String]())
    repl.check()
  }

  def replFiles(path: String): Unit = {
    val dir = Directory(path)
    val fileNames = dir.files.toArray.map(_.jfile.getName).filter(_ endsWith ".check")
    for (name <- fileNames) {
      println(s"testing $path$name")
      replFile(path, name)
    }
  }

  @Test def replAll = replFiles("../tests/repl/")
}