       exception = unquote(exception)
       doctest = unquote(doctest)
       message = unquote(message)
-
+      ExUnit.DocTest.__error__(fn -> unquote(expr_ast) end, message, doctest, exception, stack)
+    end
+  end
+
+  @doc false
+  def __test__(result, expected, doctest, expr, stack) do
+    case result do
+      ^expected ->
+        :ok
+
+      actual ->
+        error = [
+          message: "Doctest failed",
+          doctest: doctest,
+          expr: expr,
+          left: actual,
+          right: expected
+        ]
+
+        reraise ExUnit.AssertionError, error, stack
+    end
+  end
+
+  @doc false
+  def __inspect__(value, expected, doctest, expr, parent_stack) do
+    result =
       try do
-        unquote(expr_ast)
+        inspect(value, safe: false)
       rescue
-        error ->
-          actual_exception = error.__struct__
-          actual_message = Exception.message(error)
-
-          message =
-            cond do
-              actual_exception != exception ->
-                "Doctest failed: expected exception #{inspect(exception)} but got " <>
-                  "#{inspect(actual_exception)} with message #{inspect(actual_message)}"
-
-              actual_message != message ->
-                "Doctest failed: wrong message for #{inspect(actual_exception)}\n" <>
-                  "expected:\n" <>
-                  "  #{inspect(message)}\n" <>
-                  "actual:\n" <> "  #{inspect(actual_message)}"
-
-              true ->
-                nil
-            end
-
-          if message do
-            reraise ExUnit.AssertionError, [message: message, doctest: doctest], stack
+        e ->
+          stack = Enum.drop(__STACKTRACE__, 1)
+          {[message: Exception.message(e)], ExUnit.Runner.prune_stacktrace(stack)}
+      else
+        ^expected -> :ok
+        actual -> {[left: actual, right: expected, message: "Doctest failed"], []}
+      end
+
+    case result do
+      :ok ->
+        :ok
+
+      {extra, stack} ->
+        error = [doctest: doctest, expr: expr] ++ extra
+        reraise ExUnit.AssertionError, error, stack ++ parent_stack
+    end
+  end
+
+  @doc false
+  def __error__(fun, message, doctest, exception, stack) do
+    try do
+      fun.()
+    rescue
+      error ->
+        actual_exception = error.__struct__
+        actual_message = Exception.message(error)
+
+        message =
+          cond do
+            actual_exception != exception ->
+              "Doctest failed: expected exception #{inspect(exception)} but got " <>
+                "#{inspect(actual_exception)} with message #{inspect(actual_message)}"
+
+            actual_message != message ->
+              "Doctest failed: wrong message for #{inspect(actual_exception)}\n" <>
+                "expected:\n" <>
+                "  #{inspect(message)}\n" <>
+                "actual:\n" <> "  #{inspect(actual_message)}"
+
+            true ->
+              nil
           end
-      else
-        _ ->
-          message =
-            "Doctest failed: expected exception #{inspect(exception)} but nothing was raised"
-
-          error = [message: message, doctest: doctest]
-          reraise ExUnit.AssertionError, error, stack
-      end
+
+        if message do
+          reraise ExUnit.AssertionError, [message: message, doctest: doctest], stack
+        end
+    else
+      _ ->
+        message =
+          "Doctest failed: expected exception #{inspect(exception)} but nothing was raised"
+
+        error = [message: message, doctest: doctest]
+        reraise ExUnit.AssertionError, error, stack
     end
   end
 

    doctest = "\n" <> formatted <> "\n" <> expected
    expr_ast = string_to_quoted(location, stack, expr, doctest) |> insert_assertions()
    expected_ast = string_to_quoted(location, stack, expected, doctest)
    last_expr_ast = last_expr(expr_ast)

    quote do
      expected = unquote(expected_ast)
      value = unquote(expr_ast)

      result =
        try do
          inspect(value, safe: false)
        rescue
          e -> {[message: Exception.message(e)], ExUnit.Runner.prune_stacktrace(__STACKTRACE__)}
        else
          ^expected -> :ok
          actual -> {[left: actual, right: expected, message: "Doctest failed"], []}
        end

      case result do
        :ok ->
          :ok

        {extra, stack} ->
          doctest = unquote(doctest)

          expr =
            "inspect(#{unquote(Macro.to_string(last_expr_ast))}) === " <>
              "#{unquote(String.trim(expected))}"

          error = [doctest: doctest, expr: expr] ++ extra
          reraise ExUnit.AssertionError, error, stack ++ unquote(stack)
      end
    end
  end



    quote do
      expected = unquote(expected_ast)
      doctest = unquote(doctest)
      expr = <<unquote(Macro.to_string(last_expr_ast)), " === ", unquote(String.trim(expected))>>
      stack = unquote(stack)

      ExUnit.DocTest.__test__(unquote(expr_ast), expected, doctest, expr, stack)
    end
  end

