652
719
%%!============================================================
653
720
%%! Note: The handling of sequences in get_suite/2 and get_all/2
654
%%! is deprecated and should be removed after OTP R13!
721
%%! is deprecated and should be removed at some point...
655
722
%%!============================================================
725
get_suite(Mod, Group={conf,Props,_Init,TCs,_End}) ->
726
Name = proplists:get_value(name, Props),
727
case catch apply(Mod, groups, []) of
730
GroupDefs when is_list(GroupDefs) ->
731
case catch find_groups(Mod, Name, TCs, GroupDefs) of
733
%% this makes test_server call error_in_suite as first
734
%% (and only) test case so we can report Error properly
735
[{?MODULE,error_in_suite,[[Error]]}];
737
{error,{invalid_group_spec,Name}};
739
case lists:member(skipped, Props) of
741
%% a *subgroup* specified *only* as skipped (and not
742
%% as an explicit test) should not be returned, or
743
%% init/end functions for top groups will be executed
744
case catch proplists:get_value(name, element(2, hd(ConfTests))) of
746
delete_subs(ConfTests, ConfTests);
751
delete_subs(ConfTests, ConfTests)
755
E = "Bad return value from "++atom_to_list(Mod)++":groups/0",
756
[{?MODULE,error_in_suite,[[{error,list_to_atom(E)}]]}]
657
760
get_suite(Mod, Name) ->
658
%% Name may be name of a group or a test case. If it's a group,
659
%% it should be expanded to list of cases (in a conf term)
660
case catch apply(Mod, groups, []) of
663
GroupDefs when is_list(GroupDefs) ->
664
case catch check_groups(Mod, GroupDefs) of
666
%% this makes test_server call error_in_suite as first
667
%% (and only) test case so we can report Error properly
668
[{?MODULE,error_in_suite,[[Error]]}];
670
FindConf = fun({conf,Props,_,_,_}) ->
671
case proplists:get_value(name, Props) of
676
case lists:filter(FindConf, ConfTests) of
677
[] -> % must be a test case
763
%%%-----------------------------------------------------------------
765
find_groups(Mod, Name, TCs, GroupDefs) ->
766
Found = find(Mod, Name, TCs, GroupDefs, [], GroupDefs, false),
767
Trimmed = trim(Found),
768
%% I cannot find a reason to why this function is called,
769
%% It deletes any group which is referenced in any other
772
%% [{test, [], [testcase1]},
773
%% {testcases, [], [{group, test}]}].
774
%% Would be changed to
776
%% [{testcases, [], [testcase1]}].
777
%% instead of what I believe is correct:
779
%% [{test, [], [testcase1]},
780
%% {testcases, [], [testcase1]}].
781
%% Have to double check with peppe
782
delete_subs(Trimmed, Trimmed),
785
find(Mod, all, _TCs, [{Name,Props,Tests} | Gs], Known, Defs, _)
786
when is_atom(Name), is_list(Props), is_list(Tests) ->
787
cyclic_test(Mod, Name, Known),
788
[make_conf(Mod, Name, Props,
789
find(Mod, all, all, Tests, [Name | Known], Defs, true)) |
790
find(Mod, all, all, Gs, [], Defs, true)];
792
find(Mod, Name, TCs, [{Name,Props,Tests} | _Gs], Known, Defs, false)
793
when is_atom(Name), is_list(Props), is_list(Tests) ->
794
cyclic_test(Mod, Name, Known),
797
[make_conf(Mod, Name, Props,
798
find(Mod, Name, TCs, Tests, [Name | Known], Defs, true))];
684
E = "Bad return value from "++atom_to_list(Mod)++":groups/0",
685
[{?MODULE,error_in_suite,[[{error,list_to_atom(E)}]]}]
688
check_groups(_Mod, []) ->
690
check_groups(Mod, Defs) ->
691
check_groups(Mod, Defs, Defs, []).
693
check_groups(Mod, [TC | Gs], Defs, Levels) when is_atom(TC), length(Levels)>0 ->
694
[TC | check_groups(Mod, Gs, Defs, Levels)];
696
check_groups(Mod, [{group,SubName} | Gs], Defs, Levels) when is_atom(SubName) ->
697
case lists:member(SubName, Levels) of
699
E = "Cyclic reference to group "++atom_to_list(SubName)++
700
" in "++atom_to_list(Mod)++":groups/0",
701
throw({error,list_to_atom(E)});
703
case find_group(Mod, SubName, Defs) of
707
[check_groups(Mod, [G], Defs, Levels) |
708
check_groups(Mod, Gs, Defs, Levels)]
800
Tests1 = [TC || TC <- TCs,
801
lists:member(TC, Tests) == true],
802
[make_conf(Mod, Name, Props, Tests1)]
712
check_groups(Mod, [{Name,Tests} | Gs], Defs, Levels) when is_atom(Name),
714
check_groups(Mod, [{Name,[],Tests} | Gs], Defs, Levels);
716
check_groups(Mod, [{Name,Props,Tests} | Gs], Defs, Levels) when is_atom(Name),
722
{check_groups(Mod, Tests, Defs, [Name]),[]};
724
{check_groups(Mod, Tests, Defs, [Name|Levels]),Levels}
726
[make_conf(Mod, Name, Props, TestSpec) |
727
check_groups(Mod, Gs, Defs, Levels1)];
729
check_groups(Mod, [BadTerm | _Gs], _Defs, Levels) ->
730
Where = if length(Levels) == 0 ->
805
find(Mod, Name, TCs, [{Name1,Props,Tests} | Gs], Known, Defs, false)
806
when is_atom(Name1), is_list(Props), is_list(Tests) ->
807
cyclic_test(Mod, Name1, Known),
808
[make_conf(Mod,Name1,Props,
809
find(Mod, Name, TCs, Tests, [Name1 | Known], Defs, false)) |
810
find(Mod, Name, TCs, Gs, [], Defs, false)];
812
find(Mod, Name, _TCs, [{Name,_Props,_Tests} | _Gs], _Known, _Defs, true)
813
when is_atom(Name) ->
814
E = "Duplicate groups named "++atom_to_list(Name)++" in "++
815
atom_to_list(Mod)++":groups/0",
816
throw({error,list_to_atom(E)});
818
find(Mod, Name, all, [{Name1,Props,Tests} | Gs], Known, Defs, true)
819
when is_atom(Name1), is_list(Props), is_list(Tests) ->
820
cyclic_test(Mod, Name1, Known),
821
[make_conf(Mod, Name1, Props,
822
find(Mod, Name, all, Tests, [Name1 | Known], Defs, true)) |
823
find(Mod, Name, all, Gs, [], Defs, true)];
825
find(Mod, Name, TCs, [{group,Name1} | Gs], Known, Defs, Found)
826
when is_atom(Name1) ->
827
find(Mod, Name, TCs, [expand(Mod, Name1, Defs) | Gs], Known, Defs, Found);
829
%% Undocumented remote group feature, use with caution
830
find(Mod, Name, TCs, [{group, ExtMod, ExtGrp} | Gs], Known, Defs, true)
831
when is_atom(ExtMod), is_atom(ExtGrp) ->
832
ExternalDefs = ExtMod:groups(),
833
ExternalTCs = find(ExtMod, ExtGrp, TCs, [{group, ExtGrp}],
834
[], ExternalDefs, false),
835
ExternalTCs ++ find(Mod, Name, TCs, Gs, Known, Defs, true);
837
find(Mod, Name, TCs, [{Name1,Tests} | Gs], Known, Defs, Found)
838
when is_atom(Name1), is_list(Tests) ->
839
find(Mod, Name, TCs, [{Name1,[],Tests} | Gs], Known, Defs, Found);
841
find(Mod, Name, TCs, [_TC | Gs], Known, Defs, false) ->
842
find(Mod, Name, TCs, Gs, Known, Defs, false);
844
find(Mod, Name, TCs, [TC | Gs], Known, Defs, true) when is_atom(TC) ->
845
[{Mod, TC} | find(Mod, Name, TCs, Gs, Known, Defs, true)];
847
find(Mod, Name, TCs, [{ExternalTC, Case} = TC | Gs], Known, Defs, true)
848
when is_atom(ExternalTC),
850
[TC | find(Mod, Name, TCs, Gs, Known, Defs, true)];
852
find(Mod, _Name, _TCs, [BadTerm | _Gs], Known, _Defs, _Found) ->
853
Where = if length(Known) == 0 ->
731
854
atom_to_list(Mod)++":groups/0";
733
"group "++atom_to_list(lists:last(Levels))++
856
"group "++atom_to_list(lists:last(Known))++
734
857
" in "++atom_to_list(Mod)++":groups/0"
736
859
Term = io_lib:format("~p", [BadTerm]),
737
860
E = "Bad term "++lists:flatten(Term)++" in "++Where,
738
861
throw({error,list_to_atom(E)});
740
check_groups(_Mod, [], _Defs, _) ->
743
find_group(Mod, Name, Defs) ->
863
find(_Mod, _Name, _TCs, [], _Known, _Defs, false) ->
866
find(_Mod, _Name, _TCs, [], _Known, _Defs, _Found) ->
869
delete_subs([{conf, _,_,_,_} = Conf | Confs], All) ->
870
All1 = delete_conf(Conf, All),
871
case is_sub(Conf, All1) of
873
delete_subs(Confs, All1);
875
delete_subs(Confs, All)
877
delete_subs([_Else | Confs], All) ->
878
delete_subs(Confs, All);
879
delete_subs([], All) ->
882
delete_conf({conf,Props,_,_,_}, Confs) ->
883
Name = proplists:get_value(name, Props),
884
[Conf || Conf = {conf,Props0,_,_,_} <- Confs,
885
Name =/= proplists:get_value(name, Props0)].
887
is_sub({conf,Props,_,_,_}=Conf, [{conf,_,_,Tests,_} | Confs]) ->
888
Name = proplists:get_value(name, Props),
889
case lists:any(fun({conf,Props0,_,_,_}) ->
890
case proplists:get_value(name, Props0) of
902
is_sub(Conf, Tests) or is_sub(Conf, Confs)
905
is_sub(Conf, [_TC | Tests]) ->
911
trim(['$NOMATCH' | Tests]) ->
914
trim([{conf,Props,Init,Tests,End} | Confs]) ->
919
[{conf,Props,Init,Trimmed,End} | trim(Confs)]
922
trim([TC | Tests]) ->
928
cyclic_test(Mod, Name, Names) ->
929
case lists:member(Name, Names) of
931
E = "Cyclic reference to group "++atom_to_list(Name)++
932
" in "++atom_to_list(Mod)++":groups/0",
933
throw({error,list_to_atom(E)});
938
expand(Mod, Name, Defs) ->
744
939
case lists:keysearch(Name, 1, Defs) of