@@ -57,9 +57,10 @@ defmodule ExUnit.Server do
5757    state  =  % { 
5858      loaded:  System . monotonic_time ( ) , 
5959      waiting:  nil , 
60-       async_groups:  % { } , 
60+       groups:  % { } , 
61+       async_groups:  [ ] , 
6162      async_modules:  :queue . new ( ) , 
62-       sync_modules:  :queue . new ( ) 
63+       sync_modules:  [ ] 
6364    } 
6465
6566    { :ok ,  state } 
@@ -72,31 +73,31 @@ defmodule ExUnit.Server do
7273
7374  # Called once after all async modules have been sent and reverts the state. 
7475  def  handle_call ( :take_sync_modules ,  _from ,  state )  do 
75-     % { waiting:  nil ,  loaded:  :done ,  async_modules:  async_modules }  =  state 
76-     0  =  :queue . len ( async_modules ) 
76+     % { waiting:  nil ,  loaded:  :done ,  async_groups:  [ ] }  =  state 
77+     true  =  :queue . is_empty ( state . async_modules ) 
7778
78-     { :reply ,  :queue . to_list ( state . sync_modules ) , 
79-      % { state  |  sync_modules:  :queue . new ( ) ,  loaded:  System . monotonic_time ( ) } } 
79+     { :reply ,  state . sync_modules ,  % { state  |  sync_modules:  [ ] ,  loaded:  System . monotonic_time ( ) } } 
8080  end 
8181
8282  # Called by the runner when --repeat-until-failure is used. 
8383  def  handle_call ( { :restore_modules ,  async_modules ,  sync_modules } ,  _from ,  state )  do 
84-     { async_modules ,  async_groups }  = 
85-       Enum . map_reduce ( async_modules ,  % { } ,  fn 
86-         { nil ,  [ module ] } ,  { modules ,  groups }  -> 
87-           { [ { : module,   module }   |   modules ] ,  groups } 
84+     { async_modules ,  async_groups ,   groups }  = 
85+       Enum . reduce ( async_modules ,  { [ ] ,   [ ] ,   [ ] } ,  fn 
86+         { nil ,  [ module ] } ,  { async_modules ,   async_groups ,  groups }  -> 
87+           { [ module   |   async_modules ] ,   async_groups ,  groups } 
8888
89-         { group ,  group_modules } ,  { modules ,  groups }  -> 
90-           { [ { :group ,   group }  |  modules ] ,  Map . put ( groups ,   group ,  group_modules ) } 
89+         { group ,  group_modules } ,  { async_modules ,   async_groups ,  groups }  -> 
90+           { async_modules ,   [ group  |  async_groups ] ,  [ { group ,  group_modules }   |   groups ] } 
9191      end ) 
9292
9393    { :reply ,  :ok , 
9494     % { 
9595       state 
9696       |  loaded:  :done , 
97+          groups:  Map . new ( groups ) , 
9798         async_groups:  async_groups , 
9899         async_modules:  :queue . from_list ( async_modules ) , 
99-          sync_modules:  :queue . from_list ( sync_modules ) 
100+          sync_modules:  sync_modules 
100101     } } 
101102  end 
102103
@@ -108,22 +109,24 @@ defmodule ExUnit.Server do
108109      when  is_integer ( loaded )  do 
109110    state  = 
110111      if  uniq?  do 
111-         async_groups  = 
112-           Map . new ( state . async_groups ,  fn  { group ,  modules }  -> 
113-             { group ,  Enum . uniq ( modules ) } 
114-           end ) 
115- 
112+         groups  =  Map . new ( state . groups ,  fn  { group ,  modules }  ->  { group ,  Enum . uniq ( modules ) }  end ) 
113+         async_groups  =  state . async_groups  |>  Enum . uniq ( )  |>  Enum . reverse ( ) 
116114        async_modules  =  :queue . to_list ( state . async_modules )  |>  Enum . uniq ( )  |>  :queue . from_list ( ) 
117-         sync_modules  =  :queue . to_list ( state . sync_modules )  |>  Enum . uniq ( )  |>  :queue . from_list ( ) 
115+         sync_modules  =  state . sync_modules  |>  Enum . uniq ( )  |>  Enum . reverse ( ) 
118116
119117        % { 
120118          state 
121-           |  async_groups:  async_groups , 
119+           |  groups:  groups , 
120+             async_groups:  async_groups , 
122121            async_modules:  async_modules , 
123122            sync_modules:  sync_modules 
124123        } 
125124      else 
126-         state 
125+         % { 
126+           state 
127+           |  async_groups:  Enum . reverse ( state . async_groups ) , 
128+             sync_modules:  Enum . reverse ( state . sync_modules ) 
129+         } 
127130      end 
128131
129132    diff  =  System . convert_time_unit ( System . monotonic_time ( )  -  loaded ,  :native ,  :microsecond ) 
@@ -132,9 +135,7 @@ defmodule ExUnit.Server do
132135
133136  def  handle_call ( { :add ,  false  =  _async ,  _group ,  names } ,  _from ,  % { loaded:  loaded }  =  state ) 
134137      when  is_integer ( loaded )  do 
135-     state  = 
136-       update_in ( state . sync_modules ,  & Enum . reduce ( names ,  & 1 ,  fn  name ,  q  ->  :queue . in ( name ,  q )  end ) ) 
137- 
138+     state  =  update_in ( state . sync_modules ,  & Enum . reverse ( names ,  & 1 ) ) 
138139    { :reply ,  :ok ,  state } 
139140  end 
140141
@@ -143,25 +144,24 @@ defmodule ExUnit.Server do
143144    state  = 
144145      update_in ( 
145146        state . async_modules , 
146-         & Enum . reduce ( names ,  & 1 ,  fn  name ,  q  ->  :queue . in ( { :module ,   name } ,  q )  end ) 
147+         & Enum . reduce ( names ,  & 1 ,  fn  name ,  q  ->  :queue . in ( name ,  q )  end ) 
147148      ) 
148149
149150    { :reply ,  :ok ,  take_modules ( state ) } 
150151  end 
151152
152153  def  handle_call ( { :add ,  true  =  _async ,  group ,  names } ,  _from ,  % { loaded:  loaded }  =  state ) 
153154      when  is_integer ( loaded )  do 
154-     { async_groups ,   async_modules }  = 
155-       case  state . async_groups  do 
156-         % { ^ group  =>  entries }  =  async_groups  -> 
157-           { % { async_groups  |  group  =>  names   ++   entries } ,  state . async_modules } 
155+     { groups ,   async_groups }  = 
156+       case  state . groups  do 
157+         % { ^ group  =>  entries }  =  groups  -> 
158+           { % { groups  |  group  =>  Enum . reverse ( names ,   entries ) } ,  state . async_groups } 
158159
159-         % { }  =  async_groups  -> 
160-           { Map . put ( async_groups ,  group ,  names ) ,  :queue . in ( { : group,   group } ,  state . async_modules ) } 
160+         % { }  =  groups  -> 
161+           { Map . put ( groups ,  group ,  names ) ,  [ group   |  state . async_groups ] } 
161162      end 
162163
163-     { :reply ,  :ok , 
164-      take_modules ( % { state  |  async_groups:  async_groups ,  async_modules:  async_modules } ) } 
164+     { :reply ,  :ok ,  take_modules ( % { state  |  groups:  groups ,  async_groups:  async_groups } ) } 
165165  end 
166166
167167  def  handle_call ( { :add ,  _async? ,  _group ,  _names } ,  _from ,  state )  do 
@@ -174,49 +174,44 @@ defmodule ExUnit.Server do
174174
175175  defp  take_modules ( % { waiting:  { from ,  count } }  =  state )  do 
176176    has_async_modules?  =  not  :queue . is_empty ( state . async_modules ) 
177+     has_async_groups?  =  state . async_groups  !=  [ ] 
177178
178179    cond  do 
179-       not  has_async_modules?  and  state . loaded  ==  :done  -> 
180+       not  has_async_modules?  and  not   has_async_groups?   and   state . loaded  ==  :done  -> 
180181        GenServer . reply ( from ,  nil ) 
181182        % { state  |  waiting:  nil } 
182183
183-       not  has_async_modules?  -> 
184-         state 
185- 
186-       true  -> 
187-         { async_modules ,  remaining_modules }  =  take_until ( count ,  state . async_modules ) 
184+       has_async_modules?  -> 
185+         { reply ,  remaining_modules }  =  take_until ( count ,  state . async_modules ) 
186+         GenServer . reply ( from ,  reply ) 
187+         % { state  |  async_modules:  remaining_modules ,  waiting:  nil } 
188188
189-         { async_modules ,  remaining_groups }  = 
190-           Enum . map_reduce ( async_modules ,  state . async_groups ,  fn 
191-             { :module ,  module } ,  async_groups  -> 
192-               { [ module ] ,  async_groups } 
189+       has_async_groups?  -> 
190+         { groups ,  remaining_groups }  =  Enum . split ( state . async_groups ,  count ) 
193191
194-             { :group ,  group } ,  async_groups  -> 
195-               { group_modules ,  async_groups }  =  Map . pop! ( async_groups ,  group ) 
196-               { Enum . reverse ( group_modules ) ,  async_groups } 
192+         { reply ,  groups }  = 
193+           Enum . map_reduce ( groups ,  state . groups ,  fn  group ,  acc  -> 
194+             { entries ,  acc }  =  Map . pop! ( acc ,  group ) 
195+             { { group ,  Enum . reverse ( entries ) } ,  acc } 
197196          end ) 
198197
199-         GenServer . reply ( from ,  async_modules ) 
198+         GenServer . reply ( from ,  reply ) 
199+         % { state  |  groups:  groups ,  async_groups:  remaining_groups ,  waiting:  nil } 
200200
201-         % { 
202-           state 
203-           |  async_groups:  remaining_groups , 
204-             async_modules:  remaining_modules , 
205-             waiting:  nil 
206-         } 
201+       true  -> 
202+         state 
207203    end 
208204  end 
209205
210-   # :queue.split fails if the provided count is larger than the queue size; 
211-   # as we also want to return the values as a list later, we directly 
212-   # return {list, queue} instead of {queue, queue} 
206+   # :queue.split fails if the provided count is larger than the queue size. 
207+   # We also want to return the values as tuples of shape {group, [modules]}. 
213208  defp  take_until ( n ,  queue ) ,  do:  take_until ( n ,  queue ,  [ ] ) 
214209
215210  defp  take_until ( 0 ,  queue ,  acc ) ,  do:  { Enum . reverse ( acc ) ,  queue } 
216211
217212  defp  take_until ( n ,  queue ,  acc )  do 
218213    case  :queue . out ( queue )  do 
219-       { { :value ,  item } ,  queue }  ->  take_until ( n  -  1 ,  queue ,  [ item  |  acc ] ) 
214+       { { :value ,  item } ,  queue }  ->  take_until ( n  -  1 ,  queue ,  [ { nil ,   [ item ] }  |  acc ] ) 
220215      { :empty ,  queue }  ->  { Enum . reverse ( acc ) ,  queue } 
221216    end 
222217  end 
0 commit comments