diff options
-rw-r--r-- | lib/dialyzer/test/Makefile | 3 | ||||
-rw-r--r-- | lib/dialyzer/test/typer_SUITE.erl | 158 |
2 files changed, 160 insertions, 1 deletions
diff --git a/lib/dialyzer/test/Makefile b/lib/dialyzer/test/Makefile index 0d8fba438c..43c8a61ce1 100644 --- a/lib/dialyzer/test/Makefile +++ b/lib/dialyzer/test/Makefile @@ -13,7 +13,8 @@ AUXILIARY_FILES=\ file_utils.erl\ dialyzer_SUITE.erl\ abstract_SUITE.erl\ - plt_SUITE.erl + plt_SUITE.erl\ + typer_SUITE.erl # ---------------------------------------------------- # Release directory specification diff --git a/lib/dialyzer/test/typer_SUITE.erl b/lib/dialyzer/test/typer_SUITE.erl new file mode 100644 index 0000000000..da5b961643 --- /dev/null +++ b/lib/dialyzer/test/typer_SUITE.erl @@ -0,0 +1,158 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2017. All Rights Reserved. +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% 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. +%% +%% %CopyrightEnd% +%% +-module(typer_SUITE). + +-export([all/0,suite/0,groups/0,init_per_suite/1,end_per_suite/1, + init_per_group/2,end_per_group/2, + smoke/1]). + +-include_lib("common_test/include/ct.hrl"). + +suite() -> [{ct_hooks,[ts_install_cth]}]. + +all() -> + [smoke]. + +groups() -> + []. + +init_per_suite(Config) -> + OutDir = proplists:get_value(priv_dir, Config), + case dialyzer_common:check_plt(OutDir) of + fail -> {skip, "Plt creation/check failed."}; + ok -> [{dialyzer_options, []}|Config] + end. + +end_per_suite(_Config) -> + ok. + +init_per_group(_GroupName, Config) -> + Config. + +end_per_group(_GroupName, Config) -> + Config. + +smoke(Config) -> + Code = <<"-module(typer_test_module). + -compile([export_all,nowarn_export_all]). + a(L) -> + L ++ [1,2,3].">>, + PrivDir = proplists:get_value(priv_dir, Config), + Src = filename:join(PrivDir, "typer_test_module.erl"), + ok = file:write_file(Src, Code), + Args = "--plt " ++ PrivDir ++ "dialyzer_plt", + Res = ["^$", + "^%% File:", + "^%% ----", + "^-spec a", + "^_OK_"], + run(Config, Args, Src, Res), + ok. + +typer() -> + case os:find_executable("typer") of + false -> + ct:fail("Can't find typer"); + Typer -> + Typer + end. + +%% Runs a command. + +run(Config, Args0, Name, Expect) -> + Args = Args0 ++ " " ++ Name, + Result = run_command(Config, Args), + verify_result(Result, Expect). + +verify_result(Result, Expect) -> + Messages = split(Result, [], []), + io:format("Result: ~p", [Messages]), + io:format("Expected: ~p", [Expect]), + match_messages(Messages, Expect). + +split([$\n|Rest], Current, Lines) -> + split(Rest, [], [lists:reverse(Current)|Lines]); +split([$\r|Rest], Current, Lines) -> + split(Rest, Current, Lines); +split([Char|Rest], Current, Lines) -> + split(Rest, [Char|Current], Lines); +split([], [], Lines) -> + lists:reverse(Lines); +split([], Current, Lines) -> + split([], [], [lists:reverse(Current)|Lines]). + +match_messages([Msg|Rest1], [Regexp|Rest2]) -> + case re:run(Msg, Regexp, [{capture,none}, unicode]) of + match -> + ok; + nomatch -> + io:format("Not matching: ~s\n", [Msg]), + io:format("Regexp : ~s\n", [Regexp]), + ct:fail(message_mismatch) + end, + match_messages(Rest1, Rest2); +match_messages([], [Expect|Rest]) -> + ct:fail({too_few_messages, [Expect|Rest]}); +match_messages([Msg|Rest], []) -> + ct:fail({too_many_messages, [Msg|Rest]}); +match_messages([], []) -> + ok. + +%% Runs the command using os:cmd/1. +%% +%% Returns the output from the command (as a list of characters with +%% embedded newlines). The very last line will indicate the +%% exit status of the command, where _OK_ means zero, and _ERROR_ +%% a non-zero exit status. + +run_command(Config, Args) -> + TmpDir = filename:join(proplists:get_value(priv_dir, Config), "tmp"), + file:make_dir(TmpDir), + {RunFile, Run, Script} = run_command(TmpDir, os:type(), Args), + ok = file:write_file(filename:join(TmpDir, RunFile), + unicode:characters_to_binary(Script)), + io:format("~ts\n", [Script]), + os:cmd(Run). + +run_command(Dir, {win32, _}, Args) -> + BatchFile = filename:join(Dir, "run.bat"), + Run = re:replace(filename:rootname(BatchFile), "/", "\\", + [global,{return,list}]), + Typer = typer(), + {BatchFile, + Run, + ["@echo off\r\n", + "\"",Typer,"\" ",Args, "\r\n", + "if errorlevel 1 echo _ERROR_\r\n", + "if not errorlevel 1 echo _OK_\r\n"]}; +run_command(Dir, {unix, _}, Args) -> + TyperDir = filename:dirname(typer()), + Name = filename:join(Dir, "run"), + {Name, + "/bin/sh " ++ Name, + ["#!/bin/sh\n", + "PATH=\"",TyperDir,":$PATH\"\n", + "typer ",Args,"\n", + "case $? in\n", + " 0) echo '_OK_';;\n", + " *) echo '_ERROR_';;\n", + "esac\n"]}; +run_command(_Dir, Other, _Args) -> + ct:fail("Don't know how to test exit code for ~p", [Other]). |