Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions lib/ex_unit/lib/ex_unit/diff.ex
Original file line number Diff line number Diff line change
Expand Up @@ -1142,9 +1142,22 @@ defmodule ExUnit.Diff do
defp maybe_escape(other, %{context: :match}), do: other
defp maybe_escape(other, _env), do: escape(other)

# We escape container types to make a distinction between AST
# and values that should be inspected. All other values have no
# special AST representation, so we can keep them as is.
# We escape container types to make a distinction between AST and values that
# should be inspected. Maps and structs without custom inspect implementation
# should not be inspected, convert it to ast.
# All other values have no special AST representation, so we can keep them as is.
defp escape(other) when is_map(other) do
struct = maybe_struct(other)

if struct && Inspect.impl_for(other) not in [Inspect.Any, Inspect.Map] do
other
else
other
|> Map.to_list()
|> build_map_or_struct(struct)
end
end

defp escape(other) when is_list(other) or is_tuple(other), do: {other}
defp escape(other), do: other

Expand Down
187 changes: 180 additions & 7 deletions lib/ex_unit/test/ex_unit/diff_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ defmodule ExUnit.DiffTest do
defstruct [:name, :age]
end

defmodule Customer do
defstruct [:address, :age, :first_name, :language, :last_name, :notifications]
end

defmodule Person do
defstruct [:age]
end
Expand Down Expand Up @@ -126,10 +130,11 @@ defmodule ExUnit.DiffTest do
assert env_binding == expected_binding
end

@terminal_width 80
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this changes other tests. I can either adjust it or make a custom helper to test it ???

defp to_diff(side, sign) do
side
|> Diff.to_algebra(&diff_wrapper(&1, sign))
|> Algebra.format(:infinity)
|> Algebra.format(@terminal_width)
|> IO.iodata_to_binary()
end

Expand Down Expand Up @@ -682,13 +687,49 @@ defmodule ExUnit.DiffTest do
refute_diff(
%User{age: %Date{}} = struct,
~s/%ExUnit.DiffTest.User{age: %-Date-{}}/,
~s/%ExUnit.DiffTest.User{age: %+DateTime+{calendar: Calendar.ISO, day: 30, hour: 13, microsecond: {253158, 6}, minute: 49, month: 7, second: 59, std_offset: 0, time_zone: "Etc\/UTC", utc_offset: 0, year: 2020, zone_abbr: "UTC"}, name: nil}/
"""
%ExUnit.DiffTest.User{
age: %+DateTime+{
calendar: Calendar.ISO,
day: 30,
hour: 13,
microsecond: {253158, 6},
minute: 49,
month: 7,
second: 59,
std_offset: 0,
time_zone: "Etc\/UTC",
utc_offset: 0,
year: 2020,
zone_abbr: "UTC"
},
name: nil
}\
"""
)

refute_diff(
%{age: %Date{}} = struct,
~s/%{age: %-Date-{}}/,
~s/%ExUnit.DiffTest.User{age: %+DateTime+{calendar: Calendar.ISO, day: 30, hour: 13, microsecond: {253158, 6}, minute: 49, month: 7, second: 59, std_offset: 0, time_zone: "Etc\/UTC", utc_offset: 0, year: 2020, zone_abbr: "UTC"}, name: nil}/
"""
%ExUnit.DiffTest.User{
age: %+DateTime+{
calendar: Calendar.ISO,
day: 30,
hour: 13,
microsecond: {253158, 6},
minute: 49,
month: 7,
second: 59,
std_offset: 0,
time_zone: \"Etc/UTC\",
utc_offset: 0,
year: 2020,
zone_abbr: \"UTC\"
},
name: nil
}\
"""
)
end

Expand Down Expand Up @@ -836,6 +877,110 @@ defmodule ExUnit.DiffTest do
)
end

