89
88
XMLDir = proplists:get_value(dir, Options, ?XMLDIR),
90
89
St = #state{verbose = proplists:get_bool(verbose, Options),
92
testsuite = #testsuite{}},
94
93
{start, _Reference} ->
98
97
terminate({ok, _Data}, St) ->
99
TestSuite = St#state.testsuite,
98
TestSuites = St#state.testsuites,
100
99
XmlDir = St#state.xmldir,
101
write_report(TestSuite, XmlDir),
100
write_reports(TestSuites, XmlDir),
103
terminate({error, Reason}, _St) ->
104
io:fwrite("Internal error: ~P.\n", [Reason, 25]),
109
{stop, Reference, ReplyTo} ->
110
ReplyTo ! {result, Reference, Result},
114
handle_begin(group, Data, St) ->
102
terminate({error, _Reason}, _St) ->
103
%% Don't report any errors here, since eunit_tty takes care of that.
107
handle_begin(Kind, Data, St) when Kind == group; Kind == test ->
108
%% Run this code both for groups and tests; test is a bit
109
%% surprising: This is a workaround for the fact that we don't get
110
%% a group (handle_begin(group, ...) for testsuites (modules)
111
%% which only have one test case. In that case we get a test case
112
%% with an id comprised of just one integer - the group id.
115
113
NewId = proplists:get_value(id, Data),
120
118
Desc = proplists:get_value(desc, Data),
121
TestSuite = St#state.testsuite,
122
NewTestSuite = TestSuite#testsuite{name = Desc},
123
St#state{testsuite=NewTestSuite};
119
TestSuite = #testsuite{id = GroupId, name = Desc},
120
St#state{testsuites=store_suite(TestSuite, St#state.testsuites)};
124
121
%% Surefire format is not hierarchic: Ignore subgroups:
128
handle_begin(test, _Data, St) ->
130
125
handle_end(group, Data, St) ->
131
126
%% Retrieve existing test suite:
132
127
case proplists:get_value(id, Data) of
136
TestSuite = St#state.testsuite,
131
TestSuites = St#state.testsuites,
132
TestSuite = lookup_suite_by_group_id(GroupId, TestSuites),
138
134
%% Update TestSuite data:
139
135
Time = proplists:get_value(time, Data),
140
136
Output = proplists:get_value(output, Data),
141
137
NewTestSuite = TestSuite#testsuite{ time = Time, output = Output },
142
St#state{testsuite=NewTestSuite}
138
St#state{testsuites=store_suite(NewTestSuite, TestSuites)}
144
140
handle_end(test, Data, St) ->
145
141
%% Retrieve existing test suite:
146
TestSuite = St#state.testsuite,
142
[GroupId|_] = proplists:get_value(id, Data),
143
TestSuites = St#state.testsuites,
144
TestSuite = lookup_suite_by_group_id(GroupId, TestSuites),
148
146
%% Create test case:
149
147
Name = format_name(proplists:get_value(source, Data),
189
189
format_desc(Desc) when is_list(Desc) ->
192
lookup_suite_by_group_id(GroupId, TestSuites) ->
193
#testsuite{} = lists:keyfind(GroupId, #testsuite.id, TestSuites).
195
store_suite(#testsuite{id=GroupId} = TestSuite, TestSuites) ->
196
lists:keystore(GroupId, #testsuite.id, TestSuites, TestSuite).
192
198
%% Add testcase to testsuite depending on the result of the test.
193
199
add_testcase_to_testsuite(ok, TestCaseTmp, TestSuite) ->
194
200
TestCase = TestCaseTmp#testcase{ result = ok },
220
226
%% Write a report to the XML directory.
221
227
%% This function opens the report file, calls write_report_to/2 and closes the file.
222
228
%% ----------------------------------------------------------------------------
229
write_reports(TestSuites, XmlDir) ->
230
lists:foreach(fun(TestSuite) -> write_report(TestSuite, XmlDir) end,
223
233
write_report(#testsuite{name = Name} = TestSuite, XmlDir) ->
224
234
Filename = filename:join(XmlDir, lists:flatten(["TEST-", escape_suitename(Name)], ".xml")),
225
235
case file:open(Filename, [write, raw]) of
323
331
format_testcase_result(ok) -> [<<>>];
324
332
format_testcase_result({failed, {error, {Type, _}, _} = Exception}) when is_atom(Type) ->
325
333
[?INDENT, ?INDENT, <<"<failure type=\"">>, escape_attr(atom_to_list(Type)), <<"\">">>, ?NEWLINE,
326
<<"::">>, escape_text(eunit_lib:format_exception(Exception)),
334
<<"::">>, escape_text(eunit_lib:format_exception(Exception, 100)),
327
335
?INDENT, ?INDENT, <<"</failure>">>, ?NEWLINE];
328
336
format_testcase_result({failed, Term}) ->
329
337
[?INDENT, ?INDENT, <<"<failure type=\"unknown\">">>, ?NEWLINE,
331
339
?INDENT, ?INDENT, <<"</failure>">>, ?NEWLINE];
332
340
format_testcase_result({aborted, {Class, _Term, _Trace} = Exception}) when is_atom(Class) ->
333
341
[?INDENT, ?INDENT, <<"<error type=\"">>, escape_attr(atom_to_list(Class)), <<"\">">>, ?NEWLINE,
334
<<"::">>, escape_text(eunit_lib:format_exception(Exception)),
342
<<"::">>, escape_text(eunit_lib:format_exception(Exception, 100)),
335
343
?INDENT, ?INDENT, <<"</error>">>, ?NEWLINE];
336
344
format_testcase_result({aborted, Term}) ->
337
345
[?INDENT, ?INDENT, <<"<error type=\"unknown\">">>, ?NEWLINE,