@@ -20,16 +20,14 @@ defmodule Mix.Tasks.Test do
20
20
Mix . shell ( ) . info ( "\n Generating cover results ...\n " )
21
21
{ :result , ok , _fail } = :cover . analyse ( :coverage , :line )
22
22
23
- results =
24
- ok
25
- |> gather_coverage ( :cover . modules ( ) )
26
- |> Enum . sort_by ( & percentage ( elem ( & 1 , 1 ) ) , & >= / 2 )
23
+ { module_results , totals } = gather_coverage ( ok , :cover . modules ( ) )
24
+ module_results = Enum . sort_by ( module_results , & percentage ( elem ( & 1 , 1 ) ) , & >= / 2 )
27
25
28
26
if summary_opts = Keyword . get ( opts , :summary , true ) do
29
- console ( results , summary_opts )
27
+ console ( module_results , totals , summary_opts )
30
28
end
31
29
32
- html ( results , opts )
30
+ html ( module_results , opts )
33
31
end
34
32
end
35
33
@@ -40,50 +38,44 @@ defmodule Mix.Tasks.Test do
40
38
# We may also have multiple entries on the same line.
41
39
# Each line is only considered once.
42
40
#
43
- # We use the process dictionary for performance, to avoid
44
- # working with nested maps, but we clean it up afterwards.
45
- modules =
46
- Enum . reduce ( results , MapSet . new ( ) , fn
47
- { { module , 0 } , _ } , acc ->
48
- MapSet . put ( acc , module )
49
-
50
- { { module , line } , { 1 , 0 } } , acc ->
51
- coverage = Process . get ( module ) || % { }
52
- Process . put ( module , Map . put ( coverage , line , true ) )
53
- MapSet . put ( acc , module )
54
-
55
- { { module , line } , { 0 , 1 } } , acc ->
56
- coverage = Process . get ( module ) || % { }
57
- Process . put ( module , Map . put_new ( coverage , line , false ) )
58
- MapSet . put ( acc , module )
41
+ # We use ets for performance, to avoid working with nested maps
42
+ table = :ets . new ( __MODULE__ , [ :set , :private ] )
43
+
44
+ try do
45
+ Enum . each ( results , fn
46
+ { { module , 0 } , _ } -> :ets . insert ( table , { { module , 0 } , :dummy } )
47
+ { { module , line } , { 1 , 0 } } -> :ets . insert ( table , { { module , line } , true } )
48
+ { { module , line } , { 0 , 1 } } -> :ets . insert_new ( table , { { module , line } , false } )
59
49
end )
60
50
61
- for module <- modules , results = Process . delete ( module ) || % { } , module in keep do
62
- result =
63
- Enum . reduce ( results , { 0 , 0 } , fn
64
- { _line , true } , { covered , not_covered } -> { covered + 1 , not_covered }
65
- { _line , false } , { covered , not_covered } -> { covered , not_covered + 1 }
66
- end )
51
+ module_results =
52
+ for module <- keep ,
53
+ results = read_module_cover_results ( table , module ) ,
54
+ do: { module , results }
67
55
68
- { module , result }
56
+ total_covered = :ets . select_count ( table , [ { { :_ , true } , [ ] , [ true ] } ] )
57
+ total_not_covered = :ets . select_count ( table , [ { { :_ , false } , [ ] , [ true ] } ] )
58
+
59
+ { module_results , { total_covered , total_not_covered } }
60
+ after
61
+ :ets . delete ( table )
69
62
end
70
63
end
71
64
72
- defp console ( results , true ) , do: console ( results , [ ] )
65
+ defp read_module_cover_results ( table , module ) do
66
+ covered = :ets . select_count ( table , [ { { { module , :_ } , true } , [ ] , [ true ] } ] )
67
+ not_covered = :ets . select_count ( table , [ { { { module , :_ } , false } , [ ] , [ true ] } ] )
68
+ { covered , not_covered }
69
+ end
70
+
71
+ defp console ( results , totals , true ) , do: console ( results , totals , [ ] )
73
72
74
- defp console ( results , opts ) when is_list ( opts ) do
73
+ defp console ( results , totals , opts ) when is_list ( opts ) do
75
74
Mix . shell ( ) . info ( "Percentage | Module" )
76
75
Mix . shell ( ) . info ( "-----------|--------------------------" )
77
76
Enum . each ( results , & display ( & 1 , opts ) )
78
77
Mix . shell ( ) . info ( "-----------|--------------------------" )
79
-
80
- total =
81
- Enum . reduce ( results , { 0 , 0 } , fn { _ , { covered , not_covered } } ,
82
- { total_covered , total_not_covered } ->
83
- { total_covered + covered , total_not_covered + not_covered }
84
- end )
85
-
86
- display ( { "Total" , total } , opts )
78
+ display ( { "Total" , totals } , opts )
87
79
Mix . shell ( ) . info ( "" )
88
80
end
89
81
@@ -121,14 +113,10 @@ defmodule Mix.Tasks.Test do
121
113
] )
122
114
end
123
115
124
- defp percentage ( { 0 , 0 } ) , do: 100
116
+ defp percentage ( { 0 , 0 } ) , do: 100.0
125
117
defp percentage ( { covered , not_covered } ) , do: covered / ( covered + not_covered ) * 100
126
118
127
- defp format ( number , length ) when is_integer ( number ) ,
128
- do: :io_lib . format ( "~#{ length } b" , [ number ] )
129
-
130
- defp format ( number , length ) when is_float ( number ) ,
131
- do: :io_lib . format ( "~#{ length } .2f" , [ number ] )
119
+ defp format ( number , length ) , do: :io_lib . format ( "~#{ length } .2f" , [ number ] )
132
120
133
121
defp format_name ( name ) when is_binary ( name ) , do: name
134
122
defp format_name ( mod ) when is_atom ( mod ) , do: inspect ( mod )
0 commit comments