Skip to content

Commit 92c5a94

Browse files
authored
Fix expecty macro (com-lihaoyi#307)
trying to fix com-lihaoyi#305 It seems that AST that our macro produces is spliced into AST of the expression provided to Expecty.expect Then it tries to evaluate this composed AST, but it fails, I'm not exactly sure why, maybe some local vals in macro arent simply available in the scope where expecty evaluates them. I think Expecty.expect should expand only AST of expression provided to it (and do not follow macros and splice ASTs generated by them) This PR rewrites macro a little bit not to use values calculated in macro itself (it also removes potentially problematic Expr.apply call). As a consequence we have to make a segmentsFromString public, because call to it is also inlined. This change fixes compilation of expecty macros, but due to the fact that expecty expands AST too much, its assertion clues will be malformed anyway, but I don't think we would be able to solve this in os-lib. Note: Using scala 2 there is no bug.
1 parent 0ba9dfb commit 92c5a94

File tree

5 files changed

+41
-7
lines changed

5 files changed

+41
-7
lines changed

build.sc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ object Deps {
2424
val geny = ivy"com.lihaoyi::geny::1.1.1"
2525
val sourcecode = ivy"com.lihaoyi::sourcecode::0.4.2"
2626
val utest = ivy"com.lihaoyi::utest::0.8.4"
27+
val expecty = ivy"com.eed3si9n.expecty::expecty::0.16.0"
2728
def scalaReflect(scalaVersion: String) = ivy"org.scala-lang:scala-reflect:$scalaVersion"
2829
def scalaLibrary(version: String) = ivy"org.scala-lang:scala-library:${version}"
2930
}
@@ -164,6 +165,7 @@ object os extends Module {
164165
object jvm extends Cross[OsJvmModule](scalaVersions)
165166
trait OsJvmModule extends OsModule with MiMaChecks {
166167
object test extends ScalaTests with OsLibTestModule {
168+
override def ivyDeps = T{super.ivyDeps() ++ Agg(Deps.expecty)}
167169

168170
// we check the textual output of system commands and expect it in english
169171
def forkEnv = super.forkEnv() ++ Map(

os/src-3/Macros.scala

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package os
22

3-
import os.PathChunk.{RelPathChunk, StringPathChunk, segmentsFromStringLiteralValidation}
3+
import os.PathChunk.{RelPathChunk, StringPathChunk, segmentsFromString, segmentsFromStringLiteralValidation}
44
import os.RelPath.fromStringSegments
55

66
import scala.quoted.{Expr, Quotes}
@@ -20,11 +20,9 @@ object Macros {
2020

2121
s.asTerm match {
2222
case Inlined(_, _, Literal(StringConstant(literal))) =>
23-
val stringSegments = segmentsFromStringLiteralValidation(literal)
23+
segmentsFromStringLiteralValidation(literal)
2424
'{
25-
new RelPathChunk(fromStringSegments(${
26-
Expr(stringSegments)
27-
}))
25+
new RelPathChunk(fromStringSegments(segmentsFromString($s)))
2826
}
2927
case _ =>
3028
'{

os/src/Path.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ trait StringPathChunkConversion {
2020
}
2121

2222
object PathChunk extends PathChunkMacros {
23-
private[os] def segmentsFromString(s: String): Array[String] = {
23+
def segmentsFromString(s: String): Array[String] = {
2424
val trailingSeparatorsCount = s.reverseIterator.takeWhile(_ == '/').length
2525
val strNoTrailingSeps = s.dropRight(trailingSeparatorsCount)
2626
val splitted = strNoTrailingSeps.split('/')
2727
splitted ++ Array.fill(trailingSeparatorsCount)("")
2828
}
2929

30-
private[os] def segmentsFromStringLiteralValidation(literal: String) = {
30+
private[os] def segmentsFromStringLiteralValidation(literal: String): Array[String] = {
3131
val stringSegments = segmentsFromString(literal)
3232
val validSegmnts = validLiteralSegments(stringSegments)
3333
val sanitizedLiteral = validSegmnts.mkString("/")
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package test.os
2+
3+
import os._
4+
import utest._
5+
import com.eed3si9n.expecty.Expecty.expect
6+
7+
object ExpectyIntegration extends TestSuite {
8+
val tests = Tests {
9+
test("Literals") {
10+
test("Basic") {
11+
expect(rel / "src" / "Main/.scala" == rel / "src" / "Main" / ".scala")
12+
expect(root / "core/src/test" == root / "core" / "src" / "test")
13+
expect(root / "core/src/test" == root / "core" / "src/test")
14+
}
15+
test("literals with [..]") {
16+
expect(rel / "src" / ".." == rel / "src" / os.up)
17+
expect(root / "src/.." == root / "src" / os.up)
18+
expect(root / "src" / ".." == root / "src" / os.up)
19+
expect(root / "hello" / ".." / "world" == root / "hello" / os.up / "world")
20+
expect(root / "hello" / "../world" == root / "hello" / os.up / "world")
21+
expect(root / "hello/../world" == root / "hello" / os.up / "world")
22+
}
23+
test("from issue") {
24+
expect(Seq(os.pwd / "foo") == Seq(os.pwd / "foo"))
25+
val path = os.Path("/") / "tmp" / "foo"
26+
expect(path.startsWith(os.Path("/") / "tmp"))
27+
}
28+
test("multiple args") {
29+
expect(rel / "src" / ".." == rel / "src" / os.up, root / "src/.." == root / "src" / os.up)
30+
}
31+
}
32+
}
33+
}

os/test/src/PathTests.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ object PathTests extends TestSuite {
2121
assert(root / "core/src/test" == root / "core" / "src/test")
2222
}
2323
test("literals with [..]") {
24+
2425
assert(rel / "src" / ".." == rel / "src" / os.up)
2526
assert(root / "src/.." == root / "src" / os.up)
2627
assert(root / "src" / ".." == root / "src" / os.up)

0 commit comments

Comments
 (0)