1010defmodule Module.Types.DescrTest do
1111 use ExUnit.Case , async: true
1212
13- import Module.Types.Descr
13+ import Module.Types.Descr , except: [ fun: 1 ]
1414
1515 describe "union" do
1616 test "bitmap" do
@@ -111,7 +111,7 @@ defmodule Module.Types.DescrTest do
111111
112112 test "fun" do
113113 assert equal? ( union ( fun ( ) , fun ( ) ) , fun ( ) )
114- assert equal? ( union ( fun ( ) , fun ( 1 ) ) , fun ( ) )
114+ assert equal? ( union ( fun ( ) , none_fun ( 1 ) ) , fun ( ) )
115115
116116 dynamic_fun = intersection ( fun ( ) , dynamic ( ) )
117117 assert equal? ( union ( dynamic_fun , fun ( ) ) , fun ( ) )
@@ -335,7 +335,7 @@ defmodule Module.Types.DescrTest do
335335 end
336336
337337 test "function" do
338- assert not empty? ( intersection ( negation ( fun ( 2 ) ) , negation ( fun ( 3 ) ) ) )
338+ assert not empty? ( intersection ( negation ( none_fun ( 2 ) ) , negation ( none_fun ( 3 ) ) ) )
339339 end
340340 end
341341
@@ -528,19 +528,19 @@ defmodule Module.Types.DescrTest do
528528
529529 test "fun" do
530530 for arity <- [ 0 , 1 , 2 , 3 ] do
531- assert empty? ( difference ( fun ( arity ) , fun ( arity ) ) )
531+ assert empty? ( difference ( none_fun ( arity ) , none_fun ( arity ) ) )
532532 end
533533
534534 assert empty? ( difference ( fun ( ) , fun ( ) ) )
535- assert empty? ( difference ( fun ( 3 ) , fun ( ) ) )
536- refute empty? ( difference ( fun ( ) , fun ( 1 ) ) )
537- refute empty? ( difference ( fun ( 2 ) , fun ( 3 ) ) )
538- assert empty? ( intersection ( fun ( 2 ) , fun ( 3 ) ) )
535+ assert empty? ( difference ( none_fun ( 3 ) , fun ( ) ) )
536+ refute empty? ( difference ( fun ( ) , none_fun ( 1 ) ) )
537+ refute empty? ( difference ( none_fun ( 2 ) , none_fun ( 3 ) ) )
538+ assert empty? ( intersection ( none_fun ( 2 ) , none_fun ( 3 ) ) )
539539
540- f1f2 = union ( fun ( 1 ) , fun ( 2 ) )
541- assert f1f2 |> difference ( fun ( 1 ) ) |> difference ( fun ( 2 ) ) |> empty? ( )
542- assert fun ( 1 ) |> difference ( difference ( f1f2 , fun ( 2 ) ) ) |> empty? ( )
543- assert f1f2 |> difference ( fun ( 1 ) ) |> equal? ( fun ( 2 ) )
540+ f1f2 = union ( none_fun ( 1 ) , none_fun ( 2 ) )
541+ assert f1f2 |> difference ( none_fun ( 1 ) ) |> difference ( none_fun ( 2 ) ) |> empty? ( )
542+ assert none_fun ( 1 ) |> difference ( difference ( f1f2 , none_fun ( 2 ) ) ) |> empty? ( )
543+ assert f1f2 |> difference ( none_fun ( 1 ) ) |> equal? ( none_fun ( 2 ) )
544544
545545 assert fun ( [ integer ( ) ] , term ( ) ) |> difference ( fun ( [ none ( ) ] , term ( ) ) ) |> empty? ( )
546546 end
@@ -742,25 +742,27 @@ defmodule Module.Types.DescrTest do
742742
743743 test "fun" do
744744 refute empty? ( fun ( ) )
745- refute empty? ( fun ( 1 ) )
745+ refute empty? ( none_fun ( 1 ) )
746746 refute empty? ( fun ( [ integer ( ) ] , atom ( ) ) )
747747
748- assert empty? ( intersection ( fun ( 1 ) , fun ( 2 ) ) )
749- refute empty? ( intersection ( fun ( ) , fun ( 1 ) ) )
750- assert empty? ( difference ( fun ( 1 ) , union ( fun ( 1 ) , fun ( 2 ) ) ) )
748+ assert empty? ( intersection ( none_fun ( 1 ) , none_fun ( 2 ) ) )
749+ refute empty? ( intersection ( fun ( ) , none_fun ( 1 ) ) )
750+ assert empty? ( difference ( none_fun ( 1 ) , union ( none_fun ( 1 ) , none_fun ( 2 ) ) ) )
751751 end
752752 end
753753
754754 describe "function application" do
755+ defp none_fun ( arity ) , do: fun ( List . duplicate ( none ( ) , arity ) , term ( ) )
756+
755757 test "non funs" do
756758 assert fun_apply ( term ( ) , [ integer ( ) ] ) == :badfun
757- assert fun_apply ( union ( integer ( ) , fun ( 1 ) ) , [ integer ( ) ] ) == :badfun
759+ assert fun_apply ( union ( integer ( ) , none_fun ( 1 ) ) , [ integer ( ) ] ) == :badfun
758760 end
759761
760762 test "static" do
761763 # Full static
762- assert fun_apply ( fun ( ) , [ integer ( ) ] ) == { :ok , term ( ) }
763- assert fun_apply ( difference ( fun ( ) , fun ( 2 ) ) , [ integer ( ) ] ) == { :ok , term ( ) }
764+ assert fun_apply ( fun ( ) , [ integer ( ) ] ) == :badarg
765+ assert fun_apply ( difference ( fun ( ) , none_fun ( 2 ) ) , [ integer ( ) ] ) == :badarg
764766
765767 # Basic function application scenarios
766768 assert fun_apply ( fun ( [ integer ( ) ] , atom ( ) ) , [ integer ( ) ] ) == { :ok , atom ( ) }
@@ -776,7 +778,13 @@ defmodule Module.Types.DescrTest do
776778 assert fun_apply ( fun ( [ integer ( ) ] , integer ( ) ) , [ term ( ) , term ( ) ] ) == { :badarity , [ 1 ] }
777779 assert fun_apply ( fun ( [ integer ( ) , atom ( ) ] , boolean ( ) ) , [ integer ( ) ] ) == { :badarity , [ 2 ] }
778780
779- # Function intersection tests - basic
781+ # Function intersection tests (no overlap)
782+ fun0 = intersection ( fun ( [ integer ( ) ] , atom ( ) ) , fun ( [ float ( ) ] , binary ( ) ) )
783+ assert fun_apply ( fun0 , [ integer ( ) ] ) == { :ok , atom ( ) }
784+ assert fun_apply ( fun0 , [ float ( ) ] ) == { :ok , binary ( ) }
785+ assert fun_apply ( fun0 , [ union ( integer ( ) , float ( ) ) ] ) == { :ok , union ( atom ( ) , binary ( ) ) }
786+
787+ # Function intersection tests (overlap)
780788 fun1 = intersection ( fun ( [ integer ( ) ] , atom ( ) ) , fun ( [ number ( ) ] , term ( ) ) )
781789 assert fun_apply ( fun1 , [ integer ( ) ] ) == { :ok , atom ( ) }
782790 assert fun_apply ( fun1 , [ float ( ) ] ) == { :ok , term ( ) }
@@ -816,8 +824,8 @@ defmodule Module.Types.DescrTest do
816824
817825 fun = fun ( [ dynamic ( integer ( ) ) ] , atom ( ) )
818826 assert fun_apply ( fun , [ dynamic ( integer ( ) ) ] ) |> elem ( 1 ) |> equal? ( atom ( ) )
819- assert fun_apply ( fun , [ dynamic ( number ( ) ) ] ) == :badarg
820- assert fun_apply ( fun , [ integer ( ) ] ) == :badarg
827+ assert fun_apply ( fun , [ dynamic ( number ( ) ) ] ) == { :ok , dynamic ( ) }
828+ assert fun_apply ( fun , [ integer ( ) ] ) == { :ok , dynamic ( ) }
821829 assert fun_apply ( fun , [ float ( ) ] ) == :badarg
822830 end
823831
@@ -826,12 +834,13 @@ defmodule Module.Types.DescrTest do
826834 test "dynamic" do
827835 # Full dynamic
828836 assert fun_apply ( dynamic ( ) , [ integer ( ) ] ) == { :ok , dynamic ( ) }
829- assert fun_apply ( difference ( dynamic ( ) , integer ( ) ) , [ integer ( ) ] ) == { :ok , dynamic ( ) }
837+ assert fun_apply ( dynamic ( none_fun ( 1 ) ) , [ integer ( ) ] ) == { :ok , dynamic ( ) }
838+ assert fun_apply ( difference ( dynamic ( ) , none_fun ( 2 ) ) , [ integer ( ) ] ) == { :ok , dynamic ( ) }
830839
831840 # Basic function application scenarios
832841 assert fun_apply ( dynamic_fun ( [ integer ( ) ] , atom ( ) ) , [ integer ( ) ] ) == { :ok , dynamic ( atom ( ) ) }
833- assert fun_apply ( dynamic_fun ( [ integer ( ) ] , atom ( ) ) , [ float ( ) ] ) == :badarg
834- assert fun_apply ( dynamic_fun ( [ integer ( ) ] , atom ( ) ) , [ term ( ) ] ) == :badarg
842+ assert fun_apply ( dynamic_fun ( [ integer ( ) ] , atom ( ) ) , [ float ( ) ] ) == { :ok , dynamic ( ) }
843+ assert fun_apply ( dynamic_fun ( [ integer ( ) ] , atom ( ) ) , [ term ( ) ] ) == { :ok , dynamic ( ) }
835844 assert fun_apply ( dynamic_fun ( [ integer ( ) ] , none ( ) ) , [ integer ( ) ] ) == { :ok , dynamic ( none ( ) ) }
836845 assert fun_apply ( dynamic_fun ( [ integer ( ) ] , term ( ) ) , [ integer ( ) ] ) == { :ok , dynamic ( ) }
837846
@@ -841,7 +850,7 @@ defmodule Module.Types.DescrTest do
841850 fun = dynamic_fun ( [ integer ( ) ] , binary ( ) )
842851 assert fun_apply ( fun , [ integer ( ) ] ) == { :ok , dynamic ( binary ( ) ) }
843852 assert fun_apply ( fun , [ dynamic ( integer ( ) ) ] ) == { :ok , dynamic ( binary ( ) ) }
844- assert fun_apply ( fun , [ dynamic ( atom ( ) ) ] ) == :badarg
853+ assert fun_apply ( fun , [ dynamic ( atom ( ) ) ] ) == { :ok , dynamic ( ) }
845854
846855 # Arity mismatches
847856 assert fun_apply ( dynamic_fun ( [ integer ( ) ] , integer ( ) ) , [ term ( ) , term ( ) ] ) == { :badarity , [ 1 ] }
@@ -916,20 +925,20 @@ defmodule Module.Types.DescrTest do
916925 dynamic_fun ( [ integer ( ) ] , binary ( ) )
917926 )
918927
919- assert fun_args |> fun_apply ( [ atom ( ) ] ) == :badarg
928+ assert fun_args |> fun_apply ( [ atom ( ) ] ) == { :ok , dynamic ( ) }
920929 assert fun_args |> fun_apply ( [ integer ( ) ] ) == :badarg
921930
922931 # Badfun
923932 assert union (
924933 fun ( [ atom ( ) ] , integer ( ) ) ,
925- dynamic_fun ( [ integer ( ) ] , binary ( ) ) |> intersection ( fun ( 2 ) )
934+ dynamic_fun ( [ integer ( ) ] , binary ( ) ) |> intersection ( none_fun ( 2 ) )
926935 )
927936 |> fun_apply ( [ atom ( ) ] )
928937 |> elem ( 1 )
929938 |> equal? ( integer ( ) )
930939
931940 assert union (
932- fun ( [ atom ( ) ] , integer ( ) ) |> intersection ( fun ( 2 ) ) ,
941+ fun ( [ atom ( ) ] , integer ( ) ) |> intersection ( none_fun ( 2 ) ) ,
933942 dynamic_fun ( [ integer ( ) ] , binary ( ) )
934943 )
935944 |> fun_apply ( [ integer ( ) ] ) == { :ok , dynamic ( binary ( ) ) }
@@ -1744,7 +1753,7 @@ defmodule Module.Types.DescrTest do
17441753
17451754 test "function" do
17461755 assert fun ( ) |> to_quoted_string ( ) == "fun()"
1747- assert fun ( 1 ) |> to_quoted_string ( ) == "(none() -> term())"
1756+ assert none_fun ( 1 ) |> to_quoted_string ( ) == "(none() -> term())"
17481757
17491758 assert fun ( [ dynamic ( integer ( ) ) ] , float ( ) ) |> to_quoted_string ( ) ==
17501759 "dynamic((none() -> float())) or (integer() -> float())"
0 commit comments