forked from scalameta/munit
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Olafur Pall Geirsson
committed
Jan 3, 2020
0 parents
commit dfeaecb
Showing
13 changed files
with
572 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
version = "2.3.2" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" | ||
) | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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") | ||
} | ||
|
||
} |
Oops, something went wrong.