%% %% %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]).