Skip to content

Commit 2e7a49d

Browse files
committed
Abort diffing on binary patterns, closes #15191
1 parent 5bad452 commit 2e7a49d

3 files changed

Lines changed: 39 additions & 36 deletions

File tree

lib/ex_unit/lib/ex_unit/diff.ex

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ defmodule ExUnit.Diff do
3838
"""
3939
def compute(left, right, context) do
4040
diff(left, right, context_to_env(context))
41+
catch
42+
:undiffable -> nil
4143
end
4244

4345
defp context_to_env({:match, pins}),
@@ -113,6 +115,18 @@ defmodule ExUnit.Diff do
113115
diff_string_concat(left, right, env)
114116
end
115117

118+
defp diff_quoted({:<<>>, _, parts} = left, right, _expanded, env) do
119+
if Enum.all?(parts, &is_binary/1) do
120+
equivalent? = IO.iodata_to_binary(parts) == right
121+
diff_left = update_diff_meta(left, not equivalent?)
122+
diff_right = escape(right) |> update_diff_meta(not equivalent?)
123+
diff = %__MODULE__{equivalent?: equivalent?, left: diff_left, right: diff_right}
124+
{diff, env}
125+
else
126+
throw(:undiffable)
127+
end
128+
end
129+
116130
defp diff_quoted({:when, _, [_, _]} = left, right, _expanded, env) do
117131
diff_guard(left, right, env)
118132
end

lib/ex_unit/test/ex_unit/diff_test.exs

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,22 +1132,6 @@ defmodule ExUnit.DiffTest do
11321132
)
11331133
end
11341134

1135-
test "concat binaries with specifiers" do
1136-
input = "foobar"
1137-
1138-
refute_diff(
1139-
<<trap::binary-size(3)>> <> "baz" = input,
1140-
"-<<trap::binary-size(3)>> <> \"baz\"-",
1141-
"+\"foobar\"+"
1142-
)
1143-
1144-
refute_diff(
1145-
"hello " <> <<_::binary-size(6)>> = "hello world",
1146-
"\"hello \" <> -<<_::binary-size(6)>>-",
1147-
"\"hello +world+\""
1148-
)
1149-
end
1150-
11511135
test "underscore" do
11521136
assert_diff(_ = :a, [])
11531137
assert_diff({_, _} = {:a, :b}, [])
@@ -1361,12 +1345,4 @@ defmodule ExUnit.DiffTest do
13611345
"#Function<\n #{uniq}/0 in ExUnit.DiffTest.closure/1\n [+2+]\n>"
13621346
)
13631347
end
1364-
1365-
test "not supported" do
1366-
refute_diff(
1367-
<<147, 1, 2, 31>> = <<193, 1, 31>>,
1368-
"-<<147, 1, 2, 31>>-",
1369-
"+<<193, 1, 31>>+"
1370-
)
1371-
end
13721348
end

lib/ex_unit/test/ex_unit/formatter_test.exs

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ defmodule ExUnit.FormatterTest do
3535
defp formatter(_key, value), do: value
3636

3737
defp diff_formatter(:diff_enabled?, _default), do: true
38+
defp diff_formatter(:diff_insert, value), do: Inspect.Algebra.concat(["+", value, "+"])
39+
defp diff_formatter(:diff_delete, value), do: Inspect.Algebra.concat(["-", value, "-"])
3840
defp diff_formatter(_key, value), do: value
3941

4042
defp kw_to_string(kw), do: for({k, v} <- kw, do: {k, IO.iodata_to_binary(v)})
@@ -328,12 +330,15 @@ defmodule ExUnit.FormatterTest do
328330

329331
assert format_assertion_diff(assertion_error, 0, :infinity, &diff_formatter/2)
330332
|> kw_to_string() ==
331-
[{:left, "{3, 2, 1}"}, {:right, "{1, 2, 3}"}]
333+
[{:left, "{-3-, 2, -1-}"}, {:right, "{+1+, 2, +3+}"}]
332334
end
333335

334336
nfc_hello = String.normalize("héllo", :nfc)
335337
nfd_hello = String.normalize("héllo", :nfd)
336338

339+
nfc_left_hello = String.normalize("h-é-llo", :nfc)
340+
nfd_right_hello = String.normalize("h+é+llo", :nfd)
341+
337342
test "formats assertions with hints" do
338343
assertion_error = catch_assertion(assert unquote(nfc_hello) == unquote(nfd_hello))
339344
failure = [{:error, assertion_error, []}]
@@ -343,19 +348,16 @@ defmodule ExUnit.FormatterTest do
343348
test/ex_unit/formatter_test.exs:1
344349
Assertion with == failed
345350
code: assert "#{unquote(nfc_hello)}" == "#{unquote(nfd_hello)}"
346-
left: "#{unquote(nfc_hello)}"
347-
right: "#{unquote(nfd_hello)}"
351+
left: "#{unquote(nfc_left_hello)}"
352+
right: "#{unquote(nfd_right_hello)}"
348353
hint: you are comparing strings that have the same visual representation but are made of different Unicode codepoints
349354
"""
350355

351-
assert format_test_failure(test(), failure, 1, 80, &diff_formatter/2) ==
352-
format_test_failure(test(), failure, 1, 80, &formatter/2)
353-
354356
assert format_assertion_diff(assertion_error, 0, :infinity, &diff_formatter/2)
355357
|> kw_to_string() ==
356358
[
357-
left: inspect(unquote(nfc_hello)),
358-
right: inspect(unquote(nfd_hello)),
359+
left: inspect(unquote(nfc_left_hello)),
360+
right: inspect(unquote(nfd_right_hello)),
359361
hint:
360362
"you are comparing strings that have the same visual representation but are made of different Unicode codepoints"
361363
]
@@ -377,8 +379,8 @@ defmodule ExUnit.FormatterTest do
377379
The following variables were pinned:
378380
expected_module = ExUnit.TestModule
379381
code: assert %^expected_module{} = nil
380-
left: %^expected_module{}
381-
right: nil
382+
left: -%^expected_module{}-
383+
right: +nil+
382384
"""
383385
end
384386

@@ -548,8 +550,19 @@ defmodule ExUnit.FormatterTest do
548550
assert format_test_all_failure(test_module(), failure, 1, :infinity, &diff_formatter/2) =~ """
549551
match (=) failed
550552
code: assert :foo = %{bar: [1 | 2]}
551-
left: :foo
552-
right: %{bar: [1 | 2]}
553+
left: -:foo-
554+
right: +%{bar: [1 | 2]}+
555+
"""
556+
end
557+
558+
test "formats assertions with binary matching without diffing" do
559+
failure = [{:error, catch_assertion(assert %{foo: <<_>>, bar: 2} = %{foo: "!", bar: 3}), []}]
560+
561+
assert format_test_all_failure(test_module(), failure, 1, :infinity, &diff_formatter/2) =~ """
562+
match (=) failed
563+
code: assert %{foo: <<_>>, bar: 2} = %{foo: "!", bar: 3}
564+
left: %{foo: <<_>>, bar: 2}
565+
right: %{foo: "!", bar: 3}
553566
"""
554567
end
555568

0 commit comments

Comments
 (0)