Runtime support library for scoverage code coverage tool that collects coverage data during program execution when code has been instrumented by the scalac compiler plugin.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Scalac Scoverage Runtime is the runtime support library for scoverage, a code coverage tool for Scala. This library provides the essential instrumentation infrastructure that collects coverage data during program execution when code has been instrumented by the scalac-scoverage-plugin compiler plugin. It supports both JVM and JavaScript platforms through Scala.js.
libraryDependencies += "org.scoverage" %% "scalac-scoverage-runtime" % "1.4.11"<artifactId>scalac-scoverage-runtime_2.11</artifactId>import scoverage.Invoker
import scoverage.Platform._For JavaScript-specific functionality:
import scalajssupport.{File, FileWriter, Source}The runtime library is typically used automatically by instrumented code, but can also be used directly for coverage analysis:
import scoverage.Invoker
import scoverage.Platform._
// Record statement execution (called by instrumented code)
Invoker.invoked(statementId = 42, dataDir = "/path/to/coverage/data")
// Find measurement files for analysis
val dataDir = "/path/to/coverage/data"
val measurementFiles = Invoker.findMeasurementFiles(dataDir)
// Load invoked statement IDs from files
val invokedIds = Invoker.invoked(measurementFiles)
println(s"Covered statements: ${invokedIds.size}")The runtime library uses a cross-platform architecture with several key components:
scoverage.Platform provides unified interfaces across JVM and JavaScript with compile-time type resolutionscoverage.Invoker handles thread-safe recording of statement executions with per-thread measurement filesruntimeUUID) combined with thread ID to create unique measurement filesCore instrumentation runtime that records which statements have been executed during program execution.
object Invoker {
/**
* Records that a statement has been executed
* @param id the ID of the statement that was invoked
* @param dataDir the directory where measurement data is stored
* @param reportTestName whether to include test name information
*/
def invoked(id: Int, dataDir: String, reportTestName: Boolean = false): Unit
/**
* Gets the measurement file path for a given data directory
* @param dataDir the data directory as File
* @return measurement file for current thread
*/
def measurementFile(dataDir: File): File
/**
* Gets the measurement file path for a given data directory
* @param dataDir the data directory path as String
* @return measurement file for current thread
*/
def measurementFile(dataDir: String): File
/**
* Finds all measurement files in the given directory
* @param dataDir the directory to search as String
* @return array of measurement files
*/
def findMeasurementFiles(dataDir: String): Array[File]
/**
* Finds all measurement files in the given directory
* @param dataDir the directory to search as File
* @return array of measurement files
*/
def findMeasurementFiles(dataDir: File): Array[File]
/**
* Loads all invoked statement IDs from measurement files
* @param files sequence of measurement files to read
* @return set of statement IDs that were executed
* @note Each line may contain just the ID, or ID followed by test name (space-separated)
*/
def invoked(files: Seq[File]): Set[Int]
/**
* Utility method to identify calling ScalaTest suite
* @return name of calling test suite or empty string
*/
def getCallingScalaTest: String
}Provides unified cross-platform interfaces for file operations and concurrent data structures.
object Platform {
// JVM Platform (when compiling to JVM bytecode)
type ThreadSafeMap[A, B] = scala.collection.concurrent.TrieMap[A, B]
lazy val ThreadSafeMap: TrieMap.type = TrieMap
type File = java.io.File
type FileWriter = java.io.FileWriter
type FileFilter = java.io.FileFilter
lazy val Source: scala.io.Source.type = scala.io.Source
// JavaScript Platform (when compiling to JavaScript via Scala.js)
type ThreadSafeMap[A, B] = scala.collection.mutable.HashMap[A, B]
lazy val ThreadSafeMap: HashMap.type = HashMap
type File = scalajssupport.File
type FileWriter = scalajssupport.FileWriter
type FileFilter = scalajssupport.FileFilter
lazy val Source: scalajssupport.Source.type = scalajssupport.Source
}JavaScript-compatible file system abstractions that emulate Java I/O APIs for Scala.js environments.
// JavaScript File abstraction
class File(path: String) {
/**
* Creates a File with parent path and child name
* @param path parent directory path
* @param child child file/directory name
*/
def this(path: String, child: String)
/** Deletes the file or directory */
def delete(): Unit
/** Returns the absolute path */
def getAbsolutePath(): String
/** Returns the file name */
def getName(): String
/** Returns the file path */
def getPath(): String
/** Checks if this is a directory */
def isDirectory(): Boolean
/** Creates directory structure */
def mkdirs(): Unit
/** Lists all files in directory */
def listFiles(): Array[File]
/** Lists files matching filter */
def listFiles(filter: FileFilter): Array[File]
/** Reads entire file content as string */
def readFile(): String
}
object File {
/** Joins path components */
def pathJoin(path: String, child: String): String
/** Writes data to file */
def write(path: String, data: String, mode: String = "a"): Unit
}
// JavaScript FileWriter abstraction
class FileWriter(file: File, append: Boolean) {
/** Create FileWriter for file without append mode */
def this(file: File)
/** Create FileWriter for file path without append mode */
def this(file: String)
/** Create FileWriter for file path with append mode */
def this(file: String, append: Boolean)
/** Appends character sequence, returns this for chaining */
def append(csq: CharSequence): FileWriter
/** Closes the writer */
def close(): Unit
/** Flushes the writer */
def flush(): Unit
}
// JavaScript Source abstraction
object Source {
/** Creates source reader from file */
def fromFile(file: File): scala.io.Source
}
// File filtering interface
trait FileFilter {
/** Returns true if file should be included */
def accept(file: File): Boolean
}
// JavaScript File trait hierarchy
trait JsFile {
/** Deletes the file or directory */
def delete(): Unit
/** Returns the absolute path */
def getAbsolutePath(): String
/** Returns the file name */
def getName(): String
/** Returns the file path */
def getPath(): String
/** Checks if this is a directory */
def isDirectory(): Boolean
/** Creates directory structure */
def mkdirs(): Unit
/** Lists all files in directory */
def listFiles(): Array[File]
/** Lists files matching filter */
def listFiles(filter: FileFilter): Array[File]
/** Reads entire file content as string */
def readFile(): String
}
trait JsFileObject {
/** Writes data to file with mode (default append) */
def write(path: String, data: String, mode: String = "a"): Unit
/** Joins path components */
def pathJoin(path: String, child: String): String
/** Creates JsFile instance for path */
def apply(path: String): JsFile
}// Core platform types (resolved at compile time based on target platform)
type ThreadSafeMap[A, B] // TrieMap on JVM, HashMap on JS
type File // java.io.File on JVM, scalajssupport.File on JS
type FileWriter // java.io.FileWriter on JVM, scalajssupport.FileWriter on JS
type FileFilter // java.io.FileFilter on JVM, scalajssupport.FileFilter on JSThe library handles errors gracefully across both platforms:
false for isDirectory() if file doesn't exist)dataDirToIds.synchronized to guard against SI-7943invoked(files) method skips empty lines in measurement files using if (!line.isEmpty)java.util.concurrent.TrieMap for thread-safe collectionsThreadLocal storage for file writersscala.collection.mutable.HashMap (JavaScript is single-threaded)NodeFile, RhinoFile, PhantomFile)Packages (Rhino), callPhantom (PhantomJS), or defaults to Node.jsscoverage.measurements.<UUID>.<threadId>"123""123 MySuite" (when reportTestName = true)Recording coverage data (typically done by instrumented code):
import scoverage.Invoker
// Record that statement 123 was executed
Invoker.invoked(123, "/tmp/scoverage-data")
// Record with test name information
Invoker.invoked(456, "/tmp/scoverage-data", reportTestName = true)Analyzing coverage data:
import scoverage.Invoker
import scoverage.Platform._
val dataDir = "/tmp/scoverage-data"
// Find all measurement files
val files = Invoker.findMeasurementFiles(dataDir)
println(s"Found ${files.length} measurement files")
// Load executed statement IDs
val executedIds = Invoker.invoked(files.toSeq)
println(s"Total statements executed: ${executedIds.size}")
// Check if specific statement was executed
val statementId = 42
if (executedIds.contains(statementId)) {
println(s"Statement $statementId was executed")
}Cross-platform file operations:
import scoverage.Platform._
// This works on both JVM and JavaScript
val file = new File("/path/to/data", "measurements.txt")
val writer = new FileWriter(file, append = true)
writer.append("42\n")
writer.close()
// Read measurement data
val source = Source.fromFile(file)
val lines = source.getLines().toList
source.close()