11defmodule ExUnit.DocTest do
2- @ moduledoc """
2+ @ moduledoc ~S """
33 Extract test cases from the documentation.
44
55 Doctests allow us to generate tests from code examples found
@@ -131,7 +131,7 @@ defmodule ExUnit.DocTest do
131131
132132 You can also showcase expressions raising an exception, for example:
133133
134- iex(1) > raise "some error"
134+ iex> raise "some error"
135135 ** (RuntimeError) some error
136136
137137 Doctest will look for a line starting with `** (` and it will parse it
@@ -141,6 +141,19 @@ defmodule ExUnit.DocTest do
141141 Therefore, it is possible to match on multiline messages as long as there
142142 are no empty lines on the message itself.
143143
144+ Asserting on the full exception message might not be possible because it is
145+ non-deterministic, or it might result in brittle tests if the exact message
146+ changes and gets more detailed.
147+ Since Elixir 1.19.0, doctests allow the use of an ellipsis (`...`) at the
148+ end of messages:
149+
150+ iex> raise "some error in pid: #{inspect(self())}"
151+ ** (RuntimeError) some error in pid: ...
152+
153+ iex> raise "some error in pid:\n#{inspect(self())}"
154+ ** (RuntimeError) some error in pid:
155+ ...
156+
144157 ## When not to use doctest
145158
146159 In general, doctests are not recommended when your code examples contain
@@ -565,7 +578,7 @@ defmodule ExUnit.DocTest do
565578 "Doctest failed: expected exception #{ inspect ( exception ) } but got " <>
566579 "#{ inspect ( actual_exception ) } with message #{ inspect ( actual_message ) } "
567580
568- actual_message != message ->
581+ not error_message_matches? ( actual_message , message ) ->
569582 "Doctest failed: wrong message for #{ inspect ( actual_exception ) } \n " <>
570583 "expected:\n " <>
571584 " #{ inspect ( message ) } \n " <>
@@ -588,6 +601,15 @@ defmodule ExUnit.DocTest do
588601 end
589602 end
590603
604+ defp error_message_matches? ( actual , expected ) when actual == expected , do: true
605+
606+ defp error_message_matches? ( actual , expected ) do
607+ case String . replace_suffix ( expected , "..." , "" ) do
608+ ^ expected -> false
609+ ellipsis_removed -> String . starts_with? ( actual , ellipsis_removed )
610+ end
611+ end
612+
591613 defp test_import ( _mod , false ) , do: [ ]
592614 defp test_import ( mod , _ ) , do: [ quote ( do: import ( unquote ( mod ) ) ) ]
593615
0 commit comments