Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Olafur Pall Geirsson committed Jan 3, 2020
0 parents commit dfeaecb
Show file tree
Hide file tree
Showing 13 changed files with 572 additions and 0 deletions.
48 changes: 48 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
*.class
*.log

# sbt specific
.cache
.history
.lib/
dist/*
target/
lib_managed/
src_managed/
project/boot/
project/plugins/project/
**/.bloop

# Scala-IDE specific
.scala_dependencies
.worksheet

.idea

# ENSIME specific
.ensime_cache/
.ensime

.metals/
metals.sbt
metals/project/

.vscode/

local.*

.DS_Store

node_modules

lib/core/metadata.js
lib/core/MetadataBlog.js

website/translated_docs
website/build/
website/yarn.lock
website/node_modules
website/i18n/*
!website/i18n/en.json

project/metals.sbt
1 change: 1 addition & 0 deletions .scalafmt.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
version = "2.3.2"
21 changes: 21 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
def scala212 = "2.12.10"
def scala213 = "2.13.1"
inThisBuild(
List(
scalaVersion := scala213,
crossScalaVersions := List(scala213, scala212),
fork := true
)
)

skip in publish := true

lazy val munit = project
.settings(
libraryDependencies ++= List(
"junit" % "junit" % "4.13",
"com.geirsson" % "junit-interface" % "0.11.1-scalatest",
"com.lihaoyi" %% "sourcecode" % "0.1.9",
"com.lihaoyi" %% "fansi" % "0.2.7"
)
)
47 changes: 47 additions & 0 deletions munit/src/main/scala/munit/Arguments.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package munit

import java.nio.file.Path
import java.nio.file.PathMatcher
import java.nio.file.Paths

class Arguments {
var includeTags: List[Tag] = Nil
var excludeTags: List[Tag] = Nil
var includeFilter: List[PathMatcher] = Nil
var excludeFilter: List[PathMatcher] = Nil

def matchingTests(suite: Suite): List[Test] = {
val parents = suite.getClass.getCanonicalName().split('.')
if (parents.isEmpty) suite.tests.toList
else {
val it = parents.iterator
val path = it.foldLeft(Paths.get(it.next())) {
case (dir, name) => dir.resolve(name)
}
suite.tests.iterator.filter(test => matchesFilter(path, test)).toList
}
}

private def matchesFilter(
parent: Path,
test: Test
): Boolean = {
val path = parent.resolve(test.name)
val isIncluded =
includeFilter.isEmpty ||
includeFilter.exists(_.matches(path))
val isExcluded =
excludeFilter.exists(_.matches(path))
isIncluded && !isExcluded
}
private def matchesTags(
test: Test
): Boolean = {
val isIncluded =
includeTags.isEmpty ||
includeTags.exists(test.tags.contains)
val isExcluded =
includeTags.exists(test.tags.contains)
isIncluded && !isExcluded
}
}
12 changes: 12 additions & 0 deletions munit/src/main/scala/munit/BeforeAll.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package munit

class BeforeAll private[munit] ()
class AfterAll private[munit] ()

class BeforeEach(
val test: Test
)

class AfterEach(
val test: Test
)
155 changes: 155 additions & 0 deletions munit/src/main/scala/munit/Formatter.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
package munit

import scala.collection.mutable
import scala.util.{Failure, Success}
import munit.internal.StackMarker
import munit.internal.Colors
import fansi.Bold
import fansi.Str
import fansi.Attrs

object Formatter extends Formatter

/**
* Default implementation of [[Formatter]], also used by the default SBT test
* framework. Allows some degree of customization of the formatted test results.
*/
trait Formatter {

def formatColor: Boolean = true
def formatTruncateHeight: Int = 15
def formatWrapWidth: Int =
Int.MaxValue >> 1 // halving here to avoid overflows later

def formatValue(x: Any): Str = testValueColor("" + x)

def toggledColor(t: fansi.Attrs): Attrs =
if (formatColor) t else fansi.Attrs.Empty
def testValueColor: Attrs = toggledColor(fansi.Color.Blue)
def exceptionClassColor: Attrs =
toggledColor(fansi.Underlined.On ++ fansi.Color.LightRed)
def exceptionMsgColor: Attrs = toggledColor(fansi.Color.LightRed)
def exceptionPrefixColor: Attrs = toggledColor(fansi.Color.Red)
def exceptionMethodColor: Attrs = toggledColor(fansi.Color.LightRed)
def exceptionPunctuationColor: Attrs = toggledColor(fansi.Color.Red)
def exceptionLineNumberColor: Attrs = toggledColor(fansi.Color.LightRed)

def formatResultColor(success: Boolean): Attrs = toggledColor(
if (success) fansi.Color.Green
else fansi.Color.Red
)

def formatMillisColor: Attrs = toggledColor(Colors.Bold.Faint)

def exceptionStackFrameHighlighter(s: StackTraceElement): Boolean = true

def formatException(x: Throwable, leftIndent: String): Str = {
val output = mutable.Buffer.empty[Str]
var current = x
while (current != null) {
val exCls = exceptionClassColor(current.getClass.getName)
output.append(
joinLineStr(
lineWrapInput(
current.getMessage match {
case null => exCls
case nonNull =>
Str.join(exCls, ": ", exceptionMsgColor(nonNull))
},
leftIndent
),
leftIndent
)
)

val stack = current.getStackTrace

StackMarker
.filterCallStack(stack)
.foreach { e =>
// Scala.js for some reason likes putting in full-paths into the
// filename slot, rather than just the last segment of the file-path
// like Scala-JVM does. This results in that portion of the
// stacktrace being terribly long, wrapping around and generally
// being impossible to read. We thus manually drop the earlier
// portion of the file path and keep only the last segment

val filenameFrag: Str = e.getFileName match {
case null => exceptionLineNumberColor("Unknown")
case fileName =>
val shortenedFilename = fileName.lastIndexOf('/') match {
case -1 => fileName
case n => fileName.drop(n + 1)
}
Str.join(
exceptionLineNumberColor(shortenedFilename),
":",
exceptionLineNumberColor(e.getLineNumber.toString)
)
}

val frameIndent = leftIndent + " "
val wrapper =
if (exceptionStackFrameHighlighter(e)) fansi.Attrs.Empty
else Colors.Bold.Faint

output.append(
"\n",
frameIndent,
joinLineStr(
lineWrapInput(
wrapper(
Str.join(
exceptionPrefixColor(e.getClassName + "."),
exceptionMethodColor(e.getMethodName),
exceptionPunctuationColor("("),
filenameFrag,
exceptionPunctuationColor(")")
)
),
frameIndent
),
frameIndent
)
)
}
current = current.getCause
if (current != null) output.append("\n", leftIndent)
}

Str.join(output.toSeq: _*)
}

def lineWrapInput(input: Str, leftIndent: String): Seq[Str] = {
val output = mutable.Buffer.empty[Str]
val plainText = input.plainText
var index = 0
while (index < plainText.length) {
val nextWholeLine = index + (formatWrapWidth - leftIndent.length)
val (nextIndex, skipOne) = plainText.indexOf('\n', index + 1) match {
case -1 =>
if (nextWholeLine < plainText.length) (nextWholeLine, false)
else (plainText.length, false)
case n =>
if (nextWholeLine < n) (nextWholeLine, false)
else (n, true)
}

output.append(input.substring(index, nextIndex))
if (skipOne) index = nextIndex + 1
else index = nextIndex
}
output.toSeq
}

def joinLineStr(lines: Seq[Str], leftIndent: String): Str = {
Str.join(
lines.flatMap(Seq[Str]("\n", leftIndent, _)).drop(2): _*
)
}

def formatIcon(success: Boolean): Str = {
formatResultColor(success)(if (success) "+" else "X")
}

}
Loading

0 comments on commit dfeaecb

Please sign in to comment.