From 9bf1caf9c9855682566505b946003060754f407d Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 10 Sep 2024 01:30:46 -0400 Subject: [PATCH 1/5] Fix Location macro to be hermetic **Problem** The Locaiton macro currently captures the absolute path of the source file, which is not hermetic, and won't cache correctly on remote cached build tools such as Bazel, Gradle, and (in development) sbt 2.x. **Solution** This captures the relative path from the working directory instead. --- munit/js/src/main/scala/munit/internal/io/Files.scala | 2 ++ .../src/main/scala/munit/internal/io/PlatformIO.scala | 3 +++ .../src/main/scala/munit/internal/io/PlatformIO.scala | 5 +++++ .../src/main/scala/munit/internal/io/PlatformIO.scala | 5 +++++ .../src/main/scala-3/munit/internal/MacroCompat.scala | 8 ++++++-- .../main/scala/munit/internal/MacroCompatScala2.scala | 7 ++++++- .../src/main/scala/munit/internal/console/Lines.scala | 11 ++++++++++- .../main/scala/munit/AssertionsFrameworkSuite.scala | 8 ++++---- .../scala/munit/AsyncFunFixtureFrameworkSuite.scala | 2 +- .../src/main/scala/munit/BoxedFrameworkSuite.scala | 2 +- .../src/main/scala/munit/CiOnlyFrameworkSuite.scala | 2 +- .../main/scala/munit/DiffProductFrameworkSuite.scala | 2 +- .../scala/munit/DuplicateNameFrameworkSuite.scala | 4 ++-- .../src/main/scala/munit/FailFrameworkSuite.scala | 2 +- .../main/scala/munit/FailSuiteFrameworkSuite.scala | 2 +- .../src/main/scala/munit/Issue179FrameworkSuite.scala | 2 +- .../main/scala/munit/StackTraceFrameworkSuite.scala | 4 ++-- tests/shared/src/test/scala/munit/LinesSuite.scala | 7 +++---- 18 files changed, 55 insertions(+), 23 deletions(-) diff --git a/munit/js/src/main/scala/munit/internal/io/Files.scala b/munit/js/src/main/scala/munit/internal/io/Files.scala index 77ea39d4..94d64267 100644 --- a/munit/js/src/main/scala/munit/internal/io/Files.scala +++ b/munit/js/src/main/scala/munit/internal/io/Files.scala @@ -27,4 +27,6 @@ object Files { } result } + def exists(path: MunitPath): Boolean = + JSIO.exists(path.toString) } diff --git a/munit/js/src/main/scala/munit/internal/io/PlatformIO.scala b/munit/js/src/main/scala/munit/internal/io/PlatformIO.scala index 50ff8eec..695dc6bb 100644 --- a/munit/js/src/main/scala/munit/internal/io/PlatformIO.scala +++ b/munit/js/src/main/scala/munit/internal/io/PlatformIO.scala @@ -9,8 +9,11 @@ object PlatformIO { object Files { def readAllLines(path: Path): java.util.List[String] = munit.internal.io.Files.readAllLines(path) + def exists(path: Path): Boolean = + munit.internal.io.Files.exists(path) } type Path = MunitPath + val Path = MunitPath val Paths = munit.internal.io.Paths } diff --git a/munit/jvm/src/main/scala/munit/internal/io/PlatformIO.scala b/munit/jvm/src/main/scala/munit/internal/io/PlatformIO.scala index 3e942d10..f75479d6 100644 --- a/munit/jvm/src/main/scala/munit/internal/io/PlatformIO.scala +++ b/munit/jvm/src/main/scala/munit/internal/io/PlatformIO.scala @@ -9,9 +9,14 @@ object PlatformIO { object Files { def readAllLines(path: Path): java.util.List[String] = java.nio.file.Files.readAllLines(path) + def exists(path: Path): Boolean = + java.nio.file.Files.exists(path) } type Path = java.nio.file.Path + object Path { + def workingDirectory = Paths.get(sys.props("user.dir")) + } object Paths { def get(path: String): Path = java.nio.file.Paths.get(path) } diff --git a/munit/native/src/main/scala/munit/internal/io/PlatformIO.scala b/munit/native/src/main/scala/munit/internal/io/PlatformIO.scala index 3e942d10..f75479d6 100644 --- a/munit/native/src/main/scala/munit/internal/io/PlatformIO.scala +++ b/munit/native/src/main/scala/munit/internal/io/PlatformIO.scala @@ -9,9 +9,14 @@ object PlatformIO { object Files { def readAllLines(path: Path): java.util.List[String] = java.nio.file.Files.readAllLines(path) + def exists(path: Path): Boolean = + java.nio.file.Files.exists(path) } type Path = java.nio.file.Path + object Path { + def workingDirectory = Paths.get(sys.props("user.dir")) + } object Paths { def get(path: String): Path = java.nio.file.Paths.get(path) } diff --git a/munit/shared/src/main/scala-3/munit/internal/MacroCompat.scala b/munit/shared/src/main/scala-3/munit/internal/MacroCompat.scala index b5abce2b..16c7e331 100644 --- a/munit/shared/src/main/scala-3/munit/internal/MacroCompat.scala +++ b/munit/shared/src/main/scala-3/munit/internal/MacroCompat.scala @@ -6,6 +6,7 @@ import scala.quoted._ import scala.language.experimental.macros object MacroCompat { + private val workingDirectory: String = sys.props("user.dir") + java.io.File.separator trait LocationMacro { inline implicit def generate: Location = ${ locationImpl() } @@ -15,11 +16,14 @@ object MacroCompat { def locationImpl()(using Quotes): Expr[Location] = { import quotes.reflect._ val pos = Position.ofMacroExpansion - val path = pos.sourceFile.getJPath + val path0 = pos.sourceFile.getJPath .map(_.toString()) .getOrElse(pos.sourceFile.path) + val relativePath = + if (path0.startsWith(workingDirectory)) path0.drop(workingDirectory.length) + else path0 val startLine = pos.startLine + 1 - '{ new Location(${ Expr(path) }, ${ Expr(startLine) }) } + '{ new Location(${ Expr(relativePath) }, ${ Expr(startLine) }) } } trait ClueMacro { diff --git a/munit/shared/src/main/scala/munit/internal/MacroCompatScala2.scala b/munit/shared/src/main/scala/munit/internal/MacroCompatScala2.scala index 90c298db..d9936e1c 100644 --- a/munit/shared/src/main/scala/munit/internal/MacroCompatScala2.scala +++ b/munit/shared/src/main/scala/munit/internal/MacroCompatScala2.scala @@ -10,8 +10,13 @@ object MacroCompatScala2 { def locationImpl(c: Context): c.Tree = { import c.universe._ + val workingDirectory: String = sys.props("user.dir") + java.io.File.separator val line = Literal(Constant(c.enclosingPosition.line)) - val path = Literal(Constant(c.enclosingPosition.source.path)) + val path0 = c.enclosingPosition.source.path + val relativePath = + if (path0.startsWith(workingDirectory)) path0.drop(workingDirectory.length) + else path0 + val path = Literal(Constant(relativePath)) New(c.mirror.staticClass(classOf[Location].getName()), path, line) } diff --git a/munit/shared/src/main/scala/munit/internal/console/Lines.scala b/munit/shared/src/main/scala/munit/internal/console/Lines.scala index 440a55dc..65bb81c4 100644 --- a/munit/shared/src/main/scala/munit/internal/console/Lines.scala +++ b/munit/shared/src/main/scala/munit/internal/console/Lines.scala @@ -16,9 +16,18 @@ class Lines extends Serializable { } def formatPath(location: Location): String = location.path + + def findPath(cwd: String, path: String, max: Int): Path = { + val p = Paths.get(cwd).resolve(path) + if (Files.exists(p)) p + else if (max < 1) sys.error(s"$path was not found") + else if (cwd.contains("\\")) findPath(cwd.split("\\").dropRight(1).mkString("\\"), path, max - 1) + else findPath(cwd.split("/").dropRight(1).mkString("/"), path, max - 1) + } + def formatLine(location: Location, message: String, clues: Clues): String = { try { - val path = Paths.get(location.path) + val path = findPath(Path.workingDirectory.toString, location.path, 3) val lines = filecache.getOrElseUpdate( path, { Files.readAllLines(path).asScala.toArray diff --git a/tests/shared/src/main/scala/munit/AssertionsFrameworkSuite.scala b/tests/shared/src/main/scala/munit/AssertionsFrameworkSuite.scala index 1f4c624b..377e85be 100644 --- a/tests/shared/src/main/scala/munit/AssertionsFrameworkSuite.scala +++ b/tests/shared/src/main/scala/munit/AssertionsFrameworkSuite.scala @@ -43,15 +43,15 @@ class AssertionsFrameworkSuite extends FunSuite { object AssertionsFrameworkSuite extends FrameworkTest( classOf[AssertionsFrameworkSuite], - """|==> failure munit.AssertionsFrameworkSuite.equal-tostring - /scala/munit/AssertionsFrameworkSuite.scala:11 values are not equal even if they have the same `toString()`: C + """|==> 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 |10: } |11: assertEquals[Any, Any](new A(), new B()) |12: } - |==> failure munit.AssertionsFrameworkSuite.case-class-productPrefix - /scala/munit/AssertionsFrameworkSuite.scala:21 values are not equal even if they have the same `toString()`: A() + |==> 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() |20: } |21: assertEquals[Any, Any](a.A(), b.A()) |22: } - |==> failure munit.AssertionsFrameworkSuite.different-toString - /scala/munit/AssertionsFrameworkSuite.scala:35 + |==> failure munit.AssertionsFrameworkSuite.different-toString - tests/shared/src/main/scala/munit/AssertionsFrameworkSuite.scala:35 |34: } |35: assertEquals[Any, Any](a.A(), b.A()) |36: } @@ -61,7 +61,7 @@ object AssertionsFrameworkSuite |=> Diff (- obtained, + expected) |-a.A() |+b.B() - |==> 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 + |==> 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 |38: test("toString-has-different-whitespace") { |39: assertEquals[Any, Any]("foo", "foo ") |40: } diff --git a/tests/shared/src/main/scala/munit/AsyncFunFixtureFrameworkSuite.scala b/tests/shared/src/main/scala/munit/AsyncFunFixtureFrameworkSuite.scala index 83697faa..c401b2ee 100644 --- a/tests/shared/src/main/scala/munit/AsyncFunFixtureFrameworkSuite.scala +++ b/tests/shared/src/main/scala/munit/AsyncFunFixtureFrameworkSuite.scala @@ -54,7 +54,7 @@ object AsyncFunFixtureFrameworkSuite classOf[AsyncFunFixtureFrameworkSuite], """|==> failure munit.AsyncFunFixtureFrameworkSuite.fail when setup fails - failure in setup |==> failure munit.AsyncFunFixtureFrameworkSuite.fail when teardown fails - failure in teardown - |==> failure munit.AsyncFunFixtureFrameworkSuite.fail when test and teardown fail - /scala/munit/AsyncFunFixtureFrameworkSuite.scala:28 failure in test + |==> failure munit.AsyncFunFixtureFrameworkSuite.fail when test and teardown fail - tests/shared/src/main/scala/munit/AsyncFunFixtureFrameworkSuite.scala:28 failure in test |27: failingTeardown.test("fail when test and teardown fail") { _ => |28: fail("failure in test") |29: } diff --git a/tests/shared/src/main/scala/munit/BoxedFrameworkSuite.scala b/tests/shared/src/main/scala/munit/BoxedFrameworkSuite.scala index de571a0a..59c98879 100644 --- a/tests/shared/src/main/scala/munit/BoxedFrameworkSuite.scala +++ b/tests/shared/src/main/scala/munit/BoxedFrameworkSuite.scala @@ -20,7 +20,7 @@ class BoxedFrameworkSuite extends FunSuite { object BoxedFrameworkSuite extends FrameworkTest( classOf[BoxedFrameworkSuite], - """|==> failure munit.BoxedFrameworkSuite.exist issue - /scala/munit/BoxedFrameworkSuite.scala:15 assertion failed + """|==> failure munit.BoxedFrameworkSuite.exist issue - tests/shared/src/main/scala/munit/BoxedFrameworkSuite.scala:15 assertion failed |14: ) |15: assert(values.exists(outer => outer.data.exists(inner => inner.value > 90))) |16: } diff --git a/tests/shared/src/main/scala/munit/CiOnlyFrameworkSuite.scala b/tests/shared/src/main/scala/munit/CiOnlyFrameworkSuite.scala index 01e9279c..c89691c4 100644 --- a/tests/shared/src/main/scala/munit/CiOnlyFrameworkSuite.scala +++ b/tests/shared/src/main/scala/munit/CiOnlyFrameworkSuite.scala @@ -13,7 +13,7 @@ class CiOnlyFrameworkSuite extends FunSuite { object CiOnlyFrameworkSuite extends FrameworkTest( classOf[CiOnlyFrameworkSuite], - """|==> failure munit.CiOnlyFrameworkSuite.only - /scala/munit/CiOnlyFrameworkSuite.scala:5 'Only' tag is not allowed when `isCI=true` + """|==> failure munit.CiOnlyFrameworkSuite.only - tests/shared/src/main/scala/munit/CiOnlyFrameworkSuite.scala:5 'Only' tag is not allowed when `isCI=true` |4: override def isCI: Boolean = true |5: test("only".only) { |6: println("pass") diff --git a/tests/shared/src/main/scala/munit/DiffProductFrameworkSuite.scala b/tests/shared/src/main/scala/munit/DiffProductFrameworkSuite.scala index fefd1872..676a9d5e 100644 --- a/tests/shared/src/main/scala/munit/DiffProductFrameworkSuite.scala +++ b/tests/shared/src/main/scala/munit/DiffProductFrameworkSuite.scala @@ -14,7 +14,7 @@ class DiffProductFrameworkSuite extends FunSuite { object DiffProductFrameworkSuite extends FrameworkTest( classOf[DiffProductFrameworkSuite], - """|==> failure munit.DiffProductFrameworkSuite.pass - /scala/munit/DiffProductFrameworkSuite.scala:9 + """|==> failure munit.DiffProductFrameworkSuite.pass - tests/shared/src/main/scala/munit/DiffProductFrameworkSuite.scala:9 |8: val john2 = User("John", 43, 2.to(2).toList) |9: assertEquals(john2, john) |10: } diff --git a/tests/shared/src/main/scala/munit/DuplicateNameFrameworkSuite.scala b/tests/shared/src/main/scala/munit/DuplicateNameFrameworkSuite.scala index e4090479..05e86b91 100644 --- a/tests/shared/src/main/scala/munit/DuplicateNameFrameworkSuite.scala +++ b/tests/shared/src/main/scala/munit/DuplicateNameFrameworkSuite.scala @@ -18,11 +18,11 @@ object DuplicateNameFrameworkSuite extends FrameworkTest( classOf[DuplicateNameFrameworkSuite], """|==> success munit.DuplicateNameFrameworkSuite.a - |==> failure munit.DuplicateNameFrameworkSuite.a-1 - /scala/munit/DuplicateNameFrameworkSuite.scala:9 boom + |==> failure munit.DuplicateNameFrameworkSuite.a-1 - tests/shared/src/main/scala/munit/DuplicateNameFrameworkSuite.scala:9 boom |8: check("a")(() => ()) |9: check("a")(() => fail("boom")) |10: check("a")(() => fail("boom")) - |==> failure munit.DuplicateNameFrameworkSuite.a-2 - /scala/munit/DuplicateNameFrameworkSuite.scala:10 boom + |==> failure munit.DuplicateNameFrameworkSuite.a-2 - tests/shared/src/main/scala/munit/DuplicateNameFrameworkSuite.scala:10 boom |9: check("a")(() => fail("boom")) |10: check("a")(() => fail("boom")) |11: check("a")(() => ()) diff --git a/tests/shared/src/main/scala/munit/FailFrameworkSuite.scala b/tests/shared/src/main/scala/munit/FailFrameworkSuite.scala index 7dcaa402..9da75914 100644 --- a/tests/shared/src/main/scala/munit/FailFrameworkSuite.scala +++ b/tests/shared/src/main/scala/munit/FailFrameworkSuite.scala @@ -12,7 +12,7 @@ class FailFrameworkSuite extends FunSuite { object FailFrameworkSuite extends FrameworkTest( classOf[FailFrameworkSuite], - """|==> failure munit.FailFrameworkSuite.pass - /scala/munit/FailFrameworkSuite.scala:4 expected failure but test passed + """|==> failure munit.FailFrameworkSuite.pass - tests/shared/src/main/scala/munit/FailFrameworkSuite.scala:4 expected failure but test passed |3:class FailFrameworkSuite extends FunSuite { |4: test("pass".fail) { |5: // println("pass") diff --git a/tests/shared/src/main/scala/munit/FailSuiteFrameworkSuite.scala b/tests/shared/src/main/scala/munit/FailSuiteFrameworkSuite.scala index b22a9d36..bcaec610 100644 --- a/tests/shared/src/main/scala/munit/FailSuiteFrameworkSuite.scala +++ b/tests/shared/src/main/scala/munit/FailSuiteFrameworkSuite.scala @@ -16,7 +16,7 @@ object FailSuiteFrameworkSuite extends FrameworkTest( classOf[FailSuiteFrameworkSuite], """|==> success munit.FailSuiteFrameworkSuite.pass - |==> failure munit.FailSuiteFrameworkSuite.fail - /scala/munit/FailSuiteFrameworkSuite.scala:8 Oops, can not do anything. + |==> failure munit.FailSuiteFrameworkSuite.fail - tests/shared/src/main/scala/munit/FailSuiteFrameworkSuite.scala:8 Oops, can not do anything. |7: test("fail") { |8: failSuite("Oops, can not do anything.") |9: } diff --git a/tests/shared/src/main/scala/munit/Issue179FrameworkSuite.scala b/tests/shared/src/main/scala/munit/Issue179FrameworkSuite.scala index 5fa72c70..1576bdc9 100644 --- a/tests/shared/src/main/scala/munit/Issue179FrameworkSuite.scala +++ b/tests/shared/src/main/scala/munit/Issue179FrameworkSuite.scala @@ -9,7 +9,7 @@ class Issue179FrameworkSuite extends FunSuite { object Issue179FrameworkSuite extends FrameworkTest( classOf[Issue179FrameworkSuite], - """|==> failure munit.Issue179FrameworkSuite.issue-179 - /scala/munit/Issue179FrameworkSuite.scala:5 + """|==> failure munit.Issue179FrameworkSuite.issue-179 - tests/shared/src/main/scala/munit/Issue179FrameworkSuite.scala:5 |4: test("issue-179") { |5: assertNoDiff("/n", "A/n") |6: } diff --git a/tests/shared/src/main/scala/munit/StackTraceFrameworkSuite.scala b/tests/shared/src/main/scala/munit/StackTraceFrameworkSuite.scala index a2071c5d..118bc921 100644 --- a/tests/shared/src/main/scala/munit/StackTraceFrameworkSuite.scala +++ b/tests/shared/src/main/scala/munit/StackTraceFrameworkSuite.scala @@ -28,7 +28,7 @@ object FullStackTraceFrameworkSuite extends BaseStackTraceFrameworkSuite( Array("-F"), """|at munit.Assertions:failComparison - |==> failure munit.StackTraceFrameworkSuite.fail - /scala/munit/StackTraceFrameworkSuite.scala:5 + |==> failure munit.StackTraceFrameworkSuite.fail - tests/shared/src/main/scala/munit/StackTraceFrameworkSuite.scala:5 |4: test("fail") { |5: assertNoDiff("a", "b") |6: } @@ -45,7 +45,7 @@ object SmallStackTraceFrameworkSuite extends BaseStackTraceFrameworkSuite( Array(), """|at munit.Assertions:failComparison - |==> failure munit.StackTraceFrameworkSuite.fail - /scala/munit/StackTraceFrameworkSuite.scala:5 + |==> failure munit.StackTraceFrameworkSuite.fail - tests/shared/src/main/scala/munit/StackTraceFrameworkSuite.scala:5 |4: test("fail") { |5: assertNoDiff("a", "b") |6: } diff --git a/tests/shared/src/test/scala/munit/LinesSuite.scala b/tests/shared/src/test/scala/munit/LinesSuite.scala index cecd4997..5bfa1cc0 100644 --- a/tests/shared/src/test/scala/munit/LinesSuite.scala +++ b/tests/shared/src/test/scala/munit/LinesSuite.scala @@ -7,7 +7,7 @@ class LinesSuite extends FunSuite { "hello", Location.generate, // comment - """|LinesSuite.scala:8 hello + """|tests/shared/src/test/scala/munit/LinesSuite.scala:8 hello |7: "hello", |8: Location.generate, |9: // comment @@ -19,7 +19,7 @@ class LinesSuite extends FunSuite { "hello\nworld!", Location.generate, // comment - """|LinesSuite.scala:20 + """|tests/shared/src/test/scala/munit/LinesSuite.scala:20 |19: "hello\nworld!", |20: Location.generate, |21: // comment @@ -39,14 +39,13 @@ class LinesSuite extends FunSuite { test(options) { val obtained = munitLines .formatLine(location, message) - .replace(location.path, location.filename) assertNoDiff(obtained, expected) } } val line: Int = Location.generate.line + 7 val endOfFileExpected: String = - s"""|LinesSuite.scala:${line} issue-211 + s"""|tests/shared/src/test/scala/munit/LinesSuite.scala:${line} issue-211 |${line - 1}: // hello! |${line}: check("end-of-file", "issue-211", Location.generate, endOfFileExpected ) } |""".stripMargin From c9b63ce4a9e9dff5266c5e10399f4a137327673c Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 10 Sep 2024 12:44:00 -0400 Subject: [PATCH 2/5] Scalafmt and Scalafix --- munit/jvm/src/main/scala/munit/internal/io/PlatformIO.scala | 2 +- .../src/main/scala/munit/internal/io/PlatformIO.scala | 2 +- .../src/main/scala/munit/internal/MacroCompatScala2.scala | 6 ++++-- .../src/main/scala/munit/internal/console/Lines.scala | 3 ++- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/munit/jvm/src/main/scala/munit/internal/io/PlatformIO.scala b/munit/jvm/src/main/scala/munit/internal/io/PlatformIO.scala index f75479d6..4f7a623b 100644 --- a/munit/jvm/src/main/scala/munit/internal/io/PlatformIO.scala +++ b/munit/jvm/src/main/scala/munit/internal/io/PlatformIO.scala @@ -15,7 +15,7 @@ object PlatformIO { type Path = java.nio.file.Path object Path { - def workingDirectory = Paths.get(sys.props("user.dir")) + def workingDirectory: Path = Paths.get(sys.props("user.dir")) } object Paths { def get(path: String): Path = java.nio.file.Paths.get(path) diff --git a/munit/native/src/main/scala/munit/internal/io/PlatformIO.scala b/munit/native/src/main/scala/munit/internal/io/PlatformIO.scala index f75479d6..4f7a623b 100644 --- a/munit/native/src/main/scala/munit/internal/io/PlatformIO.scala +++ b/munit/native/src/main/scala/munit/internal/io/PlatformIO.scala @@ -15,7 +15,7 @@ object PlatformIO { type Path = java.nio.file.Path object Path { - def workingDirectory = Paths.get(sys.props("user.dir")) + def workingDirectory: Path = Paths.get(sys.props("user.dir")) } object Paths { def get(path: String): Path = java.nio.file.Paths.get(path) diff --git a/munit/shared/src/main/scala/munit/internal/MacroCompatScala2.scala b/munit/shared/src/main/scala/munit/internal/MacroCompatScala2.scala index d9936e1c..641ff3e8 100644 --- a/munit/shared/src/main/scala/munit/internal/MacroCompatScala2.scala +++ b/munit/shared/src/main/scala/munit/internal/MacroCompatScala2.scala @@ -10,11 +10,13 @@ object MacroCompatScala2 { def locationImpl(c: Context): c.Tree = { import c.universe._ - val workingDirectory: String = sys.props("user.dir") + java.io.File.separator + val workingDirectory: String = + sys.props("user.dir") + java.io.File.separator val line = Literal(Constant(c.enclosingPosition.line)) val path0 = c.enclosingPosition.source.path val relativePath = - if (path0.startsWith(workingDirectory)) path0.drop(workingDirectory.length) + if (path0.startsWith(workingDirectory)) + path0.drop(workingDirectory.length) else path0 val path = Literal(Constant(relativePath)) New(c.mirror.staticClass(classOf[Location].getName()), path, line) diff --git a/munit/shared/src/main/scala/munit/internal/console/Lines.scala b/munit/shared/src/main/scala/munit/internal/console/Lines.scala index 65bb81c4..6cc97211 100644 --- a/munit/shared/src/main/scala/munit/internal/console/Lines.scala +++ b/munit/shared/src/main/scala/munit/internal/console/Lines.scala @@ -21,7 +21,8 @@ class Lines extends Serializable { val p = Paths.get(cwd).resolve(path) if (Files.exists(p)) p else if (max < 1) sys.error(s"$path was not found") - else if (cwd.contains("\\")) findPath(cwd.split("\\").dropRight(1).mkString("\\"), path, max - 1) + else if (cwd.contains("\\")) + findPath(cwd.split("\\").dropRight(1).mkString("\\"), path, max - 1) else findPath(cwd.split("/").dropRight(1).mkString("/"), path, max - 1) } From 0ef1d84d6fb22a7f533afa45fd6022a87e6816d5 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 10 Sep 2024 13:08:45 -0400 Subject: [PATCH 3/5] Deal with Windows paths --- .../src/main/scala/munit/internal/console/Lines.scala | 10 ++++++++-- tests/shared/src/test/scala/munit/LinesSuite.scala | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/munit/shared/src/main/scala/munit/internal/console/Lines.scala b/munit/shared/src/main/scala/munit/internal/console/Lines.scala index 6cc97211..fffc9913 100644 --- a/munit/shared/src/main/scala/munit/internal/console/Lines.scala +++ b/munit/shared/src/main/scala/munit/internal/console/Lines.scala @@ -19,11 +19,17 @@ class Lines extends Serializable { def findPath(cwd: String, path: String, max: Int): Path = { val p = Paths.get(cwd).resolve(path) + def getParentPath(somePath: String, sep: String): String = { + val somePath1 = + if (somePath.endsWith(sep)) somePath.dropRight(sep.length) + else somePath + somePath1.split(sep).dropRight(1).mkString(sep) + } if (Files.exists(p)) p else if (max < 1) sys.error(s"$path was not found") else if (cwd.contains("\\")) - findPath(cwd.split("\\").dropRight(1).mkString("\\"), path, max - 1) - else findPath(cwd.split("/").dropRight(1).mkString("/"), path, max - 1) + findPath(getParentPath(cwd, "\\"), path, max - 1) + else findPath(getParentPath(cwd, "/"), path, max - 1) } def formatLine(location: Location, message: String, clues: Clues): String = { diff --git a/tests/shared/src/test/scala/munit/LinesSuite.scala b/tests/shared/src/test/scala/munit/LinesSuite.scala index 5bfa1cc0..59f6ef3a 100644 --- a/tests/shared/src/test/scala/munit/LinesSuite.scala +++ b/tests/shared/src/test/scala/munit/LinesSuite.scala @@ -39,6 +39,7 @@ class LinesSuite extends FunSuite { test(options) { val obtained = munitLines .formatLine(location, message) + .replace(raw"""tests\shared\src\test\scala\munit\""", "tests/shared/src/test/scala/munit/") // for Windows assertNoDiff(obtained, expected) } } From 594b695606c54d7eba76129b90f7437bb941b072 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 10 Sep 2024 13:29:44 -0400 Subject: [PATCH 4/5] More formatting --- .../src/main/scala-3/munit/internal/MacroCompat.scala | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/munit/shared/src/main/scala-3/munit/internal/MacroCompat.scala b/munit/shared/src/main/scala-3/munit/internal/MacroCompat.scala index 16c7e331..041da301 100644 --- a/munit/shared/src/main/scala-3/munit/internal/MacroCompat.scala +++ b/munit/shared/src/main/scala-3/munit/internal/MacroCompat.scala @@ -6,7 +6,8 @@ import scala.quoted._ import scala.language.experimental.macros object MacroCompat { - private val workingDirectory: String = sys.props("user.dir") + java.io.File.separator + private val workingDirectory: String = + sys.props("user.dir") + java.io.File.separator trait LocationMacro { inline implicit def generate: Location = ${ locationImpl() } @@ -20,7 +21,8 @@ object MacroCompat { .map(_.toString()) .getOrElse(pos.sourceFile.path) val relativePath = - if (path0.startsWith(workingDirectory)) path0.drop(workingDirectory.length) + if (path0.startsWith(workingDirectory)) + path0.drop(workingDirectory.length) else path0 val startLine = pos.startLine + 1 '{ new Location(${ Expr(relativePath) }, ${ Expr(startLine) }) } From aae74ae9850d68ab2555aaa3a9e10d1f4cece7e5 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 10 Sep 2024 14:22:31 -0400 Subject: [PATCH 5/5] Regex fix --- .../src/main/scala-3/munit/internal/MacroCompat.scala | 8 ++++++-- .../src/main/scala/munit/internal/console/Lines.scala | 5 ++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/munit/shared/src/main/scala-3/munit/internal/MacroCompat.scala b/munit/shared/src/main/scala-3/munit/internal/MacroCompat.scala index 041da301..ffbf1fdb 100644 --- a/munit/shared/src/main/scala-3/munit/internal/MacroCompat.scala +++ b/munit/shared/src/main/scala-3/munit/internal/MacroCompat.scala @@ -6,8 +6,12 @@ import scala.quoted._ import scala.language.experimental.macros object MacroCompat { - private val workingDirectory: String = - sys.props("user.dir") + java.io.File.separator + private val workingDirectory: String = { + val sep = java.io.File.separator + val cwd = sys.props("user.dir") + if (cwd.endsWith(sep)) cwd + else cwd + sep + } trait LocationMacro { inline implicit def generate: Location = ${ locationImpl() } diff --git a/munit/shared/src/main/scala/munit/internal/console/Lines.scala b/munit/shared/src/main/scala/munit/internal/console/Lines.scala index fffc9913..62aab3b7 100644 --- a/munit/shared/src/main/scala/munit/internal/console/Lines.scala +++ b/munit/shared/src/main/scala/munit/internal/console/Lines.scala @@ -23,7 +23,10 @@ class Lines extends Serializable { val somePath1 = if (somePath.endsWith(sep)) somePath.dropRight(sep.length) else somePath - somePath1.split(sep).dropRight(1).mkString(sep) + val sep1 = + if (sep == "\\") "\\\\" + else sep + somePath1.split(sep1).dropRight(1).mkString(sep) } if (Files.exists(p)) p else if (max < 1) sys.error(s"$path was not found")