#Apply testing macro inside a loop?

5 messages · Page 1 of 1 (latest)

ashen wyvern
#

Hey, for the Advent of Code challenge I'm using Elixir to improve my skills with the language. Since the testing part is rather repetetive I implemented a macro that creates a simple test function. In todays puzzle there have been multiple test examples for the first time.

I tried several ways to call the macro in a way to define these different test cases in a simple matter but wasn't able to. I would like to do something like this:

defmodule Day06Test do
  use ExUnit.Case
  import TestHelpers

  @test [{"mjqjpqmgbljsphdztnvjfqwrcgsmlb", 7, 19}, ...]

  for {text, a, b} <- @test do
    describe "#{text}" do
      aoc_test(a, Puzzles.Day06.part_one(text))
      aoc_test(b, Puzzles.Day06.part_two(text))
    end
  end

This actually calls the macro the expected amount of times but after all macro calls are through it fails with:

== Compilation error in file test/day06_test.exs ==
** (CompileError) test/day06_test.exs:15: undefined function a/0 (expected Day06Test to define such a function or for it to be imported, but none are available)

Is there a way to accomplish this?

Here is the TestHelper: https://github.com/MLNW/advent_of_code/blob/extend-macro/2022/test/test_helper.exs
and here is the test: https://github.com/MLNW/advent_of_code/blob/extend-macro/2022/test/day06_test.exs#L5-L18

GitHub

This repository contains my solutions to the Advent of Code. - advent_of_code/test_helper.exs at extend-macro · MLNW/advent_of_code

GitHub

This repository contains my solutions to the Advent of Code. - advent_of_code/day06_test.exs at extend-macro · MLNW/advent_of_code

short lotus
#

You need to unquote values of a and b as these are in quoted` context and aren't busików there as values

ashen wyvern
#

Isn't that what I already do with unquote(expected)?

short lotus
#

But you do that inside macro. So your code will end up looking like that:

 describe "#{text}" do
  # aoc_test(a, Puzzles.Day06.part_one(text))
  test "test name 1", do: assert(a == Puzzles.Day06.part_one(text))
  # …

It will then try to call function a in that context, and as there is no such function - it will fail. You need to either evaluate your a in your macro or make macro spit out:

 describe "#{text}" do
  # aoc_test(a, Puzzles.Day06.part_one(text))
  test "test name 1", do: assert(unquote(a) == Puzzles.Day06.part_one(text))
  # …
ashen wyvern
#

Ah okay. That makes sense. Since I'm already unquoting a once for the normal case but I would have to unquote it twice for this new case, how would I know when to do it once and when to do it twice?