Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add __decorated_functions__ function to modules using the decorator #54

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

leggebroten
Copy link

Adds "hidden" __decorated_functions__ function to modules that use the @decorate function.

The new function allows unit tests to assert the decoration was properly called, thereby avoiding the need to assert that the behavior invoked by the @decorate call was done, and not have to assert the decorated functionality

leggebroten and others added 4 commits July 24, 2023 08:57
…t of all decorated functions

### Simple reflection for all decorated functions
A "hidden" function `__decorated_functions__/0` is added to any module that decorates functions and returns a list of
all decorated functions within that module.

This can be useful for testing purposes since you don't have to assert the decorated behaviors of the decorated
functions.  So long as your decorator function is well tested, you can just assert the expected decorators are present
for the given function.

The function returns a map with the function name and arguments as the key and a list of tuples with the decorator.
This permits multiple decorators to be asserted with a single function call so that adding new decorators will cause
the assertion to fail.

For example, given the following module:
```elixir
  defmodule NewModule do
    use Decorator.Define, [new_decorator: 1, another_decorator: 2]

    @decorate new_decorator("one")
    def func(%StructOne{} = msg) do
      msg
    end

    @decorate new_decorator("two")
    @decorate another_decorator("a", "b")
    @decorate new_decorator("b")
    def func(%StructTwo{c: 2} = _msg) do
      :ok
    end
  end
```

You can assert the decorated functions like so:
```elixir
  test "Module with decorated functions are returned by `__decorated_functions__()" do
    assert %{
             {:func, ["%StructOne{} = msg"]} => [
               {DecoratorTest.Fixture.NewDecorator, :new_decorator, ["one"]}
             ],
             {:func, ["%StructTwo{c: 2} = _msg"]} => [
               {DecoratorTest.Fixture.NewDecorator, :new_decorator, ["two"]},
               {DecoratorTest.Fixture.AnotherDecorator, :another_decorator, ["a", "b"]},
               {DecoratorTest.Fixture.NewDecorator, :new_decorator, ["b"]}
             ]
           } == NewModule.__decorated_functions__()
  end
```

Obviously, any changes to the parameters of the decorated function will cause the simple assertion to fail, but that's
intentional, as the decorator may be dependent on the parameters of the decorated function.
Added a "reflection" function `__decorated_functions__` to return lis…
Added __decorated_functions__ function to the created macro so that unit tests could assert the proper decoration had been done and not have to assert the decorated functionality
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant