scala.tools.partest.nest.StreamCapture.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of scala-partest Show documentation
Show all versions of scala-partest Show documentation
Scala Compiler Testing Tool
The newest version!
/*
* Scala (https://www.scala-lang.org)
*
* Copyright EPFL and Lightbend, Inc.
*
* Licensed under Apache License 2.0
* (http://www.apache.org/licenses/LICENSE-2.0).
*
* See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*/
package scala.tools.partest.nest
import java.io.{Console => _, _}
import java.nio.charset.Charset
import scala.util.Using
object StreamCapture {
def savingSystem[A](body: => A): A = {
val savedOut = System.out
val savedErr = System.err
try body
finally {
System.setErr(savedErr)
System.setOut(savedOut)
}
}
/** Set err to out. */
def redirErr[A](body: => A): A = savingSystem {
System.setOut(System.err)
body
}
def capturingOutErr[A](output: OutputStream)(body: => A): A = {
val charset = Charset.defaultCharset()
Using.resource(new PrintStream(output, /*autoflush=*/true, charset.name())) { printStream =>
savingSystem {
System.setOut(printStream)
System.setErr(printStream)
Console.withErr(printStream) {
Console.withOut(printStream) {
body
}
}
}
}
}
def withExtraProperties[A](extra: Map[String, String])(action: => A): A = {
val saved = System.getProperties()
val modified = new java.util.Properties()
// on Java 9, we need to cast our way around this:
// src/main/scala/scala/tools/partest/nest/StreamCapture.scala:44: ambiguous reference to overloaded definition,
// both method putAll in class Properties of type (x$1: java.util.Map[_, _])Unit
// and method putAll in class Hashtable of type (x$1: java.util.Map[_ <: Object, _ <: Object])Unit
// match argument types (java.util.Properties)
(modified: java.util.Hashtable[AnyRef, AnyRef]).putAll(saved)
extra.foreach { case (k, v) => modified.setProperty(k, v) }
// Trying to avoid other threads seeing the new properties object prior to the new entries
// https://github.com/scala/scala/pull/6391#issuecomment-371346171
// (JDK 22 deprecates `storeFence`; once we drop JDK 8 we can use the VarHandles one instead)
UnsafeAccess.U.storeFence(): @annotation.nowarn("cat=deprecation")
System.setProperties(modified)
try {
action
} finally {
System.setProperties(saved)
}
}
}