Doctest - a library to test Erlang doc attributes

AFAIK, this is not possible. You should return the expanded record tuple as the result. Record expressions are translated to tuple expressions during compilation.

Please try it in the v0.12.0 release.

Changes

Breaking changes

The -doctest attribute is now deprecated and the doctest.hrl was removed.

This is no longer valid:

-ifdef(TEST).
% The doctest header sets `doctest_transform` as a parse_transform:
-include_lib("doctest/include/doctest.hrl").
-doctest #{
    % Options
}.
-endif.

Instead, do this:

-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").
% The EUnit header will automatically export this function because it ends with "_test"
doctest_test() ->
    doctest:module(?MODULE, #{
        % Options
    }).
-endif.

How does the shell do it? The thread linked below suggests some options but they all seem hacky… I have to imagine the shell has a better solution.

1 Like

The shell cheats by reading the abstract code of the module and then when printing tuples, it checks if the tuple could possibly be a record and if so prints it as such. I’ve long though that we should expose an API for user code to do the same, but have not yet gotten around to it so right now it is very internal to the shell and cannot be used for any other purpose.

2 Likes

Thanks for the background! Makes sense that it’s difficult to do in user code. Happy to use tuple syntax for now :grin:

Thank you for refreshing my mind!
I’ll implement it! o/

1 Like

New release

v0.13.0

Changes

  • Introduce records option by @williamthome in #71
    Example:

    -module(foo).
    -export([foo/1]).
    -record(foo, {foo = foo}).
    
    -ifdef(TEST).
    -include_lib("eunit/include/eunit.hrl").
    
    doctest_test() ->
        doctest:module(?MODULE, #{
            records => [{foo, record_info(fields, foo)}]
        }).
    -endif.
    
    -doc """
    ```
    > Foo0 = #foo{}.
    > Foo = Foo0#foo{foo = bar}.
    > foo:foo(Foo).
    #foo{foo = bar}
    ```
    """.
    foo(#foo{} = Foo) ->
        Foo.
    
1 Like

Currently, running this on OTP 25 with -feature(maybe_expr,enable) raises an error when edoc tries to generate the doc chunks:

at line 3: bad attribute

I encountered this using ./rebar3 edoc on this codebase as well, but rebar3_ex_doc seems to handle it OK. I’m not sure what that library is doing differently to parse the -feature macro OK… is it an edoc option I need to pass?

Indeed, it is failing, but without any error output. Locally, in OTP-25, I’m receiving this error: {features_not_allowed, [maybe_expr,maybe_expr]}.

Unfortunately, I’ll be busy for the next few days to look into this =/
Please keep me updated if you find any possible solution.

1 Like

Hi! Did you find a solution?

Fixed in v0.13.1.

Please note that you must enable the maybe expr also via ERL_FLAGS to make it work in OTP-25, e.g.:

ERL_FLAGS="-enable-feature maybe_expr" rebar3 eunit

Without it, it will fail.
It is not required to enable it via ERL_FLAGS for OTP >= 26.

See How to enable maybe_expr?

1 Like