Skip to content

Commit 262024d

Browse files
authored
Merge pull request #823 from eed3si9n/wip/location
Fix Location macro to be hermetic
2 parents 7eb4a9a + aae74ae commit 262024d

18 files changed

+74
-23
lines changed

munit/js/src/main/scala/munit/internal/io/Files.scala

+2
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,6 @@ object Files {
2727
}
2828
result
2929
}
30+
def exists(path: MunitPath): Boolean =
31+
JSIO.exists(path.toString)
3032
}

munit/js/src/main/scala/munit/internal/io/PlatformIO.scala

+3
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@ object PlatformIO {
99
object Files {
1010
def readAllLines(path: Path): java.util.List[String] =
1111
munit.internal.io.Files.readAllLines(path)
12+
def exists(path: Path): Boolean =
13+
munit.internal.io.Files.exists(path)
1214
}
1315

1416
type Path = MunitPath
17+
val Path = MunitPath
1518
val Paths = munit.internal.io.Paths
1619
}

munit/jvm/src/main/scala/munit/internal/io/PlatformIO.scala

+5
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,14 @@ object PlatformIO {
99
object Files {
1010
def readAllLines(path: Path): java.util.List[String] =
1111
java.nio.file.Files.readAllLines(path)
12+
def exists(path: Path): Boolean =
13+
java.nio.file.Files.exists(path)
1214
}
1315

1416
type Path = java.nio.file.Path
17+
object Path {
18+
def workingDirectory: Path = Paths.get(sys.props("user.dir"))
19+
}
1520
object Paths {
1621
def get(path: String): Path = java.nio.file.Paths.get(path)
1722
}

munit/native/src/main/scala/munit/internal/io/PlatformIO.scala

+5
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,14 @@ object PlatformIO {
99
object Files {
1010
def readAllLines(path: Path): java.util.List[String] =
1111
java.nio.file.Files.readAllLines(path)
12+
def exists(path: Path): Boolean =
13+
java.nio.file.Files.exists(path)
1214
}
1315

1416
type Path = java.nio.file.Path
17+
object Path {
18+
def workingDirectory: Path = Paths.get(sys.props("user.dir"))
19+
}
1520
object Paths {
1621
def get(path: String): Path = java.nio.file.Paths.get(path)
1722
}

munit/shared/src/main/scala-3/munit/internal/MacroCompat.scala

+12-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ import scala.quoted._
66
import scala.language.experimental.macros
77

88
object MacroCompat {
9+
private val workingDirectory: String = {
10+
val sep = java.io.File.separator
11+
val cwd = sys.props("user.dir")
12+
if (cwd.endsWith(sep)) cwd
13+
else cwd + sep
14+
}
915

1016
trait LocationMacro {
1117
inline implicit def generate: Location = ${ locationImpl() }
@@ -15,11 +21,15 @@ object MacroCompat {
1521
def locationImpl()(using Quotes): Expr[Location] = {
1622
import quotes.reflect._
1723
val pos = Position.ofMacroExpansion
18-
val path = pos.sourceFile.getJPath
24+
val path0 = pos.sourceFile.getJPath
1925
.map(_.toString())
2026
.getOrElse(pos.sourceFile.path)
27+
val relativePath =
28+
if (path0.startsWith(workingDirectory))
29+
path0.drop(workingDirectory.length)
30+
else path0
2131
val startLine = pos.startLine + 1
22-
'{ new Location(${ Expr(path) }, ${ Expr(startLine) }) }
32+
'{ new Location(${ Expr(relativePath) }, ${ Expr(startLine) }) }
2333
}
2434

2535
trait ClueMacro {

munit/shared/src/main/scala/munit/internal/MacroCompatScala2.scala

+8-1
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,15 @@ object MacroCompatScala2 {
1010

1111
def locationImpl(c: Context): c.Tree = {
1212
import c.universe._
13+
val workingDirectory: String =
14+
sys.props("user.dir") + java.io.File.separator
1315
val line = Literal(Constant(c.enclosingPosition.line))
14-
val path = Literal(Constant(c.enclosingPosition.source.path))
16+
val path0 = c.enclosingPosition.source.path
17+
val relativePath =
18+
if (path0.startsWith(workingDirectory))
19+
path0.drop(workingDirectory.length)
20+
else path0
21+
val path = Literal(Constant(relativePath))
1522
New(c.mirror.staticClass(classOf[Location].getName()), path, line)
1623
}
1724

munit/shared/src/main/scala/munit/internal/console/Lines.scala

+20-1
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,28 @@ class Lines extends Serializable {
1616
}
1717
def formatPath(location: Location): String =
1818
location.path
19+
20+
def findPath(cwd: String, path: String, max: Int): Path = {
21+
val p = Paths.get(cwd).resolve(path)
22+
def getParentPath(somePath: String, sep: String): String = {
23+
val somePath1 =
24+
if (somePath.endsWith(sep)) somePath.dropRight(sep.length)
25+
else somePath
26+
val sep1 =
27+
if (sep == "\\") "\\\\"
28+
else sep
29+
somePath1.split(sep1).dropRight(1).mkString(sep)
30+
}
31+
if (Files.exists(p)) p
32+
else if (max < 1) sys.error(s"$path was not found")
33+
else if (cwd.contains("\\"))
34+
findPath(getParentPath(cwd, "\\"), path, max - 1)
35+
else findPath(getParentPath(cwd, "/"), path, max - 1)
36+
}
37+
1938
def formatLine(location: Location, message: String, clues: Clues): String = {
2039
try {
21-
val path = Paths.get(location.path)
40+
val path = findPath(Path.workingDirectory.toString, location.path, 3)
2241
val lines = filecache.getOrElseUpdate(
2342
path, {
2443
Files.readAllLines(path).asScala.toArray

tests/shared/src/main/scala/munit/AssertionsFrameworkSuite.scala

+4-4
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,15 @@ class AssertionsFrameworkSuite extends FunSuite {
4343
object AssertionsFrameworkSuite
4444
extends FrameworkTest(
4545
classOf[AssertionsFrameworkSuite],
46-
"""|==> failure munit.AssertionsFrameworkSuite.equal-tostring - /scala/munit/AssertionsFrameworkSuite.scala:11 values are not equal even if they have the same `toString()`: C
46+
"""|==> failure munit.AssertionsFrameworkSuite.equal-tostring - tests/shared/src/main/scala/munit/AssertionsFrameworkSuite.scala:11 values are not equal even if they have the same `toString()`: C
4747
|10: }
4848
|11: assertEquals[Any, Any](new A(), new B())
4949
|12: }
50-
|==> failure munit.AssertionsFrameworkSuite.case-class-productPrefix - /scala/munit/AssertionsFrameworkSuite.scala:21 values are not equal even if they have the same `toString()`: A()
50+
|==> failure munit.AssertionsFrameworkSuite.case-class-productPrefix - tests/shared/src/main/scala/munit/AssertionsFrameworkSuite.scala:21 values are not equal even if they have the same `toString()`: A()
5151
|20: }
5252
|21: assertEquals[Any, Any](a.A(), b.A())
5353
|22: }
54-
|==> failure munit.AssertionsFrameworkSuite.different-toString - /scala/munit/AssertionsFrameworkSuite.scala:35
54+
|==> failure munit.AssertionsFrameworkSuite.different-toString - tests/shared/src/main/scala/munit/AssertionsFrameworkSuite.scala:35
5555
|34: }
5656
|35: assertEquals[Any, Any](a.A(), b.A())
5757
|36: }
@@ -61,7 +61,7 @@ object AssertionsFrameworkSuite
6161
|=> Diff (- obtained, + expected)
6262
|-a.A()
6363
|+b.B()
64-
|==> failure munit.AssertionsFrameworkSuite.toString-has-different-whitespace - /scala/munit/AssertionsFrameworkSuite.scala:39 values are not equal, even if their text representation only differs in leading/trailing whitespace and ANSI escape characters: foo
64+
|==> failure munit.AssertionsFrameworkSuite.toString-has-different-whitespace - tests/shared/src/main/scala/munit/AssertionsFrameworkSuite.scala:39 values are not equal, even if their text representation only differs in leading/trailing whitespace and ANSI escape characters: foo
6565
|38: test("toString-has-different-whitespace") {
6666
|39: assertEquals[Any, Any]("foo", "foo ")
6767
|40: }

tests/shared/src/main/scala/munit/AsyncFunFixtureFrameworkSuite.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ object AsyncFunFixtureFrameworkSuite
5454
classOf[AsyncFunFixtureFrameworkSuite],
5555
"""|==> failure munit.AsyncFunFixtureFrameworkSuite.fail when setup fails - failure in setup
5656
|==> failure munit.AsyncFunFixtureFrameworkSuite.fail when teardown fails - failure in teardown
57-
|==> failure munit.AsyncFunFixtureFrameworkSuite.fail when test and teardown fail - /scala/munit/AsyncFunFixtureFrameworkSuite.scala:28 failure in test
57+
|==> failure munit.AsyncFunFixtureFrameworkSuite.fail when test and teardown fail - tests/shared/src/main/scala/munit/AsyncFunFixtureFrameworkSuite.scala:28 failure in test
5858
|27: failingTeardown.test("fail when test and teardown fail") { _ =>
5959
|28: fail("failure in test")
6060
|29: }

tests/shared/src/main/scala/munit/BoxedFrameworkSuite.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class BoxedFrameworkSuite extends FunSuite {
2020
object BoxedFrameworkSuite
2121
extends FrameworkTest(
2222
classOf[BoxedFrameworkSuite],
23-
"""|==> failure munit.BoxedFrameworkSuite.exist issue - /scala/munit/BoxedFrameworkSuite.scala:15 assertion failed
23+
"""|==> failure munit.BoxedFrameworkSuite.exist issue - tests/shared/src/main/scala/munit/BoxedFrameworkSuite.scala:15 assertion failed
2424
|14: )
2525
|15: assert(values.exists(outer => outer.data.exists(inner => inner.value > 90)))
2626
|16: }

tests/shared/src/main/scala/munit/CiOnlyFrameworkSuite.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class CiOnlyFrameworkSuite extends FunSuite {
1313
object CiOnlyFrameworkSuite
1414
extends FrameworkTest(
1515
classOf[CiOnlyFrameworkSuite],
16-
"""|==> failure munit.CiOnlyFrameworkSuite.only - /scala/munit/CiOnlyFrameworkSuite.scala:5 'Only' tag is not allowed when `isCI=true`
16+
"""|==> failure munit.CiOnlyFrameworkSuite.only - tests/shared/src/main/scala/munit/CiOnlyFrameworkSuite.scala:5 'Only' tag is not allowed when `isCI=true`
1717
|4: override def isCI: Boolean = true
1818
|5: test("only".only) {
1919
|6: println("pass")

tests/shared/src/main/scala/munit/DiffProductFrameworkSuite.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class DiffProductFrameworkSuite extends FunSuite {
1414
object DiffProductFrameworkSuite
1515
extends FrameworkTest(
1616
classOf[DiffProductFrameworkSuite],
17-
"""|==> failure munit.DiffProductFrameworkSuite.pass - /scala/munit/DiffProductFrameworkSuite.scala:9
17+
"""|==> failure munit.DiffProductFrameworkSuite.pass - tests/shared/src/main/scala/munit/DiffProductFrameworkSuite.scala:9
1818
|8: val john2 = User("John", 43, 2.to(2).toList)
1919
|9: assertEquals(john2, john)
2020
|10: }

tests/shared/src/main/scala/munit/DuplicateNameFrameworkSuite.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ object DuplicateNameFrameworkSuite
1818
extends FrameworkTest(
1919
classOf[DuplicateNameFrameworkSuite],
2020
"""|==> success munit.DuplicateNameFrameworkSuite.a
21-
|==> failure munit.DuplicateNameFrameworkSuite.a-1 - /scala/munit/DuplicateNameFrameworkSuite.scala:9 boom
21+
|==> failure munit.DuplicateNameFrameworkSuite.a-1 - tests/shared/src/main/scala/munit/DuplicateNameFrameworkSuite.scala:9 boom
2222
|8: check("a")(() => ())
2323
|9: check("a")(() => fail("boom"))
2424
|10: check("a")(() => fail("boom"))
25-
|==> failure munit.DuplicateNameFrameworkSuite.a-2 - /scala/munit/DuplicateNameFrameworkSuite.scala:10 boom
25+
|==> failure munit.DuplicateNameFrameworkSuite.a-2 - tests/shared/src/main/scala/munit/DuplicateNameFrameworkSuite.scala:10 boom
2626
|9: check("a")(() => fail("boom"))
2727
|10: check("a")(() => fail("boom"))
2828
|11: check("a")(() => ())

tests/shared/src/main/scala/munit/FailFrameworkSuite.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class FailFrameworkSuite extends FunSuite {
1212
object FailFrameworkSuite
1313
extends FrameworkTest(
1414
classOf[FailFrameworkSuite],
15-
"""|==> failure munit.FailFrameworkSuite.pass - /scala/munit/FailFrameworkSuite.scala:4 expected failure but test passed
15+
"""|==> failure munit.FailFrameworkSuite.pass - tests/shared/src/main/scala/munit/FailFrameworkSuite.scala:4 expected failure but test passed
1616
|3:class FailFrameworkSuite extends FunSuite {
1717
|4: test("pass".fail) {
1818
|5: // println("pass")

tests/shared/src/main/scala/munit/FailSuiteFrameworkSuite.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ object FailSuiteFrameworkSuite
1616
extends FrameworkTest(
1717
classOf[FailSuiteFrameworkSuite],
1818
"""|==> success munit.FailSuiteFrameworkSuite.pass
19-
|==> failure munit.FailSuiteFrameworkSuite.fail - /scala/munit/FailSuiteFrameworkSuite.scala:8 Oops, can not do anything.
19+
|==> failure munit.FailSuiteFrameworkSuite.fail - tests/shared/src/main/scala/munit/FailSuiteFrameworkSuite.scala:8 Oops, can not do anything.
2020
|7: test("fail") {
2121
|8: failSuite("Oops, can not do anything.")
2222
|9: }

tests/shared/src/main/scala/munit/Issue179FrameworkSuite.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class Issue179FrameworkSuite extends FunSuite {
99
object Issue179FrameworkSuite
1010
extends FrameworkTest(
1111
classOf[Issue179FrameworkSuite],
12-
"""|==> failure munit.Issue179FrameworkSuite.issue-179 - /scala/munit/Issue179FrameworkSuite.scala:5
12+
"""|==> failure munit.Issue179FrameworkSuite.issue-179 - tests/shared/src/main/scala/munit/Issue179FrameworkSuite.scala:5
1313
|4: test("issue-179") {
1414
|5: assertNoDiff("/n", "A/n")
1515
|6: }

tests/shared/src/main/scala/munit/StackTraceFrameworkSuite.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ object FullStackTraceFrameworkSuite
2828
extends BaseStackTraceFrameworkSuite(
2929
Array("-F"),
3030
"""|at munit.Assertions:failComparison
31-
|==> failure munit.StackTraceFrameworkSuite.fail - /scala/munit/StackTraceFrameworkSuite.scala:5
31+
|==> failure munit.StackTraceFrameworkSuite.fail - tests/shared/src/main/scala/munit/StackTraceFrameworkSuite.scala:5
3232
|4: test("fail") {
3333
|5: assertNoDiff("a", "b")
3434
|6: }
@@ -45,7 +45,7 @@ object SmallStackTraceFrameworkSuite
4545
extends BaseStackTraceFrameworkSuite(
4646
Array(),
4747
"""|at munit.Assertions:failComparison
48-
|==> failure munit.StackTraceFrameworkSuite.fail - /scala/munit/StackTraceFrameworkSuite.scala:5
48+
|==> failure munit.StackTraceFrameworkSuite.fail - tests/shared/src/main/scala/munit/StackTraceFrameworkSuite.scala:5
4949
|4: test("fail") {
5050
|5: assertNoDiff("a", "b")
5151
|6: }

tests/shared/src/test/scala/munit/LinesSuite.scala

+4-4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ class LinesSuite extends FunSuite {
77
"hello",
88
Location.generate,
99
// comment
10-
"""|LinesSuite.scala:8 hello
10+
"""|tests/shared/src/test/scala/munit/LinesSuite.scala:8 hello
1111
|7: "hello",
1212
|8: Location.generate,
1313
|9: // comment
@@ -19,7 +19,7 @@ class LinesSuite extends FunSuite {
1919
"hello\nworld!",
2020
Location.generate,
2121
// comment
22-
"""|LinesSuite.scala:20
22+
"""|tests/shared/src/test/scala/munit/LinesSuite.scala:20
2323
|19: "hello\nworld!",
2424
|20: Location.generate,
2525
|21: // comment
@@ -39,14 +39,14 @@ class LinesSuite extends FunSuite {
3939
test(options) {
4040
val obtained = munitLines
4141
.formatLine(location, message)
42-
.replace(location.path, location.filename)
42+
.replace(raw"""tests\shared\src\test\scala\munit\""", "tests/shared/src/test/scala/munit/") // for Windows
4343
assertNoDiff(obtained, expected)
4444
}
4545
}
4646

4747
val line: Int = Location.generate.line + 7
4848
val endOfFileExpected: String =
49-
s"""|LinesSuite.scala:${line} issue-211
49+
s"""|tests/shared/src/test/scala/munit/LinesSuite.scala:${line} issue-211
5050
|${line - 1}: // hello!
5151
|${line}: check("end-of-file", "issue-211", Location.generate, endOfFileExpected ) }
5252
|""".stripMargin

0 commit comments

Comments
 (0)