zachallaun / mneme

Snapshot testing for Elixir
https://hex.pm/packages/mneme
81 stars 5 forks source link

Feature: a flag to reset all auto_assert assertion to `:new` state #38

Closed mindreframer closed 1 year ago

mindreframer commented 1 year ago

I have noticed yesterday, that I had to delete the auto_assert generated values quite a lot, because I am using Maps / Structs. If I add a new key to a map, the assertion is not updated, because... well, it is still valid and passing! So, to get the new key in, I had to manually go through all the assertions and delete the asserted value and re-run the tests to get the updated map assertion. Also, when I was renaming fields in structs, the compilation for tests was failing, because the struct had still the old named key in the assertion.

If mneme had a flag to wipe out the assertions across the whole project, this would be great! :)

Example:

Mneme.start(reset: true)

Now mneme would reset all assertions (without asserting values) like this:

auto_assert(
  %State{
    columns: %{"users/email" => %Column{name: "email", order: 1}},
  } <- b
)

to

auto_assert(b)

Then one could flip the reset option back to false (or remove it), and mneme would generate new, updated assertions everywhere from scratch. For the interactive mode it would take some time, I mostly use Mneme with action: :accept, like this:

use Mneme, action: :accept, default_pattern: :last

@zachallaun What do you think about it? Is this a crazy idea? Would it make the code more complex? Is this even feasible implementation-wise?

zachallaun commented 1 year ago

Great suggestion! I’ve run into this as well.

I’d break this down into two features:

  1. An option to force patterns to update regardless of wherever the assertion is already passing. This solves the problem of adding fields to maps/structs.
  2. Some kind of task to reset all auto-assertions to a “new” state. This solves the problem of removed fields from a struct.

The challenge with the second is that, because the error occurs at compile-time, we need to use a different mechanism than normal to update things. The actual transformation is very simple -- we already have all the utilities to walk/transform an AST.

I'm inclined to add the first above, which I think has more immediate utility, and think/discuss a bit more on the second. It wouldn't be hard to add a mix mneme.reset that does the trick, but I'm not sure yet whether there isn't a better option.

@mindreframer Thoughts?

zachallaun commented 1 year ago

@mindreframer If you have a moment, would you be willing to try out the force-update branch?

# deps
{:mneme, github: "zachallaun/mneme", ref: "force-update"}

# in a test module you're working on
defmodule MyTest do
  use ExUnit.Case
  use Mneme, action: :accept, default_pattern: :last, force_update: true

  ...
end
mindreframer commented 1 year ago

@mindreframer Yeah!!! It works! I've tried it and adding new keys to maps makes them appear in assertions! I could cry from joy 😍

I also agree in splitting this issue into 2 features, since they have different implications. A mix task to reset all assertions without compilation looks like a nice alternative. Since the need to reset values does not come up very often, having this code in a Mix task provides a good semantic separation.

THANKS! Mneme has become an indispensable tool in my toolbox! I use it on every private project and love it!

Have a great Sunday and happy Easter!

zachallaun commented 1 year ago

Thank you! I really appreciate all of your feedback and advice. Having folks other than myself invested in using this project makes a huge difference :)

I’m going to merge this (and some other stuff) into main and cut a new RC later today, I think.

Happy Easter!

mindreframer commented 1 year ago

Nice, looking forward to it!

zachallaun commented 1 year ago

@mindreframer After introducing force_update: true, are you still missing a reset-to-new feature? I'm not personally finding a desire for it and was thinking of closing out this issue, but I'm open to being convinced otherwise! 🙂

mindreframer commented 1 year ago

@zachallaun hey, no objections from my side! Feel free to close and thanks for asking!

Have a great rest Sunday!

zachallaun commented 1 year ago

Sounds good! Please reopen if you find more of a need in the future!