Hacker News new | ask | show | jobs
by 147 3781 days ago
Was it not possible to simply write a function to achieve the same result?
2 comments

I don't think so, I believe the function calls need to be there at compile time so that the test actually gets run.

But I'll give it a try tonight though :)

I don't think you can get the exact same syntax without using a macro. But couldn't you have just your entire assertion in a function and pass in the conn, method, route name, and expected json status?

Then you just wrap that in your test "..." form.

I don't see much gains from writing a macro, I see more drawbacks.

Pros of just using function and wrapping it in test form:

* It's just a function, easier maintenance. If you write a macro, you have to debug not only the macro but the code your macro writes.

* You gain more clarity into what each test is testing when there are failures. You hard code the "requires authentication" part as your test string. To write a macro that is flexible enough to also allow the user to specify the string here would end up defeating all purpose of it.

* You unquote the three arguments you pass in to the macro immediately. That's a red flag to me that this shouldn't need to be a macro. It's just to avoid the test boilerplate.

Cons:

* It's syntactically longer

I'm coming from a Clojure perspective, I've dabbled briefly with Elixir so let me know if I'm wrong. I wanted to get into Elixir more but the community's pervasive use of macros is keeping me from embracing it. They say Elixir is less magical and more explicit than Ruby and while that's not an untrue statement, I'm seeing too much metaprogramming already with macros. I'm not saying all macros are bad, it's just the vast majority of them are unneeded.

If you look at the code, that's actually what the author has done.

They've made a `make_unauthenticated_request` function that does the work, and the macro just calls it.

But, I agree, I'd probably have skipped the macro. And DRYed it up with just the function.

Right. That's exactly what I'm trying to point out. The point of the macro is to get the test form stuff.
ExUnit.Case.test/3 is itself a macro.