auser-poolparty 0.2.66 → 0.2.67
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Manifest.txt +83 -41
- data/PostInstall.txt +2 -2
- data/README.txt +1 -2
- data/Rakefile +14 -1
- data/bin/cloud-start +11 -10
- data/bin/{pool-spec → pool-generate} +0 -0
- data/bin/pool-init +3 -3
- data/bin/pool-start +8 -7
- data/bin/server-update-hosts +1 -1
- data/lib/erlang/messenger/ebin/pm_client_rel-0.1.rel +1 -1
- data/lib/erlang/messenger/ebin/pm_master_rel-0.1.rel +1 -1
- data/lib/erlang/messenger/ebin/pm_node_rel-0.1.rel +1 -1
- data/lib/erlang/messenger/include/defines.hrl +7 -3
- data/lib/erlang/messenger/lib/eunit/.svn/all-wcprops +53 -0
- data/lib/erlang/messenger/lib/eunit/.svn/entries +140 -0
- data/lib/erlang/messenger/lib/eunit/.svn/format +1 -0
- data/lib/erlang/messenger/lib/eunit/.svn/prop-base/NOTES.svn-base +5 -0
- data/lib/erlang/messenger/lib/eunit/.svn/text-base/AUTHORS.svn-base +2 -0
- data/lib/erlang/messenger/lib/eunit/.svn/text-base/CHANGELOG.svn-base +14 -0
- data/lib/erlang/messenger/lib/eunit/.svn/text-base/COPYING.svn-base +504 -0
- data/lib/erlang/messenger/lib/eunit/.svn/text-base/NOTES.svn-base +276 -0
- data/lib/erlang/messenger/lib/eunit/.svn/text-base/README.svn-base +3 -0
- data/lib/erlang/messenger/lib/eunit/.svn/text-base/sys.config.svn-base +9 -0
- data/lib/erlang/messenger/lib/eunit/.svn/text-base/vsn.mk.svn-base +1 -0
- data/lib/erlang/messenger/lib/eunit/doc/.svn/all-wcprops +59 -0
- data/lib/erlang/messenger/lib/eunit/doc/.svn/entries +142 -0
- data/lib/erlang/messenger/lib/eunit/doc/.svn/format +1 -0
- data/lib/erlang/messenger/lib/eunit/doc/.svn/prop-base/erlang.png.svn-base +5 -0
- data/lib/erlang/messenger/lib/eunit/doc/.svn/prop-base/eunit.html.svn-base +5 -0
- data/lib/erlang/messenger/lib/eunit/doc/.svn/prop-base/index.html.svn-base +5 -0
- data/lib/erlang/messenger/lib/eunit/doc/.svn/prop-base/modules-frame.html.svn-base +5 -0
- data/lib/erlang/messenger/lib/eunit/doc/.svn/prop-base/overview-summary.html.svn-base +5 -0
- data/lib/erlang/messenger/lib/eunit/doc/.svn/prop-base/packages-frame.html.svn-base +5 -0
- data/lib/erlang/messenger/lib/eunit/doc/.svn/text-base/edoc-info.svn-base +3 -0
- data/lib/erlang/messenger/lib/eunit/doc/.svn/text-base/erlang.png.svn-base +0 -0
- data/lib/erlang/messenger/lib/eunit/doc/.svn/text-base/eunit.html.svn-base +172 -0
- data/lib/erlang/messenger/lib/eunit/doc/.svn/text-base/index.html.svn-base +17 -0
- data/lib/erlang/messenger/lib/eunit/doc/.svn/text-base/modules-frame.html.svn-base +12 -0
- data/lib/erlang/messenger/lib/eunit/doc/.svn/text-base/overview-summary.html.svn-base +984 -0
- data/lib/erlang/messenger/lib/eunit/doc/.svn/text-base/overview.edoc.svn-base +980 -0
- data/lib/erlang/messenger/lib/eunit/doc/.svn/text-base/packages-frame.html.svn-base +11 -0
- data/lib/erlang/messenger/lib/eunit/doc/.svn/text-base/stylesheet.css.svn-base +55 -0
- data/lib/erlang/messenger/lib/eunit/ebin/.svn/all-wcprops +5 -0
- data/lib/erlang/messenger/lib/eunit/ebin/.svn/dir-prop-base +8 -0
- data/lib/erlang/messenger/lib/eunit/ebin/.svn/entries +28 -0
- data/lib/erlang/messenger/lib/eunit/ebin/.svn/format +1 -0
- data/lib/erlang/messenger/lib/eunit/examples/.svn/all-wcprops +23 -0
- data/lib/erlang/messenger/lib/eunit/examples/.svn/entries +66 -0
- data/lib/erlang/messenger/lib/eunit/examples/.svn/format +1 -0
- data/lib/erlang/messenger/lib/eunit/examples/.svn/prop-base/eunit_examples.erl.svn-base +5 -0
- data/lib/erlang/messenger/lib/eunit/examples/.svn/prop-base/fib.erl.svn-base +5 -0
- data/lib/erlang/messenger/lib/eunit/examples/.svn/text-base/eunit_examples.erl.svn-base +339 -0
- data/lib/erlang/messenger/lib/eunit/examples/.svn/text-base/fib.erl.svn-base +19 -0
- data/lib/erlang/messenger/lib/eunit/examples/.svn/text-base/tests.txt.svn-base +1 -0
- data/lib/erlang/messenger/lib/eunit/include/.svn/all-wcprops +11 -0
- data/lib/erlang/messenger/lib/eunit/include/.svn/entries +41 -0
- data/lib/erlang/messenger/lib/eunit/include/.svn/format +1 -0
- data/lib/erlang/messenger/lib/eunit/include/.svn/prop-base/eunit.hrl.svn-base +5 -0
- data/lib/erlang/messenger/lib/eunit/include/.svn/text-base/eunit.hrl.svn-base +313 -0
- data/lib/erlang/messenger/lib/eunit/src/.svn/all-wcprops +113 -0
- data/lib/erlang/messenger/lib/eunit/src/.svn/entries +259 -0
- data/lib/erlang/messenger/lib/eunit/src/.svn/format +1 -0
- data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/autoload.erl.svn-base +5 -0
- data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/code_monitor.erl.svn-base +5 -0
- data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit.erl.svn-base +5 -0
- data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit_autoexport.erl.svn-base +5 -0
- data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit_data.erl.svn-base +5 -0
- data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit_internal.hrl.svn-base +5 -0
- data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit_lib.erl.svn-base +5 -0
- data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit_proc.erl.svn-base +5 -0
- data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit_serial.erl.svn-base +5 -0
- data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit_server.erl.svn-base +5 -0
- data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit_striptests.erl.svn-base +5 -0
- data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit_test.erl.svn-base +5 -0
- data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit_tests.erl.svn-base +5 -0
- data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit_tty.erl.svn-base +5 -0
- data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/file_monitor.erl.svn-base +5 -0
- data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/autoload.erl.svn-base +388 -0
- data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/code_monitor.erl.svn-base +243 -0
- data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit.app.src.svn-base +21 -0
- data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit.appup.src.svn-base +1 -0
- data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit.erl.svn-base +196 -0
- data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit_autoexport.erl.svn-base +102 -0
- data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit_data.erl.svn-base +798 -0
- data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit_internal.hrl.svn-base +48 -0
- data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit_lib.erl.svn-base +682 -0
- data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit_proc.erl.svn-base +552 -0
- data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit_serial.erl.svn-base +157 -0
- data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit_server.erl.svn-base +340 -0
- data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit_striptests.erl.svn-base +64 -0
- data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit_test.erl.svn-base +334 -0
- data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit_tests.erl.svn-base +45 -0
- data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit_tty.erl.svn-base +272 -0
- data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/file_monitor.erl.svn-base +409 -0
- data/lib/erlang/messenger/pm_client_rel-0.1.boot +0 -0
- data/lib/erlang/messenger/pm_client_rel-0.1.script +77 -85
- data/lib/erlang/messenger/pm_master_rel-0.1.boot +0 -0
- data/lib/erlang/messenger/pm_master_rel-0.1.script +78 -85
- data/lib/erlang/messenger/pm_node_rel-0.1.boot +0 -0
- data/lib/erlang/messenger/pm_node_rel-0.1.script +77 -86
- data/lib/erlang/messenger/src/pm_node.erl +46 -9
- data/lib/erlang/messenger/src/utils.erl +7 -1
- data/lib/poolparty.rb +17 -23
- data/lib/poolparty/base_packages/poolparty.rb +1 -1
- data/lib/poolparty/core/string.rb +11 -2
- data/lib/poolparty/helpers/binary.rb +31 -0
- data/lib/poolparty/helpers/console.rb +25 -16
- data/lib/poolparty/helpers/nice_printer.rb +36 -0
- data/lib/poolparty/helpers/optioner.rb +8 -0
- data/lib/poolparty/helpers/provisioner_base.rb +7 -5
- data/lib/poolparty/helpers/provisioners/master.rb +1 -1
- data/lib/poolparty/helpers/provisioners/slave.rb +2 -1
- data/lib/poolparty/modules/cloud_resourcer.rb +1 -1
- data/lib/poolparty/modules/file_writer.rb +12 -1
- data/lib/poolparty/modules/resourcing_dsl.rb +2 -1
- data/lib/poolparty/monitors/base_monitor.rb +3 -0
- data/lib/poolparty/net/remoter.rb +13 -11
- data/lib/poolparty/pool/base.rb +25 -13
- data/lib/poolparty/pool/cloud.rb +32 -10
- data/lib/poolparty/pool/custom_resource.rb +16 -7
- data/lib/poolparty/pool/plugin_model.rb +2 -2
- data/lib/poolparty/pool/pool.rb +2 -2
- data/lib/poolparty/pool/resource.rb +25 -7
- data/lib/poolparty/pool/resources/class_package.rb +3 -2
- data/lib/poolparty/pool/resources/exec.rb +1 -1
- data/lib/poolparty/pool/resources/variable.rb +4 -0
- data/lib/poolparty/version.rb +1 -1
- data/poolparty.gemspec +13 -11
- data/spec/poolparty/core/hash_spec.rb +1 -1
- data/spec/poolparty/core/time_spec.rb +1 -1
- data/spec/poolparty/net/remote_spec.rb +1 -1
- data/spec/poolparty/pool/base_spec.rb +25 -20
- data/spec/poolparty/pool/cloud_spec.rb +50 -3
- data/spec/poolparty/pool/plugin_spec.rb +1 -0
- data/spec/poolparty/pool/resource_spec.rb +4 -3
- data/spec/poolparty/spec_helper.rb +3 -4
- data/tasks/deployment.rake +15 -3
- data/website/index.html +2 -2
- metadata +88 -46
- data/lib/erlang/messenger/Makefile +0 -15
- data/lib/erlang/messenger/lib/eunit/Makefile +0 -28
- data/lib/erlang/messenger/lib/eunit/ebin/autoload.beam +0 -0
- data/lib/erlang/messenger/lib/eunit/ebin/code_monitor.beam +0 -0
- data/lib/erlang/messenger/lib/eunit/ebin/eunit.beam +0 -0
- data/lib/erlang/messenger/lib/eunit/ebin/eunit_autoexport.beam +0 -0
- data/lib/erlang/messenger/lib/eunit/ebin/eunit_data.beam +0 -0
- data/lib/erlang/messenger/lib/eunit/ebin/eunit_lib.beam +0 -0
- data/lib/erlang/messenger/lib/eunit/ebin/eunit_proc.beam +0 -0
- data/lib/erlang/messenger/lib/eunit/ebin/eunit_serial.beam +0 -0
- data/lib/erlang/messenger/lib/eunit/ebin/eunit_server.beam +0 -0
- data/lib/erlang/messenger/lib/eunit/ebin/eunit_striptests.beam +0 -0
- data/lib/erlang/messenger/lib/eunit/ebin/eunit_test.beam +0 -0
- data/lib/erlang/messenger/lib/eunit/ebin/eunit_tests.beam +0 -0
- data/lib/erlang/messenger/lib/eunit/ebin/eunit_tty.beam +0 -0
- data/lib/erlang/messenger/lib/eunit/ebin/file_monitor.beam +0 -0
- data/lib/erlang/messenger/lib/eunit/src/Makefile +0 -46
- data/lib/poolparty/config/allowed_commands.yml +0 -1
- data/lib/poolparty/plugins/git.rb +0 -45
- data/spec/poolparty/plugins/git_spec.rb +0 -40
@@ -0,0 +1,64 @@
|
|
1
|
+
%% This library is free software; you can redistribute it and/or modify
|
2
|
+
%% it under the terms of the GNU Lesser General Public License as
|
3
|
+
%% published by the Free Software Foundation; either version 2 of the
|
4
|
+
%% License, or (at your option) any later version.
|
5
|
+
%%
|
6
|
+
%% This library is distributed in the hope that it will be useful, but
|
7
|
+
%% WITHOUT ANY WARRANTY; without even the implied warranty of
|
8
|
+
%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
9
|
+
%% Lesser General Public License for more details.
|
10
|
+
%%
|
11
|
+
%% You should have received a copy of the GNU Lesser General Public
|
12
|
+
%% License along with this library; if not, write to the Free Software
|
13
|
+
%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
14
|
+
%% USA
|
15
|
+
%%
|
16
|
+
%% $Id:$
|
17
|
+
%%
|
18
|
+
%% @author Richard Carlsson <richardc@it.uu.se>
|
19
|
+
%% @author Eric Merritt <cyberlync@gmail.com>
|
20
|
+
%% @copyright 2006 Richard Carlsson, Eric Merritt
|
21
|
+
%% @private
|
22
|
+
%% @see eunit
|
23
|
+
%% @doc Parse transform for stripping EUnit test functions.
|
24
|
+
|
25
|
+
-module(eunit_striptests).
|
26
|
+
|
27
|
+
-include("eunit_internal.hrl").
|
28
|
+
|
29
|
+
-export([parse_transform/2]).
|
30
|
+
|
31
|
+
parse_transform(Forms, Options) ->
|
32
|
+
TestSuffix = proplists:get_value(eunit_test_suffix, Options,
|
33
|
+
?DEFAULT_TEST_SUFFIX),
|
34
|
+
GeneratorSuffix = proplists:get_value(eunit_generator_suffix,
|
35
|
+
Options,
|
36
|
+
?DEFAULT_GENERATOR_SUFFIX),
|
37
|
+
ExportSuffix = proplists:get_value(eunit_export_suffix, Options,
|
38
|
+
?DEFAULT_EXPORT_SUFFIX),
|
39
|
+
Exports = lists:foldl(fun ({attribute,_,export,Es}, S) ->
|
40
|
+
sets:union(sets:from_list(Es), S);
|
41
|
+
(_F, S) -> S
|
42
|
+
end,
|
43
|
+
sets:new(), Forms),
|
44
|
+
F = fun (Form, Acc) ->
|
45
|
+
form(Form, Acc, Exports, TestSuffix, GeneratorSuffix,
|
46
|
+
ExportSuffix)
|
47
|
+
end,
|
48
|
+
lists:reverse(lists:foldl(F, [], Forms)).
|
49
|
+
|
50
|
+
form({function, _L, Name, 0, _Cs}=Form, Acc, Exports, TestSuffix,
|
51
|
+
GeneratorSuffix, ExportSuffix) ->
|
52
|
+
N = atom_to_list(Name),
|
53
|
+
case not sets:is_element({Name, 0}, Exports)
|
54
|
+
andalso (lists:suffix(TestSuffix, N)
|
55
|
+
orelse lists:suffix(GeneratorSuffix, N)
|
56
|
+
orelse lists:suffix(ExportSuffix, N))
|
57
|
+
of
|
58
|
+
true ->
|
59
|
+
Acc;
|
60
|
+
false ->
|
61
|
+
[Form | Acc]
|
62
|
+
end;
|
63
|
+
form(Form, Acc, _, _, _, _) ->
|
64
|
+
[Form | Acc].
|
@@ -0,0 +1,334 @@
|
|
1
|
+
%% This library is free software; you can redistribute it and/or modify
|
2
|
+
%% it under the terms of the GNU Lesser General Public License as
|
3
|
+
%% published by the Free Software Foundation; either version 2 of the
|
4
|
+
%% License, or (at your option) any later version.
|
5
|
+
%%
|
6
|
+
%% This library is distributed in the hope that it will be useful, but
|
7
|
+
%% WITHOUT ANY WARRANTY; without even the implied warranty of
|
8
|
+
%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
9
|
+
%% Lesser General Public License for more details.
|
10
|
+
%%
|
11
|
+
%% You should have received a copy of the GNU Lesser General Public
|
12
|
+
%% License along with this library; if not, write to the Free Software
|
13
|
+
%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
14
|
+
%% USA
|
15
|
+
%%
|
16
|
+
%% $Id:$
|
17
|
+
%%
|
18
|
+
%% @author Richard Carlsson <richardc@it.uu.se>
|
19
|
+
%% @copyright 2006 Richard Carlsson
|
20
|
+
%% @private
|
21
|
+
%% @see eunit
|
22
|
+
%% @doc Test running functionality
|
23
|
+
|
24
|
+
-module(eunit_test).
|
25
|
+
|
26
|
+
-export([run_testfun/1, function_wrapper/2, enter_context/4,
|
27
|
+
browse_context/2, multi_setup/1]).
|
28
|
+
|
29
|
+
|
30
|
+
-include("eunit.hrl").
|
31
|
+
-include("eunit_internal.hrl").
|
32
|
+
|
33
|
+
|
34
|
+
%% ---------------------------------------------------------------------
|
35
|
+
%% Getting a cleaned up stack trace. (We don't want it to include
|
36
|
+
%% eunit's own internal functions. This complicates self-testing
|
37
|
+
%% somewhat, but you can't have everything.) Note that we assume that
|
38
|
+
%% this particular module is the boundary between eunit and user code.
|
39
|
+
|
40
|
+
get_stacktrace() ->
|
41
|
+
get_stacktrace([]).
|
42
|
+
|
43
|
+
get_stacktrace(Ts) ->
|
44
|
+
eunit_lib:uniq(prune_trace(erlang:get_stacktrace(), Ts)).
|
45
|
+
|
46
|
+
prune_trace([{?MODULE, _, _} | _Rest], Tail) ->
|
47
|
+
Tail;
|
48
|
+
prune_trace([T | Ts], Tail) ->
|
49
|
+
[T | prune_trace(Ts, Tail)];
|
50
|
+
prune_trace([], Tail) ->
|
51
|
+
Tail.
|
52
|
+
|
53
|
+
|
54
|
+
%% ---------------------------------------------------------------------
|
55
|
+
%% Test runner
|
56
|
+
|
57
|
+
%% @spec ((any()) -> any()) -> {ok, Value} | {error, eunit_lib:exception()}
|
58
|
+
%% @throws wrapperError()
|
59
|
+
|
60
|
+
run_testfun(F) ->
|
61
|
+
try
|
62
|
+
F()
|
63
|
+
of Value ->
|
64
|
+
{ok, Value}
|
65
|
+
catch
|
66
|
+
{eunit_internal, Term} ->
|
67
|
+
%% Internally generated: re-throw Term (lose the trace)
|
68
|
+
throw(Term);
|
69
|
+
Class:Reason ->
|
70
|
+
{error, {Class, Reason, get_stacktrace()}}
|
71
|
+
end.
|
72
|
+
|
73
|
+
|
74
|
+
-ifdef(TEST).
|
75
|
+
macro_test_() ->
|
76
|
+
{"macro definitions",
|
77
|
+
[{?LINE, fun () ->
|
78
|
+
{?LINE, F} = ?_test(undefined),
|
79
|
+
{ok, undefined} = run_testfun(F)
|
80
|
+
end},
|
81
|
+
?_test(begin
|
82
|
+
{?LINE, F} = ?_assert(true),
|
83
|
+
{ok, ok} = run_testfun(F)
|
84
|
+
end),
|
85
|
+
?_test(begin
|
86
|
+
{?LINE, F} = ?_assert(false),
|
87
|
+
{error,{error,{assertion_failed,
|
88
|
+
[{module,_},
|
89
|
+
{line,_},
|
90
|
+
{expression,_},
|
91
|
+
{expected,true},
|
92
|
+
{value,false}]},
|
93
|
+
_}}
|
94
|
+
= run_testfun(F)
|
95
|
+
end),
|
96
|
+
?_test(begin
|
97
|
+
{?LINE, F} = ?_assert([]),
|
98
|
+
{error,{error,{assertion_failed,
|
99
|
+
[{module,_},
|
100
|
+
{line,_},
|
101
|
+
{expression,_},
|
102
|
+
{expected,true},
|
103
|
+
{value,{not_a_boolean,[]}}]},
|
104
|
+
_}}
|
105
|
+
= run_testfun(F)
|
106
|
+
end),
|
107
|
+
?_test(begin
|
108
|
+
{?LINE, F} = ?_assertNot(false),
|
109
|
+
{ok, ok} = run_testfun(F)
|
110
|
+
end),
|
111
|
+
?_test(begin
|
112
|
+
{?LINE, F} = ?_assertNot(true),
|
113
|
+
{error,{error,{assertion_failed,
|
114
|
+
[{module,_},
|
115
|
+
{line,_},
|
116
|
+
{expression,_},
|
117
|
+
{expected,true},
|
118
|
+
{value,false}]},
|
119
|
+
_}}
|
120
|
+
= run_testfun(F)
|
121
|
+
end),
|
122
|
+
?_test(begin
|
123
|
+
{?LINE, F} = ?_assertMatch(ok, ok),
|
124
|
+
{ok, ok} = run_testfun(F)
|
125
|
+
end),
|
126
|
+
?_test(begin
|
127
|
+
{?LINE, F} = ?_assertMatch([_], []),
|
128
|
+
{error,{error,{assertMatch_failed,
|
129
|
+
[{module,_},
|
130
|
+
{line,_},
|
131
|
+
{expression,_},
|
132
|
+
{expected,"[ _ ]"},
|
133
|
+
{value,[]}]},
|
134
|
+
_}}
|
135
|
+
= run_testfun(F)
|
136
|
+
end),
|
137
|
+
?_test(begin
|
138
|
+
{?LINE, F} = ?_assertEqual(ok, ok),
|
139
|
+
{ok, ok} = run_testfun(F)
|
140
|
+
end),
|
141
|
+
?_test(begin
|
142
|
+
{?LINE, F} = ?_assertEqual(3, 1+1),
|
143
|
+
{error,{error,{assertEqual_failed,
|
144
|
+
[{module,_},
|
145
|
+
{line,_},
|
146
|
+
{expression,_},
|
147
|
+
{expected,3},
|
148
|
+
{value,2}]},
|
149
|
+
_}}
|
150
|
+
= run_testfun(F)
|
151
|
+
end),
|
152
|
+
?_test(begin
|
153
|
+
{?LINE, F} = ?_assertException(error, badarith,
|
154
|
+
erlang:error(badarith)),
|
155
|
+
{ok, ok} = run_testfun(F)
|
156
|
+
end),
|
157
|
+
?_test(begin
|
158
|
+
{?LINE, F} = ?_assertException(error, badarith, ok),
|
159
|
+
{error,{error,{assertException_failed,
|
160
|
+
[{module,_},
|
161
|
+
{line,_},
|
162
|
+
{expression,_},
|
163
|
+
{expected,_},
|
164
|
+
{unexpected_success,ok}]},
|
165
|
+
_}}
|
166
|
+
= run_testfun(F)
|
167
|
+
end),
|
168
|
+
?_test(begin
|
169
|
+
{?LINE, F} = ?_assertException(error, badarg,
|
170
|
+
erlang:error(badarith)),
|
171
|
+
{error,{error,{assertException_failed,
|
172
|
+
[{module,_},
|
173
|
+
{line,_},
|
174
|
+
{expression,_},
|
175
|
+
{expected,_},
|
176
|
+
{unexpected_exception,
|
177
|
+
{error,badarith,_}}]},
|
178
|
+
_}}
|
179
|
+
= run_testfun(F)
|
180
|
+
end)
|
181
|
+
]}.
|
182
|
+
-endif.
|
183
|
+
|
184
|
+
|
185
|
+
%% ---------------------------------------------------------------------
|
186
|
+
%% Wrapper for simple "named function" tests ({M,F}), which provides
|
187
|
+
%% better error reporting when the function is missing at test time.
|
188
|
+
%%
|
189
|
+
%% Note that the wrapper fun is usually called by run_testfun/1, and the
|
190
|
+
%% special exceptions thrown here are expected to be handled there.
|
191
|
+
%%
|
192
|
+
%% @throws {eunit_internal, wrapperError()}
|
193
|
+
%%
|
194
|
+
%% @type wrapperError() = {no_such_function, mfa()}
|
195
|
+
%% | {module_not_found, moduleName()}
|
196
|
+
|
197
|
+
function_wrapper(M, F) ->
|
198
|
+
fun () ->
|
199
|
+
try M:F()
|
200
|
+
catch
|
201
|
+
error:undef ->
|
202
|
+
%% Check if it was M:F/0 that was undefined
|
203
|
+
case erlang:module_loaded(M) of
|
204
|
+
false ->
|
205
|
+
fail({module_not_found, M});
|
206
|
+
true ->
|
207
|
+
case erlang:function_exported(M, F, 0) of
|
208
|
+
false ->
|
209
|
+
fail({no_such_function, {M,F,0}});
|
210
|
+
true ->
|
211
|
+
rethrow(error, undef, [{M,F,0}])
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end.
|
216
|
+
|
217
|
+
rethrow(Class, Reason, Trace) ->
|
218
|
+
erlang:raise(Class, Reason, get_stacktrace(Trace)).
|
219
|
+
|
220
|
+
fail(Term) ->
|
221
|
+
throw({eunit_internal, Term}).
|
222
|
+
|
223
|
+
|
224
|
+
-ifdef(TEST).
|
225
|
+
wrapper_test_() ->
|
226
|
+
{"error handling in function wrapper",
|
227
|
+
[?_assertException(throw, {module_not_found, eunit_nonexisting},
|
228
|
+
run_testfun(function_wrapper(eunit_nonexisting,test))),
|
229
|
+
?_assertException(throw,
|
230
|
+
{no_such_function, {?MODULE,nonexisting_test,0}},
|
231
|
+
run_testfun(function_wrapper(?MODULE,nonexisting_test))),
|
232
|
+
?_test({error, {error, undef, _T}}
|
233
|
+
= run_testfun(function_wrapper(?MODULE,wrapper_test_exported_)))
|
234
|
+
]}.
|
235
|
+
|
236
|
+
%% this must be exported (done automatically by the autoexport transform)
|
237
|
+
wrapper_test_exported_() ->
|
238
|
+
{ok, ?MODULE:nonexisting_function()}.
|
239
|
+
-endif.
|
240
|
+
|
241
|
+
|
242
|
+
%% ---------------------------------------------------------------------
|
243
|
+
%% Entering a setup-context, with guaranteed cleanup.
|
244
|
+
|
245
|
+
%% @spec (Setup, Cleanup, Instantiate, Callback) -> any()
|
246
|
+
%% Setup = () -> any()
|
247
|
+
%% Cleanup = (any()) -> any()
|
248
|
+
%% Instantiate = (any()) -> tests()
|
249
|
+
%% Callback = (tests()) -> any()
|
250
|
+
%% @throws {context_error, Error, eunit_lib:exception()}
|
251
|
+
%% Error = setup_failed | instantiation_failed | cleanup_failed
|
252
|
+
|
253
|
+
enter_context(Setup, Cleanup, Instantiate, Callback) ->
|
254
|
+
try Setup() of
|
255
|
+
R ->
|
256
|
+
try Instantiate(R) of
|
257
|
+
T ->
|
258
|
+
try Callback(T) %% call back to client code
|
259
|
+
after
|
260
|
+
%% Always run cleanup; client may be an idiot
|
261
|
+
try Cleanup(R)
|
262
|
+
catch
|
263
|
+
Class:Term ->
|
264
|
+
context_error(cleanup_failed, Class, Term)
|
265
|
+
end
|
266
|
+
end
|
267
|
+
catch
|
268
|
+
Class:Term ->
|
269
|
+
context_error(instantiation_failed, Class, Term)
|
270
|
+
end
|
271
|
+
catch
|
272
|
+
Class:Term ->
|
273
|
+
context_error(setup_failed, Class, Term)
|
274
|
+
end.
|
275
|
+
|
276
|
+
context_error(Type, Class, Term) ->
|
277
|
+
throw({context_error, Type, {Class, Term, get_stacktrace()}}).
|
278
|
+
|
279
|
+
%% Instantiates a context with dummy values to make browsing possible
|
280
|
+
%% @throws {context_error, instantiation_failed, eunit_lib:exception()}
|
281
|
+
|
282
|
+
browse_context(I, F) ->
|
283
|
+
%% Browse: dummy setup/cleanup and a wrapper for the instantiator
|
284
|
+
I1 = fun (_) ->
|
285
|
+
try eunit_lib:browse_fun(I) of
|
286
|
+
{_, T} -> T
|
287
|
+
catch
|
288
|
+
Class:Term ->
|
289
|
+
context_error(instantiation_failed, Class, Term)
|
290
|
+
end
|
291
|
+
end,
|
292
|
+
enter_context(fun ok/0, fun ok/1, I1, F).
|
293
|
+
|
294
|
+
ok() -> ok.
|
295
|
+
ok(_) -> ok.
|
296
|
+
|
297
|
+
%% This generates single setup/cleanup functions from a list of tuples
|
298
|
+
%% on the form {Tag, Setup, Cleanup}, where the setup function always
|
299
|
+
%% backs out correctly from partial completion.
|
300
|
+
|
301
|
+
multi_setup(List) ->
|
302
|
+
{SetupAll, CleanupAll} = multi_setup(List, fun ok/1),
|
303
|
+
%% must reverse back and forth here in order to present the list in
|
304
|
+
%% "natural" order to the test instantiation function
|
305
|
+
{fun () -> lists:reverse(SetupAll([])) end,
|
306
|
+
fun (Rs) -> CleanupAll(lists:reverse(Rs)) end}.
|
307
|
+
|
308
|
+
multi_setup([{Tag, S, C} | Es], CleanupPrev) ->
|
309
|
+
Cleanup = fun ([R | Rs]) ->
|
310
|
+
try C(R) of
|
311
|
+
_ -> CleanupPrev(Rs)
|
312
|
+
catch
|
313
|
+
Class:Term ->
|
314
|
+
throw({Tag, {Class, Term,
|
315
|
+
eunit_test:get_stacktrace()}})
|
316
|
+
end
|
317
|
+
end,
|
318
|
+
{SetupRest, CleanupAll} = multi_setup(Es, Cleanup),
|
319
|
+
{fun (Rs) ->
|
320
|
+
try S() of
|
321
|
+
R ->
|
322
|
+
SetupRest([R|Rs])
|
323
|
+
catch
|
324
|
+
Class:Term ->
|
325
|
+
CleanupPrev(Rs),
|
326
|
+
throw({Tag, {Class, Term,
|
327
|
+
eunit_test:get_stacktrace()}})
|
328
|
+
end
|
329
|
+
end,
|
330
|
+
CleanupAll};
|
331
|
+
multi_setup([{Tag, S} | Es], CleanupPrev) ->
|
332
|
+
multi_setup([{Tag, S, fun ok/1} | Es], CleanupPrev);
|
333
|
+
multi_setup([], CleanupAll) ->
|
334
|
+
{fun (Rs) -> Rs end, CleanupAll}.
|
@@ -0,0 +1,45 @@
|
|
1
|
+
%% This library is free software; you can redistribute it and/or modify
|
2
|
+
%% it under the terms of the GNU Lesser General Public License as
|
3
|
+
%% published by the Free Software Foundation; either version 2 of the
|
4
|
+
%% License, or (at your option) any later version.
|
5
|
+
%%
|
6
|
+
%% This library is distributed in the hope that it will be useful, but
|
7
|
+
%% WITHOUT ANY WARRANTY; without even the implied warranty of
|
8
|
+
%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
9
|
+
%% Lesser General Public License for more details.
|
10
|
+
%%
|
11
|
+
%% You should have received a copy of the GNU Lesser General Public
|
12
|
+
%% License along with this library; if not, write to the Free Software
|
13
|
+
%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
14
|
+
%% USA
|
15
|
+
%%
|
16
|
+
%% $Id:$
|
17
|
+
%%
|
18
|
+
%% @author Richard Carlsson <richard@it.uu.se>
|
19
|
+
%% @copyright 2007 Richard Carlsson
|
20
|
+
%% @private
|
21
|
+
%% @see eunit
|
22
|
+
%% @doc External tests for eunit.erl
|
23
|
+
|
24
|
+
-module(eunit_tests).
|
25
|
+
|
26
|
+
-include("eunit.hrl").
|
27
|
+
|
28
|
+
-ifdef(TEST).
|
29
|
+
%% Cause all the other modules to be tested as well as this one.
|
30
|
+
full_test_() ->
|
31
|
+
%%{application, eunit}. % this currently causes a loop
|
32
|
+
%% We use the below until loop detection is implemented
|
33
|
+
[eunit_autoexport,
|
34
|
+
eunit_striptests,
|
35
|
+
eunit_server,
|
36
|
+
eunit_proc,
|
37
|
+
eunit_serial,
|
38
|
+
eunit_test,
|
39
|
+
eunit_lib,
|
40
|
+
eunit_data,
|
41
|
+
eunit_tty,
|
42
|
+
code_monitor,
|
43
|
+
file_monitor,
|
44
|
+
autoload].
|
45
|
+
-endif.
|
@@ -0,0 +1,272 @@
|
|
1
|
+
%% This library is free software; you can redistribute it and/or modify
|
2
|
+
%% it under the terms of the GNU Lesser General Public License as
|
3
|
+
%% published by the Free Software Foundation; either version 2 of the
|
4
|
+
%% License, or (at your option) any later version.
|
5
|
+
%%
|
6
|
+
%% This library is distributed in the hope that it will be useful, but
|
7
|
+
%% WITHOUT ANY WARRANTY; without even the implied warranty of
|
8
|
+
%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
9
|
+
%% Lesser General Public License for more details.
|
10
|
+
%%
|
11
|
+
%% You should have received a copy of the GNU Lesser General Public
|
12
|
+
%% License along with this library; if not, write to the Free Software
|
13
|
+
%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
14
|
+
%% USA
|
15
|
+
%%
|
16
|
+
%% $Id:$
|
17
|
+
%%
|
18
|
+
%% @author Richard Carlsson <richardc@it.uu.se>
|
19
|
+
%% @copyright 2006 Richard Carlsson
|
20
|
+
%% @private
|
21
|
+
%% @see eunit
|
22
|
+
%% @doc Text-based frontend for EUnit
|
23
|
+
|
24
|
+
-module(eunit_tty).
|
25
|
+
|
26
|
+
-include("eunit.hrl").
|
27
|
+
-include("eunit_internal.hrl").
|
28
|
+
|
29
|
+
-export([start/1, start/2]).
|
30
|
+
|
31
|
+
|
32
|
+
-record(state, {verbose = false,
|
33
|
+
succeed = 0,
|
34
|
+
fail = 0,
|
35
|
+
abort = 0,
|
36
|
+
skip = 0,
|
37
|
+
indent = 0}).
|
38
|
+
|
39
|
+
start(List) ->
|
40
|
+
start(List, []).
|
41
|
+
|
42
|
+
start(List, Options) ->
|
43
|
+
St = #state{verbose = proplists:get_bool(verbose, Options)},
|
44
|
+
Id = [],
|
45
|
+
spawn(fun () -> init(Id, List, St) end).
|
46
|
+
|
47
|
+
init(Id, List, St0) ->
|
48
|
+
receive
|
49
|
+
{start, Reference} ->
|
50
|
+
if St0#state.verbose -> print_header();
|
51
|
+
true -> ok
|
52
|
+
end,
|
53
|
+
St = group_begin(Id, "", List, St0),
|
54
|
+
receive
|
55
|
+
{stop, Reference, ReplyTo} ->
|
56
|
+
Result = if St#state.fail == 0, St#state.abort == 0,
|
57
|
+
St#state.skip == 0 ->
|
58
|
+
ok;
|
59
|
+
true ->
|
60
|
+
error
|
61
|
+
end,
|
62
|
+
report(Result, St),
|
63
|
+
ReplyTo ! {result, Reference, Result},
|
64
|
+
ok
|
65
|
+
end
|
66
|
+
end.
|
67
|
+
|
68
|
+
report(ok, St) ->
|
69
|
+
if St#state.succeed == 0 ->
|
70
|
+
io:fwrite(" There were no tests to run.\n");
|
71
|
+
true ->
|
72
|
+
if St#state.verbose -> print_bar();
|
73
|
+
true -> ok
|
74
|
+
end,
|
75
|
+
if St#state.succeed == 1 ->
|
76
|
+
io:fwrite(" Test successful.\n");
|
77
|
+
true ->
|
78
|
+
io:fwrite(" All ~w tests successful.\n",
|
79
|
+
[St#state.succeed])
|
80
|
+
end
|
81
|
+
end;
|
82
|
+
report(error, St) ->
|
83
|
+
print_bar(),
|
84
|
+
io:fwrite(" Failed: ~w. Aborted: ~w."
|
85
|
+
" Skipped: ~w. Succeeded: ~w.\n",
|
86
|
+
[St#state.fail, St#state.abort,
|
87
|
+
St#state.skip, St#state.succeed]).
|
88
|
+
|
89
|
+
print_header() ->
|
90
|
+
io:fwrite("======================== EUnit "
|
91
|
+
"========================\n").
|
92
|
+
|
93
|
+
print_bar() ->
|
94
|
+
io:fwrite("============================"
|
95
|
+
"===========================\n").
|
96
|
+
|
97
|
+
wait(Id, St) ->
|
98
|
+
receive
|
99
|
+
{status, Id, Data} -> {Data, St}
|
100
|
+
end.
|
101
|
+
|
102
|
+
entry({item, Id, Desc, Test}, St) ->
|
103
|
+
test_begin(Id, Desc, Test, St);
|
104
|
+
entry({group, Id, Desc, Es}, St) ->
|
105
|
+
group_begin(Id, Desc, Es, St).
|
106
|
+
|
107
|
+
tests([E | Es], St) ->
|
108
|
+
tests(Es, entry(E, St));
|
109
|
+
tests([], St) ->
|
110
|
+
St.
|
111
|
+
|
112
|
+
test_begin(Id, Desc, {Module, Name}, St) ->
|
113
|
+
test_begin(Id, Desc, {Module, Name, 0}, St);
|
114
|
+
test_begin(Id, Desc, {Module, Name, Line}, St) ->
|
115
|
+
Text = format_test_begin(Module, Name, Line, Desc),
|
116
|
+
if St#state.verbose -> print_test_begin(St#state.indent, Text);
|
117
|
+
true -> ok
|
118
|
+
end,
|
119
|
+
case wait(Id, St) of
|
120
|
+
{{progress, 'begin', test}, St1} ->
|
121
|
+
test_end(Id, Text, St1);
|
122
|
+
{{cancel, Reason}, St1} ->
|
123
|
+
if St#state.verbose -> print_test_cancel(Reason);
|
124
|
+
Reason /= undefined ->
|
125
|
+
print_test_begin(St#state.indent, Text),
|
126
|
+
print_test_cancel(Reason);
|
127
|
+
true -> ok
|
128
|
+
end,
|
129
|
+
St1#state{skip = St1#state.skip + 1}
|
130
|
+
end.
|
131
|
+
|
132
|
+
test_end(Id, Text, St) ->
|
133
|
+
case wait(Id, St) of
|
134
|
+
{{progress, 'end', {Result, Time, _Output}}, St1} ->
|
135
|
+
if Result == ok ->
|
136
|
+
if St#state.verbose -> print_test_end(Time);
|
137
|
+
true -> ok
|
138
|
+
end,
|
139
|
+
St1#state{succeed = St1#state.succeed + 1};
|
140
|
+
true ->
|
141
|
+
if St#state.verbose -> ok;
|
142
|
+
true -> print_test_begin(St#state.indent, Text)
|
143
|
+
end,
|
144
|
+
print_test_error(Result),
|
145
|
+
St1#state{fail = St1#state.fail + 1}
|
146
|
+
end;
|
147
|
+
{{cancel, Reason}, St1} ->
|
148
|
+
if St#state.verbose -> ok;
|
149
|
+
true -> print_test_begin(St#state.indent, Text)
|
150
|
+
end,
|
151
|
+
print_test_cancel(Reason),
|
152
|
+
St1#state{abort = St1#state.abort + 1}
|
153
|
+
end.
|
154
|
+
|
155
|
+
group_begin(Id, Desc, Es, St0) ->
|
156
|
+
I = St0#state.indent,
|
157
|
+
St = if Desc /= "", St0#state.verbose ->
|
158
|
+
print_group_start(I, Desc),
|
159
|
+
St0#state{indent = I + 1};
|
160
|
+
true ->
|
161
|
+
St0
|
162
|
+
end,
|
163
|
+
case wait(Id, St) of
|
164
|
+
{{progress, 'begin', group}, St1} ->
|
165
|
+
group_end(Id, I, Desc, tests(Es, St1));
|
166
|
+
{{cancel, Reason}, St1} ->
|
167
|
+
if Desc /= "", St1#state.verbose ->
|
168
|
+
print_group_cancel(I, Reason);
|
169
|
+
Desc /= "" ->
|
170
|
+
print_group_start(I, Desc),
|
171
|
+
print_group_cancel(I, Reason);
|
172
|
+
true ->
|
173
|
+
ok
|
174
|
+
end,
|
175
|
+
%% TODO: eliminate this size calculation if possible
|
176
|
+
Size = eunit_data:list_size(Es),
|
177
|
+
St1#state{indent = I, skip = St1#state.skip + Size}
|
178
|
+
end.
|
179
|
+
|
180
|
+
group_end(Id, I, Desc, St) ->
|
181
|
+
(case wait(Id, St) of
|
182
|
+
{{progress, 'end', {_Count, Time, _Output}}, St1} ->
|
183
|
+
if Desc /= "", St#state.verbose ->
|
184
|
+
print_group_end(St1#state.indent, Time);
|
185
|
+
true ->
|
186
|
+
ok
|
187
|
+
end,
|
188
|
+
St1;
|
189
|
+
{{cancel, undefined}, St1} ->
|
190
|
+
St1; %% "skipped" message is not interesting here
|
191
|
+
{{cancel, Reason}, St1} ->
|
192
|
+
if Desc /= "", St1#state.verbose ->
|
193
|
+
print_group_cancel(I, Reason);
|
194
|
+
true ->
|
195
|
+
print_group_start(I, Desc),
|
196
|
+
print_group_cancel(I, Reason)
|
197
|
+
end,
|
198
|
+
St1
|
199
|
+
end)#state{indent = I}.
|
200
|
+
|
201
|
+
indent(N) when is_integer(N), N >= 1 ->
|
202
|
+
io:put_chars(lists:duplicate(N * 2, $\s));
|
203
|
+
indent(_) ->
|
204
|
+
ok.
|
205
|
+
|
206
|
+
print_group_start(I, Desc) ->
|
207
|
+
indent(I),
|
208
|
+
io:fwrite("~s\n", [Desc]).
|
209
|
+
|
210
|
+
print_group_end(I, Time) ->
|
211
|
+
if Time > 0 ->
|
212
|
+
indent(I),
|
213
|
+
io:fwrite("[done in ~.3f s]\n", [Time/1000]);
|
214
|
+
true ->
|
215
|
+
ok
|
216
|
+
end.
|
217
|
+
|
218
|
+
format_test_begin(Module, Name, Line, Desc) ->
|
219
|
+
L = if Line == 0 -> "";
|
220
|
+
true -> io_lib:fwrite("~w:", [Line])
|
221
|
+
end,
|
222
|
+
D = if Desc == "" -> "";
|
223
|
+
true -> io_lib:fwrite(" (~s)", [Desc])
|
224
|
+
end,
|
225
|
+
io_lib:fwrite("~s:~s~s~s...", [Module, L, Name, D]).
|
226
|
+
|
227
|
+
print_test_begin(I, Text) ->
|
228
|
+
indent(I),
|
229
|
+
io:put_chars(Text).
|
230
|
+
|
231
|
+
print_test_end(Time) ->
|
232
|
+
T = if Time > 0 -> io_lib:fwrite("[~.3f s] ", [Time/1000]);
|
233
|
+
true -> ""
|
234
|
+
end,
|
235
|
+
io:fwrite("~sok\n", [T]).
|
236
|
+
|
237
|
+
print_test_error({error, Exception}) ->
|
238
|
+
io:fwrite("*failed*\n::~s\n\n",
|
239
|
+
[eunit_lib:format_exception(Exception)]);
|
240
|
+
print_test_error({skipped, Reason}) ->
|
241
|
+
io:fwrite("*did not run*\n::~s\n\n",
|
242
|
+
[format_skipped(Reason)]).
|
243
|
+
|
244
|
+
format_skipped({module_not_found, M}) ->
|
245
|
+
io_lib:format("missing module: ~w", [M]);
|
246
|
+
format_skipped({no_such_function, {M,F,A}}) ->
|
247
|
+
io_lib:format("no such function: ~w:~w/~w", [M,F,A]).
|
248
|
+
|
249
|
+
print_test_cancel(Reason) ->
|
250
|
+
io:fwrite(format_cancel(Reason)).
|
251
|
+
|
252
|
+
print_group_cancel(_I, {blame, _}) ->
|
253
|
+
ok;
|
254
|
+
print_group_cancel(I, Reason) ->
|
255
|
+
indent(I),
|
256
|
+
io:fwrite(format_cancel(Reason)).
|
257
|
+
|
258
|
+
format_cancel(undefined) ->
|
259
|
+
"*skipped*\n";
|
260
|
+
format_cancel(timeout) ->
|
261
|
+
"*timed out*\n";
|
262
|
+
format_cancel({startup, Reason}) ->
|
263
|
+
io_lib:fwrite("*could not start test process*\n::~P\n\n",
|
264
|
+
[Reason, 15]);
|
265
|
+
format_cancel({blame, _SubId}) ->
|
266
|
+
"*cancelled because of subtask*\n";
|
267
|
+
format_cancel({exit, Reason}) ->
|
268
|
+
io_lib:fwrite("*unexpected termination of test process*\n::~P\n\n",
|
269
|
+
[Reason, 15]);
|
270
|
+
format_cancel({abort, Reason}) ->
|
271
|
+
eunit_lib:format_error(Reason).
|
272
|
+
|