aboutsummaryrefslogtreecommitdiffstats
path: root/lib/syntax_tools/test/syntax_tools_SUITE.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/syntax_tools/test/syntax_tools_SUITE.erl')
-rw-r--r--lib/syntax_tools/test/syntax_tools_SUITE.erl160
1 files changed, 145 insertions, 15 deletions
diff --git a/lib/syntax_tools/test/syntax_tools_SUITE.erl b/lib/syntax_tools/test/syntax_tools_SUITE.erl
index 43c17e9f1f..e1dd1bd73b 100644
--- a/lib/syntax_tools/test/syntax_tools_SUITE.erl
+++ b/lib/syntax_tools/test/syntax_tools_SUITE.erl
@@ -9,13 +9,11 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
+%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
%% AB. All Rights Reserved.''
-%%
-%% $Id$
-%%
+
-module(syntax_tools_SUITE).
-include_lib("common_test/include/ct.hrl").
@@ -26,15 +24,16 @@
%% Test cases
-export([app_test/1,appup_test/1,smoke_test/1,revert/1,revert_map/1,
- t_abstract_type/1,t_erl_parse_type/1,t_epp_dodger/1,
- t_comment_scan/1,t_igor/1,t_erl_tidy/1]).
+ revert_map_type/1,
+ t_abstract_type/1,t_erl_parse_type/1,t_type/1, t_epp_dodger/1,
+ t_comment_scan/1,t_igor/1,t_erl_tidy/1,t_prettypr/1]).
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [app_test,appup_test,smoke_test,revert,revert_map,
- t_abstract_type,t_erl_parse_type,t_epp_dodger,
- t_comment_scan,t_igor,t_erl_tidy].
+ [app_test,appup_test,smoke_test,revert,revert_map,revert_map_type,
+ t_abstract_type,t_erl_parse_type,t_type,t_epp_dodger,
+ t_comment_scan,t_igor,t_erl_tidy,t_prettypr].
groups() ->
[].
@@ -75,7 +74,7 @@ smoke_test_file(File) ->
[print_error_markers(F, File) || F <- Forms],
ok;
{error,Reason} ->
- io:format("~s: ~p\n", [File,Reason]),
+ io:format("~ts: ~p\n", [File,Reason]),
error
end.
@@ -83,7 +82,7 @@ print_error_markers(F, File) ->
case erl_syntax:type(F) of
error_marker ->
{L,M,Info} = erl_syntax:error_marker_info(F),
- io:format("~ts:~p: ~s", [File,L,M:format_error(Info)]);
+ io:format("~ts:~p: ~ts", [File,L,M:format_error(Info)]);
_ ->
ok
end.
@@ -123,10 +122,97 @@ revert_map(Config) when is_list(Config) ->
{map_field_assoc,{atom,17,name},{var,18,'Value'}}}]),
?t:timetrap_cancel(Dog).
-
+%% Testing bug fix for reverting map_field_assoc in types
+revert_map_type(Config) when is_list(Config) ->
+ Dog = ?t:timetrap(?t:minutes(1)),
+ Form1 = {attribute,4,record,
+ {state,
+ [{typed_record_field,
+ {record_field,5,{atom,5,x}},
+ {type,5,map,
+ [{type,5,map_field_exact,[{atom,5,y},{atom,5,z}]}]}}]}},
+ Mapped1 = erl_syntax_lib:map(fun(X) -> X end, Form1),
+ Form1 = erl_syntax:revert(Mapped1),
+ Form2 = {attribute,4,record,
+ {state,
+ [{typed_record_field,
+ {record_field,5,{atom,5,x}},
+ {type,5,map,
+ [{type,5,map_field_assoc,[{atom,5,y},{atom,5,z}]}]}}]}},
+ Mapped2 = erl_syntax_lib:map(fun(X) -> X end, Form2),
+ Form2 = erl_syntax:revert(Mapped2),
+ ?t:timetrap_cancel(Dog).
%% api tests
+t_type(Config) when is_list(Config) ->
+ F0 = fun validate_basic_type/1,
+ Appl0 = fun(Name) ->
+ Atom = erl_syntax:atom(Name),
+ erl_syntax:type_application(none, Atom, [])
+ end,
+ User0 = fun(Name) ->
+ Atom = erl_syntax:atom(Name),
+ erl_syntax:user_type_application(Atom, [])
+ end,
+ ok = validate(F0,[{"tuple()", erl_syntax:tuple_type()}
+ ,{"{}", erl_syntax:tuple_type([])}
+ ,{"integer()", Appl0(integer)}
+ ,{"foo()", User0(foo)}
+ ,{"map()", erl_syntax:map_type()}
+ ,{"#{}", erl_syntax:map_type([])}
+ ,{"1..2", erl_syntax:integer_range_type
+ (erl_syntax:integer(1), erl_syntax:integer(2))}
+ ,{"<<_:1,_:_*2>>", erl_syntax:bitstring_type
+ (erl_syntax:integer(1), erl_syntax:integer(2))}
+ ,{"fun()", erl_syntax:fun_type()}
+ ]),
+
+ F = fun validate_type/1,
+ ok = validate(F,[{"{}", tuple_type, false}
+ ,{"tuple()", tuple_type, true}
+ ,{"{atom()}", tuple_type, false}
+ ,{"{atom(),integer()}", tuple_type, false}
+ ,{"integer()", type_application, false}
+ ,{"foo()", user_type_application, false}
+ ,{"foo(integer())", user_type_application, false}
+ ,{"module:function()", type_application, false}
+ ,{"map()", map_type, true}
+ ,{"#{}", map_type, false}
+ ,{"#{atom() => integer()}", map_type, false}
+ ,{"#{atom() := integer()}", map_type, false}
+ ,{"#r{}", record_type, false}
+ ,{"#r{a :: integer()}", record_type, false}
+ ,{"[]", type_application, false}
+ ,{"nil()", type_application, false}
+ ,{"[atom()]", type_application, false}
+ ,{"1..2", integer_range_type, false}
+ ,{"<<_:1,_:_*2>>", bitstring_type, false}
+ ,{"fun()", fun_type, true}
+ ,{"integer() | atom()", type_union, false}
+ ,{"A :: fun()", annotated_type, false}
+ ,{"fun((...) -> atom())", function_type, false}
+ ,{"fun((integer()) -> atom())", function_type, false}
+ ,{"V", variable, true}
+ ]),
+ ok.
+
+validate_basic_type({String, Tree}) ->
+ ErlT = string_to_type(String),
+ ErlT = erl_syntax:revert(Tree),
+ ok.
+
+validate_type({String, Type, Leaf}) ->
+ ErlT = string_to_type(String),
+ Type = erl_syntax:type(ErlT),
+ Leaf = erl_syntax:is_leaf(ErlT),
+ Tree = erl_syntax_lib:map(fun(Node) -> Node end, ErlT),
+ Type = erl_syntax:type(Tree),
+ _ = erl_syntax:meta(Tree),
+ RevT = erl_syntax:revert(Tree),
+ Type = erl_syntax:type(RevT),
+ ok.
+
t_abstract_type(Config) when is_list(Config) ->
F = fun validate_abstract_type/1,
ok = validate(F,[{hi,atom},
@@ -139,6 +225,7 @@ t_abstract_type(Config) when is_list(Config) ->
{[$a,$b,$c],string},
{"hello world",string},
{<<1,2,3>>,binary},
+ {<<1,2,3:4>>,binary},
{#{a=>1,"b"=>2},map_expr},
{#{#{i=>1}=>1,"b"=>#{v=>2}},map_expr},
{{a,b,c},tuple}]),
@@ -213,6 +300,14 @@ t_comment_scan(Config) when is_list(Config) ->
ok = test_comment_scan(Filenames,DataDir),
ok.
+t_prettypr(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ Filenames = ["type_specs.erl",
+ "specs_and_funs.erl"],
+ ok = test_prettypr(Filenames,DataDir,PrivDir),
+ ok.
+
test_files(Config) ->
DataDir = ?config(data_dir, Config),
[ filename:join(DataDir,Filename) || Filename <- test_files() ].
@@ -220,7 +315,8 @@ test_files(Config) ->
test_files() ->
["syntax_tools_SUITE_test_module.erl",
"syntax_tools_test.erl",
- "type_specs.erl"].
+ "type_specs.erl",
+ "specs_and_funs.erl"].
t_igor(Config) when is_list(Config) ->
DataDir = ?config(data_dir, Config),
@@ -241,6 +337,12 @@ t_erl_tidy(Config) when is_list(Config) ->
DataDir = ?config(data_dir, Config),
File = filename:join(DataDir,"erl_tidy_tilde.erl"),
ok = erl_tidy:file(File, [{stdout, true}]),
+
+ %% OTP-14471.
+ Old = process_flag(trap_exit, true),
+ NonExisting = filename:join(DataDir,"non_existing_file.erl"),
+ {'EXIT',{error,{0,file,enoent}}} = (catch erl_tidy:file(NonExisting)),
+ true = process_flag(trap_exit, Old),
ok.
test_comment_scan([],_) -> ok;
@@ -260,12 +362,33 @@ test_comment_scan([File|Files],DataDir) ->
end,
Fs1 = erl_recomment:recomment_forms(Fs0, Comments),
Fs2 = erl_syntax_lib:map(Fun, Fs1),
- io:format("File: ~s~n", [Filename]),
+ io:format("File: ~ts~n", [Filename]),
io:put_chars(erl_prettypr:format(Fs2, [{paper, 120},
{ribbon, 110}])),
test_comment_scan(Files,DataDir).
+test_prettypr([],_,_) -> ok;
+test_prettypr([File|Files],DataDir,PrivDir) ->
+ Filename = filename:join(DataDir,File),
+ io:format("Parsing ~p~n", [Filename]),
+ {ok, Fs0} = epp:parse_file(Filename, [], []),
+ Fs = erl_syntax:form_list(Fs0),
+ PP = erl_prettypr:format(Fs, [{paper, 120}, {ribbon, 110}]),
+ io:put_chars(PP),
+ OutFile = filename:join(PrivDir, File),
+ ok = file:write_file(OutFile,unicode:characters_to_binary(PP)),
+ io:format("Parsing OutFile: ~ts~n", [OutFile]),
+ {ok, Fs2} = epp:parse_file(OutFile, [], []),
+ case [Error || {error, _} = Error <- Fs2] of
+ [] ->
+ ok;
+ Errors ->
+ ?t:fail(Errors)
+ end,
+ test_prettypr(Files,DataDir,PrivDir).
+
+
test_epp_dodger([], _, _) -> ok;
test_epp_dodger([Filename|Files],DataDir,PrivDir) ->
io:format("Parsing ~p~n", [Filename]),
@@ -322,7 +445,7 @@ pretty_print_parse_forms([{Fs0,Type}|FsForms],PrivDir,Filename) ->
{Fs2,{CC,CT}} = erl_syntax_lib:mapfold(Comment,{0,0}, Fs1),
io:format("Commented on ~w cases and ~w tries~n", [CC,CT]),
PP = erl_prettypr:format(Fs2),
- ok = file:write_file(OutFile,iolist_to_binary(PP)),
+ ok = file:write_file(OutFile,unicode:characters_to_binary(PP)),
pretty_print_parse_forms(FsForms,PrivDir,Filename).
@@ -426,6 +549,13 @@ string_to_expr(String) ->
{ok,[Expr]} = erl_parse:parse_exprs(Ts),
Expr.
+string_to_type(String) ->
+ io:format("Str: ~p~n", [String]),
+ {ok,Ts,_} = erl_scan:string("-type foo() :: "++String++".", 0),
+ {ok,Form} = erl_parse:parse_form(Ts),
+ {attribute,_,type,{foo,Type,_NoParms=[]}} = Form,
+ Type.
+
p_run(Test, List) ->
N = erlang:system_info(schedulers),