How to unit test a Scala 3 macro?

Viewed 100

I am trying to unit test the following, simplified, macro (by comparing the emitted expressions):

trait MyOutput {
  def speak(): Unit
}

inline def myMacro(): MyOutput = ${ myMacroImpl() }

def myMacroImpl()(using Quotes): Expr[MyOutput] = {
  '{
    new MyOutput {
      def speak(): Unit = {
        println("Hello World")
      }
    }
  }
}

I tried the following

inline private def testMacro[A](inline generated: A, expected: A): A = {
  ${ testMacroExpr('generated, 'expected) }
}

def testMacroExpr[A](generated: Expr[A], expected: Expr[A])(using Quotes): Expr[A] = {
  import quotes.reflect._

  if (generated != expected) {
    report.throwError("BOOM")
  }
}

// main.scala
@main def hello() = {
  testMacro(
    myMacro(),
    new MyOutput {
      def speak(): Unit = {
        println("Hello World")
      }
    }
  )
}

But the comparison always returns false. Also, I remarked expected.asTerm.toString() returns Inlined(EmptyTree,List(),Ident(expected$proxy1)).

I also tried:

  • using functions defined on Expr and Quotes, such as matches
  • comparing generated.show and expected.asTerm.underlying.show

Can someone point me to solution please?

0 Answers
Related