Skip to content

?LET macro throws 'proper_transformer' exception when including a markdown file with -moduledoc. #330

Description

@sthames42

This is my first experience with proper and Property Based Testing so this may be about my inexperience.

The Code

-module(my_module).
-moduledoc({file, "../doc/my_module.md"}).

...

%*------------------------------------------------*
%* `proper.hrl` must be included before functions *
%* because it contains `-import` attributes.      *
%*------------------------------------------------*
-ifdef(TEST).
-include_lib("proper/include/proper.hrl").
-include_lib("eunit/include/eunit.hrl").
-endif.

...

%*******************************************************************************
% Tests
%*******************************************************************************
-ifdef(TEST).

int_range_test() -> 
  ?assert(proper:quickcheck((fun() ->
  numtests(1000, 
    ?FORALL({From, To, Value}, ?LET(S, oneof([integer(), undefined]), {S, S, S}),
      begin
        Result   = ?TEST_VALIDATOR({int_range, {From, To}}, Value),
        Expected = 
          if 
            not is_integer(From)           -> {error, ?ERR_BAD_RANGE};
            not is_integer(To)             -> {error, ?ERR_BAD_RANGE};
            not is_integer(Value)          -> {error, ?ERR_NOT_IN_RANGE};
            Value < From orelse Value > To -> {error, ?ERR_NOT_IN_RANGE};
            true -> ok
          end,
        ?WHENFAIL(io:format(user, "int_range_test() failed~nFrom: ~p, To: ~p, Value: ~p~nExpected: ~p~nResult:   ~p~n~n", 
                            [From, To, Value, Expected, Result]), Result =:= Expected)
      end))
  end)(), [{on_output, fun(_,_) -> ok end}])).

-endif.

The Exception

> rebar3 eunit -m mymodule
===> Verifying dependencies...
===> Analyzing applications...
===> Compiling proper
===> Analyzing applications...
===> Compiling myapp
===> Compiling src/my_module.erl failed
src/my_module.erl:none: error in parse transform 'proper_transformer':
exception error: no case clause matching {epp_reply,<0.512.0>,{eof,{291,8}}}
  in function  proper_transformer:rewrite_type/2 (.../_build/default/lib/proper/src/proper_transformer.erl, line 364)
  in call from proper_transformer:rewrite_expr/2 (.../_build/default/lib/proper/src/proper_transformer.erl, line 277)
  in call from proper_transformer:'-rewrite_expr/2-lc$^4/1-1-'/2 (.../_build/default/lib/proper/src/proper_transformer.erl, line 288)
  in call from proper_transformer:'-rewrite_expr/2-lc$^4/1-1-'/2 (.../_build/default/lib/proper/src/proper_transformer.erl, line 288)
  in call from proper_transformer:rewrite_expr/2 (.../_build/default/lib/proper/src/proper_transformer.erl, line 288)
  in call from proper_transformer:'-rewrite_clause/2-lc$^1/1-1-'/2 (.../_build/default/lib/proper/src/proper_transformer.erl, line 234)
  in call from proper_transformer:rewrite_clause/2 (.../_build/default/lib/proper/src/proper_transformer.erl, line 234)
  in call from proper_transformer:'-rewrite_expr/2-lc$^17/1-10-'/2 (.../_build/default/lib/proper/src/proper_transformer.erl, line 335)

The Analysis

  1. Removing this line at the top of the file fixes the problem and tests are successful:

    -moduledoc({file, "../doc/my_module.md"}).

    It doesn't matter what is in the Markdown file. Even including an empty file results in the error.

  2. Replacing the -moduledoc() line with:

    -moduledoc """
      This is a great module!
    """.

    Also eliminates the error.

  3. The int_range_test() uses the ?LET macro to set the testing values:

    int_range_test() -> 
      ?assert(proper:quickcheck((fun() ->
      numtests(1000, 
        ?FORALL({From, To, Value}, ?LET(S, oneof([integer(), undefined]), {S, S, S}), ...

    Replacing the ?LET macro eliminates the exception:

    int_range_test() -> 
      Random = fun() -> oneof([integer(), undefined]) end,
      ?assert(proper:quickcheck((fun() ->
      numtests(1000, 
        ?FORALL({From, To, Value}, {Random(), Random(), Random()}, ...

    FWIW, I misunderstood how ?LET works and now realize {S, S, S} was giving all the same values for S. So this needed to be fixed, anyway.

Conclusion

It looks like there is a problem with compilation of the ?LET macro when an external file is included using -moduledoc().

I hope this helps with the diagnosis.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions