aboutsummaryrefslogtreecommitdiffstats
path: root/lib/stdlib/test/escript_SUITE.erl
diff options
context:
space:
mode:
authorErlang/OTP <otp@erlang.org>2009-11-20 14:54:40 +0000
committerErlang/OTP <otp@erlang.org>2009-11-20 14:54:40 +0000
commit84adefa331c4159d432d22840663c38f155cd4c1 (patch)
treebff9a9c66adda4df2106dfd0e5c053ab182a12bd /lib/stdlib/test/escript_SUITE.erl
downloadotp-84adefa331c4159d432d22840663c38f155cd4c1.tar.gz
otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.bz2
otp-84adefa331c4159d432d22840663c38f155cd4c1.zip
The R13B03 release.OTP_R13B03
Diffstat (limited to 'lib/stdlib/test/escript_SUITE.erl')
-rw-r--r--lib/stdlib/test/escript_SUITE.erl540
1 files changed, 540 insertions, 0 deletions
diff --git a/lib/stdlib/test/escript_SUITE.erl b/lib/stdlib/test/escript_SUITE.erl
new file mode 100644
index 0000000000..70aae54d62
--- /dev/null
+++ b/lib/stdlib/test/escript_SUITE.erl
@@ -0,0 +1,540 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+
+-module(escript_SUITE).
+-export([
+ all/1,
+ init_per_testcase/2,
+ fin_per_testcase/2,
+ basic/1,
+ errors/1,
+ strange_name/1,
+ emulator_flags/1,
+ module_script/1,
+ beam_script/1,
+ archive_script/1,
+ epp/1
+ ]).
+
+-include("test_server.hrl").
+
+all(suite) ->
+ [
+ basic,
+ errors,
+ strange_name,
+ emulator_flags,
+ module_script,
+ beam_script,
+ archive_script,
+ epp
+ ].
+
+init_per_testcase(_Case, Config) ->
+ ?line Dog = ?t:timetrap(?t:minutes(1)),
+ [{watchdog,Dog}|Config].
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+basic(Config) when is_list(Config) ->
+ Data = ?config(data_dir, Config),
+ Dir = filename:absname(Data), %Get rid of trailing slash.
+ ?line run(Dir, "factorial 5",
+ <<"factorial 5 = 120\nExitCode:0">>),
+ ?line run(Dir, "factorial_compile 10",
+ <<"factorial 10 = 3628800\nExitCode:0">>),
+ ?line run(Dir, "factorial_compile_main 7",
+ <<"factorial 7 = 5040\nExitCode:0">>),
+ ?line run(Dir, "factorial_warning 20",
+ [data_dir,<<"factorial_warning:12: Warning: function bar/0 is unused\n"
+ "factorial 20 = 2432902008176640000\nExitCode:0">>]),
+ ?line run(Dir, "-s", "factorial_warning",
+ [data_dir,<<"factorial_warning:12: Warning: function bar/0 is unused\nExitCode:0">>]),
+ ?line run(Dir, "-s -i", "factorial_warning",
+ [data_dir,<<"factorial_warning:12: Warning: function bar/0 is unused\nExitCode:0">>]),
+ ?line run(Dir, "-c -s", "factorial_warning",
+ [data_dir,<<"factorial_warning:12: Warning: function bar/0 is unused\nExitCode:0">>]),
+ ?line run(Dir, "filesize "++filename:join(?config(data_dir, Config),"filesize"),
+ [data_dir,<<"filesize:11: Warning: function id/1 is unused\n324\nExitCode:0">>]),
+ ?line run(Dir, "test_script_name",
+ [data_dir,<<"test_script_name\nExitCode:0">>]),
+ ?line run(Dir, "tail_rec 1000",
+ [<<"ok\nExitCode:0">>]),
+
+ %% We expect the trap_exit flag for the process to be false,
+ %% since that is the default state for newly spawned processes.
+ ?line run(Dir, "trap_exit",
+ <<"false\nExitCode:0">>),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+errors(Config) when is_list(Config) ->
+ Data = ?config(data_dir, Config),
+ Dir = filename:absname(Data), %Get rid of trailing slash.
+ ?line run(Dir, "compile_error",
+ [data_dir,<<"compile_error:5: syntax error before: '*'\n">>,
+ data_dir,<<"compile_error:8: syntax error before: blarf\n">>,
+ <<"escript: There were compilation errors.\nExitCode:127">>]),
+ ?line run(Dir, "lint_error",
+ [data_dir,<<"lint_error:6: function main/1 already defined\n">>,
+ data_dir,"lint_error:8: variable 'ExitCode' is unbound\n",
+ <<"escript: There were compilation errors.\nExitCode:127">>]),
+ ?line run(Dir, "-s", "lint_error",
+ [data_dir,<<"lint_error:6: function main/1 already defined\n">>,
+ data_dir,"lint_error:8: variable 'ExitCode' is unbound\n",
+ <<"escript: There were compilation errors.\nExitCode:127">>]),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+strange_name(Config) when is_list(Config) ->
+ Data = ?config(data_dir, Config),
+ Dir = filename:absname(Data), %Get rid of trailing slash.
+ ?line run(Dir, "strange.name -arg1 arg2 arg3",
+ [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
+ "ExitCode:0">>]),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+emulator_flags(Config) when is_list(Config) ->
+ Data = ?config(data_dir, Config),
+ Dir = filename:absname(Data), %Get rid of trailing slash.
+ ?line run(Dir, "emulator_flags -arg1 arg2 arg3",
+ [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
+ "nostick:[{nostick,[]}]\n"
+ "mnesia:[{mnesia,[\"dir\",\"a/directory\"]},{mnesia,[\"debug\",\"verbose\"]}]\n"
+ "ERL_FLAGS=false\n"
+ "unknown:[]\n"
+ "ExitCode:0">>]),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Pick the source code from the emulator_flags script
+%% Generate a new escript with a module header
+
+module_script(Config) when is_list(Config) ->
+ %% Read orig file
+ Data = ?config(data_dir, Config),
+ OrigFile = filename:join([Data,"emulator_flags"]),
+ {ok, OrigBin} = file:read_file(OrigFile),
+ ?line [Shebang, Mode, Flags | Source] = string:tokens(binary_to_list(OrigBin), "\n"),
+ ?line {ok, OrigFI} = file:read_file_info(OrigFile),
+
+ %% Write source file
+ Priv = ?config(priv_dir, Config),
+ Dir = filename:absname(Priv), % Get rid of trailing slash.
+ Base = "module_script",
+ ErlFile = filename:join([Priv, Base ++ ".erl"]),
+ ErlCode = ["-module(", Base, ").\n",
+ "-export([main/1]).\n\n",
+ string:join(Source, "\n"),
+ "\n"],
+ ?line ok = file:write_file(ErlFile, ErlCode),
+
+ %%%%%%%
+ %% Create and run scripts without emulator flags
+
+ %% With shebang
+ NoArgsBase = Base ++ "_no_args_with_shebang",
+ NoArgsFile = filename:join([Priv, NoArgsBase]),
+ ?line ok = file:write_file(NoArgsFile,
+ [Shebang, "\n",
+ ErlCode]),
+ ?line ok = file:write_file_info(NoArgsFile, OrigFI),
+
+ ?line run(Dir, NoArgsBase ++ " -arg1 arg2 arg3",
+ [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
+ "nostick:[]\n"
+ "mnesia:[]\n"
+ "ERL_FLAGS=false\n"
+ "unknown:[]\n"
+ "ExitCode:0">>]),
+
+ ?line run(Dir, "", NoArgsBase ++ " -arg1 arg2 arg3",
+ [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
+ "nostick:[]\n"
+ "mnesia:[]\n"
+ "ERL_FLAGS=false\n"
+ "unknown:[]\n"
+ "ExitCode:0">>]),
+
+ %% Without shebang
+ NoArgsBase2 = Base ++ "_no_args_without_shebang",
+ NoArgsFile2 = filename:join([Priv, NoArgsBase2]),
+ ?line ok = file:write_file(NoArgsFile2,
+ ["Something else than shebang!!!", "\n",
+ ErlCode]),
+ ?line ok = file:write_file_info(NoArgsFile2, OrigFI),
+
+ ?line run(Dir, "", NoArgsBase2 ++ " -arg1 arg2 arg3",
+ [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
+ "nostick:[]\n"
+ "mnesia:[]\n"
+ "ERL_FLAGS=false\n"
+ "unknown:[]\n"
+ "ExitCode:0">>]),
+
+ %% Plain module without header
+ NoArgsBase3 = Base ++ "_no_args_without_header",
+ NoArgsFile3 = filename:join([Priv, NoArgsBase3]),
+ ?line ok = file:write_file(NoArgsFile3, [ErlCode]),
+ ?line ok = file:write_file_info(NoArgsFile3, OrigFI),
+
+ ?line run(Dir, "", NoArgsBase3 ++ " -arg1 arg2 arg3",
+ [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
+ "nostick:[]\n"
+ "mnesia:[]\n"
+ "ERL_FLAGS=false\n"
+ "unknown:[]\n"
+ "ExitCode:0">>]),
+
+ %%%%%%%
+ %% Create and run scripts with emulator flags
+
+ %% With shebang
+ ArgsBase = Base ++ "_args_with_shebang",
+ ArgsFile = filename:join([Priv, ArgsBase]),
+ ?line ok = file:write_file(ArgsFile,
+ [Shebang, "\n",
+ Mode, "\n",
+ Flags, "\n",
+ ErlCode]),
+ ?line ok = file:write_file_info(ArgsFile, OrigFI),
+
+ ?line run(Dir, ArgsBase ++ " -arg1 arg2 arg3",
+ [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
+ "nostick:[{nostick,[]}]\n"
+ "mnesia:[{mnesia,[\"dir\",\"a/directory\"]},{mnesia,[\"debug\",\"verbose\"]}]\n"
+ "ERL_FLAGS=false\n"
+ "unknown:[]\n"
+ "ExitCode:0">>]),
+
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Pick the source code from the emulator_flags script and compile it.
+%% Generate a new escript containing the beam code and the escript header
+beam_script(Config) when is_list(Config) ->
+ %% Read orig file
+ Data = ?config(data_dir, Config),
+ OrigFile = filename:join([Data,"emulator_flags"]),
+ {ok, OrigBin} = file:read_file(OrigFile),
+ ?line [Shebang, Mode, Flags | Source] = string:tokens(binary_to_list(OrigBin), "\n"),
+ ?line {ok, OrigFI} = file:read_file_info(OrigFile),
+
+ %% Write source file
+ Priv = ?config(priv_dir, Config),
+ Dir = filename:absname(Priv), % Get rid of trailing slash.
+ Base = "beam_script",
+ ErlFile = filename:join([Priv, Base ++ ".erl"]),
+ ?line ok = file:write_file(ErlFile,
+ ["-module(", Base, ").\n",
+ "-export([main/1]).\n\n",
+ string:join(Source, "\n"),
+ "\n"]),
+
+ %% Compile the code
+ ?line {ok, _Mod, BeamCode} = compile:file(ErlFile, [binary]),
+
+ %%%%%%%
+ %% Create and run scripts without emulator flags
+
+ %% With shebang
+ NoArgsBase = Base ++ "_no_args_with_shebang",
+ NoArgsFile = filename:join([Priv, NoArgsBase]),
+ ?line ok = file:write_file(NoArgsFile,
+ [Shebang, "\n",
+ BeamCode]),
+ ?line ok = file:write_file_info(NoArgsFile, OrigFI),
+
+ ?line run(Dir, NoArgsBase ++ " -arg1 arg2 arg3",
+ [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
+ "nostick:[]\n"
+ "mnesia:[]\n"
+ "ERL_FLAGS=false\n"
+ "unknown:[]\n"
+ "ExitCode:0">>]),
+
+ ?line run(Dir, "", NoArgsBase ++ " -arg1 arg2 arg3",
+ [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
+ "nostick:[]\n"
+ "mnesia:[]\n"
+ "ERL_FLAGS=false\n"
+ "unknown:[]\n"
+ "ExitCode:0">>]),
+
+ %% Without shebang
+ NoArgsBase2 = Base ++ "_no_args_without_shebang",
+ NoArgsFile2 = filename:join([Priv, NoArgsBase2]),
+ ?line ok = file:write_file(NoArgsFile2,
+ ["Something else than shebang!!!", "\n",
+ BeamCode]),
+ ?line ok = file:write_file_info(NoArgsFile2, OrigFI),
+
+ ?line run(Dir, "", NoArgsBase2 ++ " -arg1 arg2 arg3",
+ [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
+ "nostick:[]\n"
+ "mnesia:[]\n"
+ "ERL_FLAGS=false\n"
+ "unknown:[]\n"
+ "ExitCode:0">>]),
+
+ %% Plain beam file without header
+ NoArgsBase3 = Base ++ "_no_args_without_header",
+ NoArgsFile3 = filename:join([Priv, NoArgsBase3]),
+ ?line ok = file:write_file(NoArgsFile3, [BeamCode]),
+ ?line ok = file:write_file_info(NoArgsFile3, OrigFI),
+
+ ?line run(Dir, "", NoArgsBase3 ++ " -arg1 arg2 arg3",
+ [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
+ "nostick:[]\n"
+ "mnesia:[]\n"
+ "ERL_FLAGS=false\n"
+ "unknown:[]\n"
+ "ExitCode:0">>]),
+
+ %%%%%%%
+ %% Create and run scripts with emulator flags
+
+ %% With shebang
+ ArgsBase = Base ++ "_args",
+ ArgsFile = filename:join([Priv, ArgsBase]),
+ ?line ok = file:write_file(ArgsFile,
+ [Shebang, "\n",
+ Mode, "\n",
+ Flags, "\n",
+ BeamCode]),
+ ?line ok = file:write_file_info(ArgsFile, OrigFI),
+
+ ?line run(Dir, ArgsBase ++ " -arg1 arg2 arg3",
+ [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
+ "nostick:[{nostick,[]}]\n"
+ "mnesia:[{mnesia,[\"dir\",\"a/directory\"]},{mnesia,[\"debug\",\"verbose\"]}]\n"
+ "ERL_FLAGS=false\n"
+ "unknown:[]\n"
+ "ExitCode:0">>]),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Create an archive file containing two entire applications plus two
+%% alternate main modules. Generate a new escript containing the archive
+%% (with .app and .beam files and ) and the escript header.
+
+archive_script(Config) when is_list(Config) ->
+ %% Copy the orig files to priv_dir
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ Archive = filename:join([PrivDir, "archive_script.zip"]),
+ ?line {ok, _} = zip:create(Archive, ["archive_script"],
+ [{compress, []}, {cwd, DataDir}]),
+ ?line {ok, _} = zip:extract(Archive, [{cwd, PrivDir}]),
+ TopDir = filename:join([PrivDir, "archive_script"]),
+
+ %% Compile the code
+ ?line ok = compile_app(TopDir, "archive_script_dict"),
+ ?line ok = compile_app(TopDir, "archive_script_dummy"),
+ ?line {ok, MainFiles} = file:list_dir(TopDir),
+ ?line ok = compile_files(MainFiles, TopDir, TopDir),
+
+ %% Create the archive
+ {ok, TopFiles} = file:list_dir(TopDir),
+ ?line {ok, {_, ArchiveBin}} = zip:create(Archive, TopFiles,
+ [memory, {compress, []}, {cwd, TopDir}]),
+
+ %% Read the source script
+ OrigFile = filename:join([DataDir, "emulator_flags"]),
+ {ok, OrigBin} = file:read_file(OrigFile),
+ ?line [Shebang, Mode, _Flags | _Source] =
+ string:tokens(binary_to_list(OrigBin), "\n"),
+ Flags = "%%! -archive_script_dict foo bar"
+ " -archive_script_dict foo"
+ " -archive_script_dummy bar",
+ ?line {ok, OrigFI} = file:read_file_info(OrigFile),
+
+ %%%%%%%
+ %% Create and run scripts without emulator flags
+ MainBase = "archive_script_main",
+ MainScript = filename:join([PrivDir, MainBase]),
+
+ %% With shebang
+ ?line ok = file:write_file(MainScript,
+ [Shebang, "\n",
+ Flags, "\n",
+ ArchiveBin]),
+ ?line ok = file:write_file_info(MainScript, OrigFI),
+
+ ?line run(PrivDir, MainBase ++ " -arg1 arg2 arg3",
+ [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
+ "dict:[{archive_script_dict,[\"foo\",\"bar\"]},{archive_script_dict,[\"foo\"]}]\n"
+ "dummy:[{archive_script_dummy,[\"bar\"]}]\n"
+ "priv:{ok,<<\"Some private data...\\n\">>}\n"
+ "ExitCode:0">>]),
+
+ ?line run(PrivDir, "", MainBase ++ " -arg1 arg2 arg3",
+ [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
+ "dict:[{archive_script_dict,[\"foo\",\"bar\"]},{archive_script_dict,[\"foo\"]}]\n"
+ "dummy:[{archive_script_dummy,[\"bar\"]}]\n"
+ "priv:{ok,<<\"Some private data...\\n\">>}\n"
+ "ExitCode:0">>]),
+
+ ?line ok = file:rename(MainScript, MainScript ++ "_with_shebang"),
+
+ %% Without shebang (no flags)
+ ?line ok = file:write_file(MainScript,
+ ["Something else than shebang!!!", "\n",
+ ArchiveBin]),
+ ?line ok = file:write_file_info(MainScript, OrigFI),
+
+ ?line run(PrivDir, "", MainBase ++ " -arg1 arg2 arg3",
+ [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
+ "dict:[]\n"
+ "dummy:[]\n"
+ "priv:{ok,<<\"Some private data...\\n\">>}\n"
+ "ExitCode:0">>]),
+ ?line ok = file:rename(MainScript, MainScript ++ "_without_shebang"),
+
+ %% Plain archive without header (no flags)
+
+ ?line ok = file:write_file(MainScript, [ArchiveBin]),
+ ?line ok = file:write_file_info(MainScript, OrigFI),
+
+ ?line run(PrivDir, "", MainBase ++ " -arg1 arg2 arg3",
+ [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
+ "dict:[]\n"
+ "dummy:[]\n"
+ "priv:{ok,<<\"Some private data...\\n\">>}\n"
+ "ExitCode:0">>]),
+ ?line ok = file:rename(MainScript, MainScript ++ "_without_header"),
+
+ %%%%%%%
+ %% Create and run scripts with emulator flags
+ AltBase = "archive_script_alternate_main",
+ AltScript = filename:join([PrivDir, AltBase]),
+ ?line ok = file:write_file(AltScript,
+ [Shebang, "\n",
+ Mode, "\n",
+ Flags, " -escript main archive_script_main2\n",
+ ArchiveBin]),
+ ?line ok = file:write_file_info(AltScript, OrigFI),
+
+ ?line run(PrivDir, AltBase ++ " -arg1 arg2 arg3",
+ [<<"main2:[\"-arg1\",\"arg2\",\"arg3\"]\n"
+ "dict:[{archive_script_dict,[\"foo\",\"bar\"]},{archive_script_dict,[\"foo\"]}]\n"
+ "dummy:[{archive_script_dummy,[\"bar\"]}]\n"
+ "priv:{ok,<<\"Some private data...\\n\">>}\n"
+ "ExitCode:0">>]),
+
+ ok.
+
+compile_app(TopDir, AppName) ->
+ AppDir = filename:join([TopDir, AppName]),
+ SrcDir = filename:join([AppDir, "src"]),
+ OutDir = filename:join([AppDir, "ebin"]),
+ ?line {ok, Files} = file:list_dir(SrcDir),
+ compile_files(Files, SrcDir, OutDir).
+
+compile_files([File | Files], SrcDir, OutDir) ->
+ case filename:extension(File) of
+ ".erl" ->
+ AbsFile = filename:join([SrcDir, File]),
+ case compile:file(AbsFile, [{outdir, OutDir}]) of
+ {ok, _Mod} ->
+ compile_files(Files, SrcDir, OutDir);
+ Error ->
+ {compilation_error, AbsFile, OutDir, Error}
+ end;
+ _ ->
+ compile_files(Files, SrcDir, OutDir)
+ end;
+compile_files([], _, _) ->
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+epp(Config) when is_list(Config) ->
+ Data = ?config(data_dir, Config),
+ Dir = filename:absname(Data), %Get rid of trailing slash.
+ ?line run(Dir, "factorial_epp 5",
+ <<"factorial 5 = 120\nExitCode:0">>),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+run(Dir, Cmd0, Expected0) ->
+ Expected = iolist_to_binary(expected_output(Expected0, Dir)),
+ Cmd = case os:type() of
+ {win32,_} -> "escript " ++ filename:nativename(Dir) ++ "\\" ++ Cmd0;
+ _ -> Cmd0
+ end,
+ do_run(Dir, Cmd, Expected).
+
+run(Dir, Opts, Cmd0, Expected) ->
+ Cmd = case os:type() of
+ {win32,_} -> "escript " ++ Opts ++ " " ++ filename:nativename(Dir) ++ "\\" ++ Cmd0;
+ _ -> "escript " ++ Opts ++ " " ++ Dir ++ "/" ++ Cmd0
+ end,
+ do_run(Dir, Cmd, Expected).
+
+do_run(Dir, Cmd, Expected0) ->
+ io:format("Run: ~p\n", [Cmd]),
+ Expected = iolist_to_binary(expected_output(Expected0, Dir)),
+
+ Env = [{"PATH",Dir++":"++os:getenv("PATH")}],
+ Port = open_port({spawn,Cmd}, [exit_status,eof,in,{env,Env}]),
+ Res = get_data(Port, []),
+ receive
+ {Port,{exit_status,ExitCode}} ->
+ case iolist_to_binary([Res,"ExitCode:"++integer_to_list(ExitCode)]) of
+ Expected ->
+ ok;
+ Actual ->
+ io:format("Expected: ~p\n", [Expected]),
+ io:format("Actual: ~p\n", [Actual]),
+ ?t:fail()
+ end
+ end.
+
+get_data(Port, SoFar) ->
+ receive
+ {Port,{data,Bytes}} ->
+ get_data(Port, [SoFar|Bytes]);
+ {Port,eof} ->
+ erlang:port_close(Port),
+ SoFar
+ end.
+
+expected_output([data_dir|T], Data) ->
+ Slash = case os:type() of
+ {win32,_} -> "\\";
+ _ -> "/"
+ end,
+ [filename:nativename(Data)++Slash|expected_output(T, Data)];
+expected_output([H|T], Data) ->
+ [H|expected_output(T, Data)];
+expected_output([], _) ->
+ [];
+expected_output(Bin, _) when is_binary(Bin) ->
+ Bin.
+