test "maps in lists" do
map = %{
address: %{
street: "123 Main St",
city: "Springfield",
state: "IL",
zip: "62701"
},
age: 30,
first_name: "John",
language: "en-US",
last_name: "Doe",
notifications: true
}

refute_diff(
[map] == [],
"""
[
-%{
address: %{state: "IL", zip: "62701", street: "123 Main St", city: "Springfield"},
age: 30,
first_name: "John",
language: "en-US",
last_name: "Doe",
notifications: true
}-
]\
""",
"[]"
)

refute_diff(
[] == [map],
"[]",
"""
[
+%{
address: %{state: "IL", zip: "62701", street: "123 Main St", city: "Springfield"},
age: 30,
first_name: "John",
language: "en-US",
last_name: "Doe",
notifications: true
}+
]\
"""
)

assert_diff([map] == [map], [])
end

test "structs in lists" do
customer = %Customer{
address: %{
street: "123 Main St",
city: "Springfield",
state: "IL",
zip: "62701"
},
age: 30,
first_name: "John",
language: "en-US",
last_name: "Doe",
notifications: true
}

refute_diff(
[customer] == [],
"""
[
-%ExUnit.DiffTest.Customer{
address: %{state: "IL", zip: "62701", street: "123 Main St", city: "Springfield"},
age: 30,
first_name: "John",
language: "en-US",
last_name: "Doe",
notifications: true
}-
]\
""",
"[]"
)

refute_diff(
[] == [customer],
"[]",
"""
[
+%ExUnit.DiffTest.Customer{
address: %{state: "IL", zip: "62701", street: "123 Main St", city: "Springfield"},
age: 30,
first_name: "John",
language: "en-US",
last_name: "Doe",
notifications: true
}+
]\
"""
)

assert_diff([customer] == [customer], [])
end

test "maps and structs with escaped values" do
refute_diff(
%User{age: {1, 2, 3}} = %User{age: {1, 2, 4}},
Expand Down Expand Up @@ -1082,8 +1227,18 @@ defmodule ExUnit.DiffTest do

refute_diff(
{ref1, ref2} == {ref2, ref1},
"{-#{inspect_ref1}-, -#{inspect_ref2}-}",
"{+#{inspect_ref2}+, +#{inspect_ref1}+}"
"""
{
-#{inspect_ref1}-,
-#{inspect_ref2}-
}\
""",
"""
{
+#{inspect_ref2}+,
+#{inspect_ref1}+
}\
"""
)

refute_diff(
Expand All @@ -1100,7 +1255,16 @@ defmodule ExUnit.DiffTest do

refute_diff(ref1 == :a, "-#{inspect_ref1}-", "+:a+")
refute_diff({ref1, ref2} == :a, "-{#{inspect_ref1}, #{inspect_ref2}}", "+:a+")
refute_diff(%{ref1 => ref2} == :a, "-%{#{inspect_ref1} => #{inspect_ref2}}", "+:a+")

refute_diff(
%{ref1 => ref2} == :a,
"""
-%{
#{inspect_ref1} => #{inspect_ref2}
}\
""",
"+:a+"
)

refute_diff(
%Opaque{data: ref1} == :a,
Expand Down Expand Up @@ -1141,7 +1305,16 @@ defmodule ExUnit.DiffTest do
refute_diff(identity == :a, "-#{inspect}-", "+:a+")
refute_diff({identity, identity} == :a, "-{#{inspect}, #{inspect}}", "+:a+")
refute_diff({identity, :a} == {:a, identity}, "{-#{inspect}-, -:a-}", "{+:a+, +#{inspect}+}")
refute_diff(%{identity => identity} == :a, "-%{#{inspect} => #{inspect}}", "+:a+")

refute_diff(
%{identity => identity} == :a,
"""
-%{
#{inspect} => #{inspect}
}-\
""",
"+:a+"
)

refute_diff(
(&String.to_charlist/1) == (&String.unknown/1),
Expand Down
Loading