@@ -346,9 +346,6 @@ defmodule ExUnit.DocTest do
346
346
end
347
347
348
348
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
-
352
349
if multiple_exceptions? ( exprs ) do
353
350
raise Error ,
354
351
line: line ,
@@ -358,11 +355,7 @@ defmodule ExUnit.DocTest do
358
355
"please separate your iex> prompts by multiple newlines to start new examples"
359
356
end
360
357
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 )
366
359
{ :__block__ , [ ] , test_import ( module , do_import ) ++ tests }
367
360
end
368
361
@@ -372,66 +365,74 @@ defmodule ExUnit.DocTest do
372
365
373
366
defp multiple_exceptions? ( exprs ) do
374
367
Enum . count ( exprs , fn
375
- { _ , { :error , _ , _ } , _ } -> true
368
+ % { expected: { :error , _ , _ } } -> true
376
369
_ -> false
377
370
end ) > 1
378
371
end
379
372
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 ( )
382
376
end
383
377
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 )
387
382
last_expr = Macro . to_string ( last_expr ( expr_ast ) )
388
383
389
384
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
+ )
398
395
end
399
396
end
400
397
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 ( )
403
401
last_expr = Macro . to_string ( last_expr ( expr_ast ) )
404
402
405
403
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
+ )
414
414
end
415
415
end
416
416
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 )
419
420
420
421
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
+ )
426
431
end
427
432
end
428
433
429
- defp update_line ( location , lines ) do
430
- Keyword . replace_lazy ( location , :line , & ( & 1 + length ( lines ) ) )
431
- end
432
-
433
434
@ 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
435
436
case value do
436
437
^ expected ->
437
438
{ :ok , value }
@@ -445,12 +446,12 @@ defmodule ExUnit.DocTest do
445
446
right: expected
446
447
]
447
448
448
- reraise ExUnit.AssertionError , error , stack
449
+ reraise ExUnit.AssertionError , error , stack ( module , file , line )
449
450
end
450
451
end
451
452
452
453
@ 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
454
455
result =
455
456
try do
456
457
inspect ( value , safe: false )
@@ -470,12 +471,12 @@ defmodule ExUnit.DocTest do
470
471
{ extra , stack } ->
471
472
expr = "inspect(#{ last_expr } ) === #{ String . trim ( expected_expr ) } "
472
473
error = [ doctest: doctest , expr: expr ] ++ extra
473
- reraise ExUnit.AssertionError , error , stack ++ parent_stack
474
+ reraise ExUnit.AssertionError , error , stack ++ stack ( module , file , line )
474
475
end
475
476
end
476
477
477
478
@ doc false
478
- def __error__ ( fun , message , exception , doctest , stack ) do
479
+ def __error__ ( fun , message , exception , doctest , module , file , line ) do
479
480
try do
480
481
fun . ( )
481
482
rescue
@@ -500,24 +501,24 @@ defmodule ExUnit.DocTest do
500
501
end
501
502
502
503
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 )
504
507
end
505
508
else
506
509
_ ->
507
510
failed = "Doctest failed: expected exception #{ inspect ( exception ) } but nothing was raised"
508
511
error = [ message: failed , doctest: doctest ]
509
- reraise ExUnit.AssertionError , error , stack
512
+ reraise ExUnit.AssertionError , error , stack ( module , file , line )
510
513
end
511
514
end
512
515
513
516
defp test_import ( _mod , false ) , do: [ ]
514
517
defp test_import ( mod , _ ) , do: [ quote ( do: import ( unquote ( mod ) ) ) ]
515
518
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
519
520
try do
520
- Code . string_to_quoted! ( expr , location )
521
+ Code . string_to_quoted! ( expr , file: file , line: line )
521
522
rescue
522
523
e ->
523
524
ex_message = "(#{ inspect ( e . __struct__ ) } ) #{ Exception . message ( e ) } "
@@ -544,11 +545,18 @@ defmodule ExUnit.DocTest do
544
545
end
545
546
546
547
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 ) ) )
548
551
end
549
552
end
550
553
end
551
554
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
+
552
560
## Extraction of the tests
553
561
554
562
defp extract ( module ) do
@@ -743,38 +751,36 @@ defmodule ExUnit.DocTest do
743
751
|> Enum . map ( & build_test ( & 1 , fun_arity ) )
744
752
end
745
753
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 )
748
756
% { line: line_no , exprs: Enum . reverse ( exprs ) , fun_arity: fun_arity }
749
757
end
750
758
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.
756
760
defp build_test (
757
- [ { "iex>" <> _ , _ } | _ ] = list ,
761
+ [ { "iex>" <> _ , new_line_no } | _ ] = list ,
758
762
[ _ | _ ] = expr ,
759
763
[ _ | _ ] = expected ,
760
764
formatted ,
761
- acc
765
+ acc ,
766
+ line_no
762
767
) 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 )
765
770
end
766
771
767
- # We start a new expression.
772
+ # Continuation of an expression.
768
773
defp build_test (
769
774
[ { "iex>" <> string = line , _ } | lines ] ,
770
775
expr ,
771
776
expected ,
772
777
formatted ,
773
- acc
778
+ acc ,
779
+ line_no
774
780
) do
775
781
expr = add_line ( expr , string )
776
782
formatted = add_line ( formatted , line )
777
- build_test ( lines , expr , expected , formatted , acc )
783
+ build_test ( lines , expr , expected , formatted , acc , line_no )
778
784
end
779
785
780
786
# Continuation of an expression.
@@ -783,25 +789,40 @@ defmodule ExUnit.DocTest do
783
789
expr ,
784
790
expected ,
785
791
formatted ,
786
- acc
792
+ acc ,
793
+ line_no
787
794
) do
788
795
expr = add_line ( expr , string )
789
796
formatted = add_line ( formatted , line )
790
- build_test ( lines , expr , expected , formatted , acc )
797
+ build_test ( lines , expr , expected , formatted , acc , line_no )
791
798
end
792
799
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 )
796
808
end
797
809
798
810
defp add_line ( [ ] , line ) , do: [ line ]
799
811
defp add_line ( acc , line ) , do: [ acc , [ ?\n , line ] ]
800
812
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
802
814
expected = IO . iodata_to_binary ( expected_lines )
803
815
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 ]
805
826
end
806
827
807
828
defp tag_expected ( expected ) do
0 commit comments