@@ -346,9 +346,6 @@ defmodule ExUnit.DocTest do
346346 end
347347
348348 defp test_content ( % { exprs: exprs , line: line } , module , do_import , file ) do
349- location = [ line: line , file: Path . relative_to_cwd ( file ) ]
350- stack = Macro . escape ( [ { module , :__MODULE__ , 0 , location } ] )
351-
352349 if multiple_exceptions? ( exprs ) do
353350 raise Error ,
354351 line: line ,
@@ -358,11 +355,7 @@ defmodule ExUnit.DocTest do
358355 "please separate your iex> prompts by multiple newlines to start new examples"
359356 end
360357
361- tests =
362- Enum . map ( exprs , fn { expr , expected , doctest } ->
363- test_case_content ( expr , expected , location , stack , doctest )
364- end )
365-
358+ tests = Enum . map ( exprs , fn expr -> test_case_content ( expr , module , file ) end )
366359 { :__block__ , [ ] , test_import ( module , do_import ) ++ tests }
367360 end
368361
@@ -372,66 +365,74 @@ defmodule ExUnit.DocTest do
372365
373366 defp multiple_exceptions? ( exprs ) do
374367 Enum . count ( exprs , fn
375- { _ , { :error , _ , _ } , _ } -> true
368+ % { expected: { :error , _ , _ } } -> true
376369 _ -> false
377370 end ) > 1
378371 end
379372
380- defp test_case_content ( expr_lines , :test , location , stack , doctest ) do
381- string_to_quoted ( location , stack , expr_lines , doctest ) |> insert_assertions ( )
373+ defp test_case_content ( % { expected: :test } = data , module , file ) do
374+ % { expr: expr , expr_line: expr_line , doctest: doctest } = data
375+ string_to_quoted ( module , file , expr_line , expr , doctest ) |> insert_assertions ( )
382376 end
383377
384- defp test_case_content ( expr_lines , { :test , expected } , location , stack , doctest ) do
385- expr_ast = string_to_quoted ( location , stack , expr_lines , doctest ) |> insert_assertions ( )
386- expected_ast = string_to_quoted ( update_line ( location , expr_lines ) , stack , expected , doctest )
378+ defp test_case_content ( % { expected: { :test , expected } } = data , module , file ) do
379+ % { expr: expr , expr_line: expr_line , expected_line: expected_line , doctest: doctest } = data
380+ expr_ast = string_to_quoted ( module , file , expr_line , expr , doctest ) |> insert_assertions ( )
381+ expected_ast = string_to_quoted ( module , file , expected_line , expected , doctest )
387382 last_expr = Macro . to_string ( last_expr ( expr_ast ) )
388383
389384 quote do
390- value = unquote ( expr_ast )
391- expected = unquote ( expected_ast )
392- doctest = unquote ( doctest )
393- last_expr = unquote ( last_expr )
394- expected_expr = unquote ( expected )
395- stack = unquote ( stack )
396-
397- ExUnit.DocTest . __test__ ( value , expected , doctest , last_expr , expected_expr , stack )
385+ ExUnit.DocTest . __test__ (
386+ unquote ( expr_ast ) ,
387+ unquote ( expected_ast ) ,
388+ unquote ( doctest ) ,
389+ unquote ( last_expr ) ,
390+ unquote ( expected ) ,
391+ unquote ( module ) ,
392+ unquote ( file ) ,
393+ unquote ( expr_line )
394+ )
398395 end
399396 end
400397
401- defp test_case_content ( expr_lines , { :inspect , expected } , location , stack , doctest ) do
402- expr_ast = string_to_quoted ( location , stack , expr_lines , doctest ) |> insert_assertions ( )
398+ defp test_case_content ( % { expected: { :inspect , expected } } = data , module , file ) do
399+ % { expr: expr , expr_line: expr_line , doctest: doctest } = data
400+ expr_ast = string_to_quoted ( module , file , expr_line , expr , doctest ) |> insert_assertions ( )
403401 last_expr = Macro . to_string ( last_expr ( expr_ast ) )
404402
405403 quote do
406- value = unquote ( expr_ast )
407- expected = unquote ( expected )
408- doctest = unquote ( doctest )
409- last_expr = unquote ( last_expr )
410- expected_expr = unquote ( inspect ( expected ) )
411- stack = unquote ( stack )
412-
413- ExUnit.DocTest . __inspect__ ( value , expected , doctest , last_expr , expected_expr , stack )
404+ ExUnit.DocTest . __inspect__ (
405+ unquote ( expr_ast ) ,
406+ unquote ( expected ) ,
407+ unquote ( doctest ) ,
408+ unquote ( last_expr ) ,
409+ unquote ( inspect ( expected ) ) ,
410+ unquote ( module ) ,
411+ unquote ( file ) ,
412+ unquote ( expr_line )
413+ )
414414 end
415415 end
416416
417- defp test_case_content ( expr , { :error , exception , message } , location , stack , doctest ) do
418- expr_ast = string_to_quoted ( location , stack , expr , doctest )
417+ defp test_case_content ( % { expected: { :error , exception , message } } = data , module , file ) do
418+ % { expr: expr , expr_line: expr_line , doctest: doctest } = data
419+ expr_ast = string_to_quoted ( module , file , expr_line , expr , doctest )
419420
420421 quote do
421- stack = unquote ( stack )
422- message = unquote ( message )
423- doctest = unquote ( doctest )
424- exception = unquote ( exception )
425- ExUnit.DocTest . __error__ ( fn -> unquote ( expr_ast ) end , message , exception , doctest , stack )
422+ ExUnit.DocTest . __error__ (
423+ fn -> unquote ( expr_ast ) end ,
424+ unquote ( message ) ,
425+ unquote ( exception ) ,
426+ unquote ( doctest ) ,
427+ unquote ( module ) ,
428+ unquote ( file ) ,
429+ unquote ( expr_line )
430+ )
426431 end
427432 end
428433
429- defp update_line ( location , lines ) do
430- Keyword . replace_lazy ( location , :line , & ( & 1 + length ( lines ) ) )
431- end
432-
433434 @ doc false
434- def __test__ ( value , expected , doctest , last_expr , expected_expr , stack ) do
435+ def __test__ ( value , expected , doctest , last_expr , expected_expr , module , file , line ) do
435436 case value do
436437 ^ expected ->
437438 { :ok , value }
@@ -445,12 +446,12 @@ defmodule ExUnit.DocTest do
445446 right: expected
446447 ]
447448
448- reraise ExUnit.AssertionError , error , stack
449+ reraise ExUnit.AssertionError , error , stack ( module , file , line )
449450 end
450451 end
451452
452453 @ doc false
453- def __inspect__ ( value , expected , doctest , last_expr , expected_expr , parent_stack ) do
454+ def __inspect__ ( value , expected , doctest , last_expr , expected_expr , module , file , line ) do
454455 result =
455456 try do
456457 inspect ( value , safe: false )
@@ -470,12 +471,12 @@ defmodule ExUnit.DocTest do
470471 { extra , stack } ->
471472 expr = "inspect(#{ last_expr } ) === #{ String . trim ( expected_expr ) } "
472473 error = [ doctest: doctest , expr: expr ] ++ extra
473- reraise ExUnit.AssertionError , error , stack ++ parent_stack
474+ reraise ExUnit.AssertionError , error , stack ++ stack ( module , file , line )
474475 end
475476 end
476477
477478 @ doc false
478- def __error__ ( fun , message , exception , doctest , stack ) do
479+ def __error__ ( fun , message , exception , doctest , module , file , line ) do
479480 try do
480481 fun . ( )
481482 rescue
@@ -500,24 +501,24 @@ defmodule ExUnit.DocTest do
500501 end
501502
502503 if failed do
503- reraise ExUnit.AssertionError , [ message: failed , doctest: doctest ] , stack
504+ reraise ExUnit.AssertionError ,
505+ [ message: failed , doctest: doctest ] ,
506+ stack ( module , file , line )
504507 end
505508 else
506509 _ ->
507510 failed = "Doctest failed: expected exception #{ inspect ( exception ) } but nothing was raised"
508511 error = [ message: failed , doctest: doctest ]
509- reraise ExUnit.AssertionError , error , stack
512+ reraise ExUnit.AssertionError , error , stack ( module , file , line )
510513 end
511514 end
512515
513516 defp test_import ( _mod , false ) , do: [ ]
514517 defp test_import ( mod , _ ) , do: [ quote ( do: import ( unquote ( mod ) ) ) ]
515518
516- defp string_to_quoted ( location , stack , expr , doctest ) do
517- expr = IO . iodata_to_binary ( expr )
518-
519+ defp string_to_quoted ( module , file , line , expr , doctest ) when is_binary ( expr ) do
519520 try do
520- Code . string_to_quoted! ( expr , location )
521+ Code . string_to_quoted! ( expr , file: file , line: line )
521522 rescue
522523 e ->
523524 ex_message = "(#{ inspect ( e . __struct__ ) } ) #{ Exception . message ( e ) } "
@@ -544,11 +545,18 @@ defmodule ExUnit.DocTest do
544545 end
545546
546547 quote do
547- reraise ExUnit.AssertionError , unquote ( opts ) , unquote ( stack )
548+ reraise ExUnit.AssertionError ,
549+ unquote ( opts ) ,
550+ unquote ( Macro . escape ( stack ( module , file , line ) ) )
548551 end
549552 end
550553 end
551554
555+ defp stack ( module , file , line ) do
556+ location = [ line: line , file: Path . relative_to_cwd ( file ) ]
557+ [ { module , :__MODULE__ , 0 , location } ]
558+ end
559+
552560 ## Extraction of the tests
553561
554562 defp extract ( module ) do
@@ -743,38 +751,36 @@ defmodule ExUnit.DocTest do
743751 |> Enum . map ( & build_test ( & 1 , fun_arity ) )
744752 end
745753
746- defp build_test ( [ { _ , line_no } | _ ] = lines , fun_arity ) do
747- exprs = build_test ( lines , [ ] , [ ] , [ ] , [ ] )
754+ defp build_test ( [ { "iex>" <> string = line , line_no } | lines ] , fun_arity ) do
755+ exprs = build_test ( lines , [ string ] , [ ] , [ line ] , [ ] , line_no )
748756 % { line: line_no , exprs: Enum . reverse ( exprs ) , fun_arity: fun_arity }
749757 end
750758
751- defp build_test ( [ ] , [ _ | _ ] = expr , expected , formatted , acc ) do
752- add_expr ( acc , expr , expected , formatted )
753- end
754-
755- # Tidy up the previous expression before starting a new one.
759+ # Started a new expression.
756760 defp build_test (
757- [ { "iex>" <> _ , _ } | _ ] = list ,
761+ [ { "iex>" <> _ , new_line_no } | _ ] = list ,
758762 [ _ | _ ] = expr ,
759763 [ _ | _ ] = expected ,
760764 formatted ,
761- acc
765+ acc ,
766+ line_no
762767 ) do
763- acc = add_expr ( acc , expr , expected , formatted )
764- build_test ( list , [ ] , [ ] , [ ] , acc )
768+ acc = add_expr ( acc , expr , expected , formatted , line_no )
769+ build_test ( list , [ ] , [ ] , [ ] , acc , new_line_no )
765770 end
766771
767- # We start a new expression.
772+ # Continuation of an expression.
768773 defp build_test (
769774 [ { "iex>" <> string = line , _ } | lines ] ,
770775 expr ,
771776 expected ,
772777 formatted ,
773- acc
778+ acc ,
779+ line_no
774780 ) do
775781 expr = add_line ( expr , string )
776782 formatted = add_line ( formatted , line )
777- build_test ( lines , expr , expected , formatted , acc )
783+ build_test ( lines , expr , expected , formatted , acc , line_no )
778784 end
779785
780786 # Continuation of an expression.
@@ -783,25 +789,40 @@ defmodule ExUnit.DocTest do
783789 expr ,
784790 expected ,
785791 formatted ,
786- acc
792+ acc ,
793+ line_no
787794 ) do
788795 expr = add_line ( expr , string )
789796 formatted = add_line ( formatted , line )
790- build_test ( lines , expr , expected , formatted , acc )
797+ build_test ( lines , expr , expected , formatted , acc , line_no )
791798 end
792799
793- # Otherwise, it is expected lines.
794- defp build_test ( [ { line , _ } | lines ] , expr , expected , formatted , acc ) do
795- build_test ( lines , expr , add_line ( expected , line ) , formatted , acc )
800+ # Expected lines.
801+ defp build_test ( [ { line , _ } | lines ] , expr , expected , formatted , acc , line_no ) do
802+ build_test ( lines , expr , add_line ( expected , line ) , formatted , acc , line_no )
803+ end
804+
805+ # We are done.
806+ defp build_test ( [ ] , [ _ | _ ] = expr , expected , formatted , acc , line_no ) do
807+ add_expr ( acc , expr , expected , formatted , line_no )
796808 end
797809
798810 defp add_line ( [ ] , line ) , do: [ line ]
799811 defp add_line ( acc , line ) , do: [ acc , [ ?\n , line ] ]
800812
801- defp add_expr ( exprs , expr_lines , expected_lines , formatted_lines ) do
813+ defp add_expr ( exprs , expr_lines , expected_lines , formatted_lines , line_no ) do
802814 expected = IO . iodata_to_binary ( expected_lines )
803815 doctest = IO . iodata_to_binary ( [ ?\n , formatted_lines , ?\n , expected ] )
804- [ { expr_lines , tag_expected ( expected ) , doctest } | exprs ]
816+
817+ expr = % {
818+ expr: IO . iodata_to_binary ( expr_lines ) ,
819+ expr_line: line_no ,
820+ expected: tag_expected ( expected ) ,
821+ expected_line: line_no + length ( expr_lines ) ,
822+ doctest: doctest
823+ }
824+
825+ [ expr | exprs ]
805826 end
806827
807828 defp tag_expected ( expected ) do
0 commit comments