Skip to content

Commit a4ddaa3

Browse files
author
José Valim
committed
Properly normalize ExUnit filters, closes #7390
1 parent 15bbc3f commit a4ddaa3

File tree

1 file changed

+34
-6
lines changed

1 file changed

+34
-6
lines changed

lib/ex_unit/lib/ex_unit/filters.ex

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,36 @@ defmodule ExUnit.Filters do
3737
iex> ExUnit.Filters.normalize([:foo, :bar, :bar], [:foo, :baz])
3838
{[:foo, :bar], [:baz]}
3939
40+
iex> ExUnit.Filters.normalize([foo: "true"], [:foo])
41+
{[foo: "true"], [:foo]}
42+
43+
iex> ExUnit.Filters.normalize([:foo], [foo: "true"])
44+
{[:foo], []}
45+
46+
iex> ExUnit.Filters.normalize([foo: "true"], [foo: true])
47+
{[foo: "true"], []}
48+
49+
iex> ExUnit.Filters.normalize([foo: true], [foo: "true"])
50+
{[foo: true], []}
51+
4052
"""
4153
@spec normalize(t | nil, t | nil) :: {t, t}
4254
def normalize(include, exclude) do
43-
include = include |> List.wrap() |> Enum.uniq()
44-
exclude = exclude |> List.wrap() |> Enum.uniq() |> Kernel.--(include)
45-
{include, exclude}
55+
{include_atoms, include_tags} =
56+
include |> List.wrap() |> Enum.uniq() |> Enum.split_with(&is_atom/1)
57+
58+
{exclude_atoms, exclude_tags} =
59+
exclude |> List.wrap() |> Enum.uniq() |> Enum.split_with(&is_atom/1)
60+
61+
exclude_tags = Map.new(exclude_tags)
62+
63+
exclude_included =
64+
for include_tag <- include_tags, key = has_tag(include_tag, exclude_tags), do: key
65+
66+
exclude_tags =
67+
exclude_tags |> Map.drop(include_atoms) |> Map.drop(exclude_included) |> Map.to_list()
68+
69+
{include_atoms ++ include_tags, (exclude_atoms -- include_atoms) ++ exclude_tags}
4670
end
4771

4872
@doc """
@@ -121,22 +145,26 @@ defmodule ExUnit.Filters do
121145
end
122146
end
123147

124-
defp has_tag({key, %Regex{} = value}, tags, _collection) when is_atom(key) do
148+
defp has_tag(pair, tags, _collection) do
149+
has_tag(pair, tags)
150+
end
151+
152+
defp has_tag({key, %Regex{} = value}, tags) when is_atom(key) do
125153
case Map.fetch(tags, key) do
126154
{:ok, tag} -> to_string(tag) =~ value and key
127155
_ -> false
128156
end
129157
end
130158

131-
defp has_tag({key, value}, tags, _collection) when is_atom(key) do
159+
defp has_tag({key, value}, tags) when is_atom(key) do
132160
case Map.fetch(tags, key) do
133161
{:ok, ^value} -> key
134162
{:ok, tag} -> compare(to_string(tag), to_string(value)) and key
135163
_ -> false
136164
end
137165
end
138166

139-
defp has_tag(key, tags, _collection) when is_atom(key), do: Map.has_key?(tags, key) and key
167+
defp has_tag(key, tags) when is_atom(key), do: Map.has_key?(tags, key) and key
140168

141169
defp to_integer(integer) when is_integer(integer), do: integer
142170
defp to_integer(integer) when is_binary(integer), do: String.to_integer(integer)

0 commit comments

Comments
 (0)