Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
collections of tools for building erlang applications
branch: master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.


This application really doesn't do anything except server as a repo for commonly used functions that I use for:

  • eunit testing
  • logging, but not really anymore
  • makeing fprof easier to use
  • testing the speed of a function a repeated number of times

Eunit Testing structure

The eunit structure building macros that I have built allow to build eunit tests very consisely. For example this is what an eunit test might look like normally:

    "this is a description",
    fun() ->
        meck:expect(fake_mod,do_stuff,fun(Param)-> {ok,Param} end),

        Result = fake_mod:do_stuff(testing),



and this is the same eunit test built with my macro

Tests = [
    {"this is a description"
        [{dostuff,fun(Param) -> {ok,Param} end}]}],



Its a little more consise, but a ton more consise when dealing with mecking the same module over and over again. Mostly because it can be abstracted away inside of a ?Macro.

The general structure of the tuple list is as follows:

### Standard
Tests() :: [Test() | Test()].
Test()  :: {Call :: Call(), Mecks :: Mecks(), Check :: Check()}

Check() :: Fun :: fun() -> (true | false)
        |  Any :: any()

Call()  :: { Mod :: atom(), Fun :: atom(), Args :: [ Arg :: any() | Arg :: any()]}
        |  Function :: fun() -> any()
        |  {fun(Arg :: any(),Arg :: any()), [Arg :: any() | Arg :: any()]}
Mecks() :: [Meck :: Meck() | Meck :: Meck()]
Meck()  :: {Mod :: atom(), Meck_list :: [Meck_fun :: Meck_funs() | Meck_fun :: Meck_funs() ]}
        |  {Mod :: atom(), Opts :: [any() | any()], [Meck_fun :: Meck_funs() | Meck_fun :: Meck_funs() ]}
Meck_funs() :: {Fun :: atom(), Fun_list :: [Fun :: Meck_fun() | Fun :: Meck_fun()]}
Meck_fun()  :: {Name :: atom(), Fun :: fun(Elem :: any()) -> any()}

### Extended
            |  {Name :: atom(), Patterns :: {all, Arity :: Integer(), Behaviors :: [Behavior :: Behavior() | Behavior :: Behavior()]}}
            |  {Name :: atom(), Matches :: [Match :: Match() | Match :: Match()]}
Match() :: {Args :: [Arg :: any() | Arg :: any()], Behaviors :: [Behavior :: Behavior() | Behavior :: Behavior()]}
Behavior()  :: {push,Key :: atom(), Value :: any()}
            |  {pop,Key :: atom()}
            |  {ret,Value :: any()}

Lots of options there, for the most part I would stick with using the standard mecking behavior, as the extened really has only been used a few time. mostly when testing out functions that need to return differently even though the same parameters are passed. (i.e fun gen_tcp:recv/2)

Also this is how I would reccomend that the test be structured so that you don't end up with a large block of brackets at the end of the structure that may or may not be correct.

        "Transfer Encoding Chunked identifies the end of the transfer if received from the server"
        ,{baker_http_proxy,proxy,[Server,Client,chunked,<<"0\r\n\r\n">>,unknown]} # always on one line
        ,[{fake_trans, # always on one line
            [{setopts,fun(_,_)-> ok end} # can be on one line if fun only has 1 caluse and is simple
            ,{send,fun ## needs to be split across multiple lines and indented twice becuase of multiple clauses
                    (client,<<"0\r\n">>)-> ok;
                    (client,<<"\r\n">>)-> ok end}]}]
        ,{extra,<<>>}} # one line unless its a fun, if its a fun the same rules apply as the funs in the meck area.

so in recap:

  • Funs
    • can be one one line if the are small and have one clause `fun() -> ok end
    • need to be split across multiple lines if larger or have multiple clauses
        (a) -> ok;
        (_) -> bad end


        case A of
        a -> ok;
        _ -> end
    end end

- funs also should try to keep the last `end` on the same line as the list line of code so:
    - *this is only for the structure of these tests*
    fun() -> ok end

        case true of
        end end

    fun() -> ok
  • Lists
    • should e structured so that all elements in the list are at the same indentation
      • unless
        • there is a sublist with multiple elements, then the sublist is indented
        • or the list is small and does not have a lot of elements



    List =  [{a,true}
Something went wrong with that request. Please try again.