@@ -128,7 +128,7 @@ defmodule ExUnit.Runner do
128128 defp run_test ( config , test , context ) do
129129 config . formatter . test_started ( config . formatter_id , test )
130130
131- filters = combine_filters ( config . include , config . exclude )
131+ filters = combine_filters ( [ include: config . include , exclude: config . exclude ] )
132132 result = evaluate_filters ( filters , test . tags )
133133
134134 test = case result do
@@ -200,34 +200,39 @@ defmodule ExUnit.Runner do
200200 end
201201
202202 def evaluate_filters ( filters , tags ) do
203- results = Enum . flat_map tags , fn tag ->
204- Enum . map filters , fn filter ->
205- { { elem ( filter , 0 ) , elem ( tag , 0 ) } , evaluate_filter ( filter , tag ) }
206- end
203+ Enum . find_value tags , :ok , fn { tag_key , _ } = tag ->
204+ unless tag_accepted? ( filters , tag ) , do: { :error , tag_key }
207205 end
206+ end
208207
209- results = Enum . reduce results , HashDict . new , fn { key , evaluation } , dict ->
210- Dict . update dict , key , evaluation , & ( evaluation || & 1 )
211- end
208+ defp tag_accepted? ( [ include: include , exclude: exclude ] , tag ) do
209+ tag_included? ( include , tag ) and not tag_excluded? ( exclude , tag )
210+ end
212211
213- mismatch = Enum . find Dict . to_list ( results ) , & match? ( { _ , false } , & 1 )
212+ defp tag_included? ( include , { tag_key , tag_value } ) do
213+ case Dict . fetch ( include , tag_key ) do
214+ { :ok , allowed } -> tag_value in allowed
215+ :error -> true
216+ end
217+ end
214218
215- case mismatch do
216- { { _ , tag } , _ } -> { :error , tag }
217- _ -> :ok
219+ defp tag_excluded? ( exclude , { tag_key , tag_value } ) do
220+ case Dict . fetch ( exclude , tag_key ) do
221+ { :ok , forbidden } -> tag_value in forbidden
222+ :error -> false
218223 end
219224 end
220225
221- def evaluate_filter ( { tag , value , :include } , { tag , value } ) , do: true
222- def evaluate_filter ( { tag , value , :exclude } , { tag , value } ) , do: false
223- def evaluate_filter ( { tag , _ , :include } , { tag , _ } ) , do: false
224- def evaluate_filter ( { tag , _ , :exclude } , { tag , _ } ) , do: true
225- def evaluate_filter ( _ , _ ) , do: true
226+ defp combine_filters ( [ include: include , exclude: exclude ] ) do
227+ include = group_by_key ( include )
228+ exclude = group_by_key ( exclude )
229+ [ include: include , exclude: exclude ]
230+ end
226231
227- defp combine_filters ( include , exclude ) do
228- include = Enum . map ( include , fn { tag , value } -> { tag , value , :include } end )
229- exclude = Enum . map ( exclude , fn { tag , value } -> { tag , value , :exclude } end )
230- Enum . concat ( include , exclude )
232+ defp group_by_key ( dict ) do
233+ Enum . reduce dict , HashDict . new , fn { key , value } , acc ->
234+ Dict . update acc , key , [ value ] , & [ value | & 1 ]
235+ end
231236 end
232237
233238 defp pruned_stacktrace , do: prune_stacktrace ( System . stacktrace )
0 commit comments