PageRenderTime 34ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/src/mochiweb_cover.erl

http://github.com/basho/mochiweb
Erlang | 93 lines | 56 code | 12 blank | 25 comment | 2 complexity | b644d567d0890c60f4ad4d8c4a2cc53a MD5 | raw file
Possible License(s): MIT
  1. %% @author Bob Ippolito <bob@mochimedia.com>
  2. %% @copyright 2010 Mochi Media, Inc.
  3. %%
  4. %% Permission is hereby granted, free of charge, to any person obtaining a
  5. %% copy of this software and associated documentation files (the "Software"),
  6. %% to deal in the Software without restriction, including without limitation
  7. %% the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. %% and/or sell copies of the Software, and to permit persons to whom the
  9. %% Software is furnished to do so, subject to the following conditions:
  10. %%
  11. %% The above copyright notice and this permission notice shall be included in
  12. %% all copies or substantial portions of the Software.
  13. %%
  14. %% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. %% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. %% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17. %% THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. %% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. %% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  20. %% DEALINGS IN THE SOFTWARE.
  21. %% @doc Workarounds for various cover deficiencies.
  22. -module(mochiweb_cover).
  23. -export([get_beam/1, get_abstract_code/1,
  24. get_clauses/2, clause_lookup_table/1]).
  25. -export([clause_lookup_table/2]).
  26. %% Internal
  27. get_beam(Module) ->
  28. {Module, Beam, _Path} = code:get_object_code(Module),
  29. Beam.
  30. get_abstract_code(Beam) ->
  31. {ok, {_Module,
  32. [{abstract_code,
  33. {raw_abstract_v1, L}}]}} = beam_lib:chunks(Beam, [abstract_code]),
  34. L.
  35. get_clauses(Function, Code) ->
  36. [L] = [Clauses || {function, _, FName, _, Clauses}
  37. <- Code, FName =:= Function],
  38. L.
  39. clause_lookup_table(Module, Function) ->
  40. clause_lookup_table(
  41. get_clauses(Function,
  42. get_abstract_code(get_beam(Module)))).
  43. clause_lookup_table(Clauses) ->
  44. lists:foldr(fun clause_fold/2, [], Clauses).
  45. clause_fold({clause, _,
  46. [InTerm],
  47. _Guards=[],
  48. [OutTerm]},
  49. Acc) ->
  50. try [{erl_parse:normalise(InTerm), erl_parse:normalise(OutTerm)} | Acc]
  51. catch error:_ -> Acc
  52. end;
  53. clause_fold(_, Acc) ->
  54. Acc.
  55. %%
  56. %% Tests
  57. %%
  58. -ifdef(TEST).
  59. -include_lib("eunit/include/eunit.hrl").
  60. foo_table(a) -> b;
  61. foo_table("a") -> <<"b">>;
  62. foo_table(123) -> {4, 3, 2};
  63. foo_table([list]) -> [];
  64. foo_table([list1, list2]) -> [list1, list2, list3];
  65. foo_table(ignored) -> some, code, ignored;
  66. foo_table(Var) -> Var.
  67. foo_table_test() ->
  68. T = clause_lookup_table(?MODULE, foo_table),
  69. [?assertEqual(V, foo_table(K)) || {K, V} <- T].
  70. clause_lookup_table_test() ->
  71. ?assertEqual(b, foo_table(a)),
  72. ?assertEqual(ignored, foo_table(ignored)),
  73. ?assertEqual('Var', foo_table('Var')),
  74. ?assertEqual(
  75. [{a, b},
  76. {"a", <<"b">>},
  77. {123, {4, 3, 2}},
  78. {[list], []},
  79. {[list1, list2], [list1, list2, list3]}],
  80. clause_lookup_table(?MODULE, foo_table)).
  81. -endif.