@@ -16,96 +16,219 @@ create or replace type body ut_realtime_reporter is
1616 limitations under the License.
1717 */
1818
19- constructor function ut_realtime_reporter(self in out nocopy ut_realtime_reporter) return self as result is
19+ constructor function ut_realtime_reporter(
20+ self in out nocopy ut_realtime_reporter
21+ ) return self as result is
2022 begin
2123 self.init($$plsql_unit);
24+ total_number_of_tests := 0;
25+ current_test_number := 0;
2226 current_indent := 0;
2327 return;
2428 end;
2529
26- overriding member procedure before_calling_run(self in out nocopy ut_realtime_reporter, a_run in ut_run) is
27- procedure print_test_elements(a_test ut_test) is
30+ overriding member procedure before_calling_run(
31+ self in out nocopy ut_realtime_reporter,
32+ a_run in ut_run
33+ ) is
34+ procedure print_test_elements(
35+ a_test in ut_test
36+ ) is
2837 begin
29- self.print_xml_fragment('<testcase path="' || a_test.path || '"'
30- || ' executable_type="' || a_test.item.executable_type || '"'
31- || ' owner_name="' || a_test.item.owner_name || '"'
32- || ' object_name="' || a_test.item.object_name || '"'
33- || ' procedure_name="' || a_test.item.procedure_name || '"'
34- || ' disabled="' || case when a_test.get_disabled_flag() then 'true' else 'false' end || '"'
35- || ' name="' || a_test.name || '"'
36- || ' description="' || a_test.description || '"/>');
37- end;
38+ total_number_of_tests := total_number_of_tests + 1;
39+ self.print_start_node('test', a_test.path);
40+ self.print_node('executableType', a_test.item.executable_type);
41+ self.print_node('ownerName', a_test.item.owner_name);
42+ self.print_node('objectName', a_test.item.object_name);
43+ self.print_node('procedureName', a_test.item.procedure_name);
44+ self.print_node('disabled', case when a_test.get_disabled_flag() then 'true' else 'false' end);
45+ self.print_node('name', a_test.name);
46+ self.print_node('description', a_test.description);
47+ self.print_node('testNumber', to_char(total_number_of_tests));
48+ self.print_end_node('test');
49+ end print_test_elements;
3850
39- procedure print_suite_elements(a_suite ut_logical_suite) is
51+ procedure print_suite_elements(
52+ a_suite in ut_logical_suite
53+ ) is
4054 begin
41- self.print_xml_fragment('<testsuite path="' || a_suite.path || '"'
42- || ' name="' || a_suite.name || '"'
43- || ' description="' || a_suite.description || '">', 0, 1);
55+ self.print_start_node('suite', a_suite.path);
56+ self.print_node('name', a_suite.name);
57+ self.print_node('description', a_suite.description);
58+ <<suite_elements>>
4459 for i in 1 .. a_suite.items.count loop
4560 if a_suite.items(i) is of(ut_test) then
4661 print_test_elements(treat(a_suite.items(i) as ut_test));
4762 elsif a_suite.items(i) is of(ut_logical_suite) then
4863 print_suite_elements(treat(a_suite.items(i) as ut_logical_suite));
4964 end if;
50- end loop;
51- self.print_xml_fragment('</testsuite>', -1);
52- end;
53-
65+ end loop suite_elements;
66+ self.print_end_node('suite');
67+ end print_suite_elements;
5468 begin
5569 self.print_xml_fragment(ut_utils.get_xml_header(a_run.client_character_set));
56- self.print_xml_fragment('<report>', 0, 1);
57- self.print_xml_fragment('<prolog>', 0, 1);
58- self.print_xml_fragment('<testsuites>', 0, 1);
70+ self.print_start_node('report');
71+ self.print_start_node('preRun');
72+ self.print_start_node('suites');
73+ <<items>>
5974 for i in 1 .. a_run.items.count loop
6075 print_suite_elements(treat(a_run.items(i) as ut_logical_suite));
61- end loop;
62- self.print_xml_fragment('</testsuites>', -1);
63- self.print_xml_fragment('</prolog>', -1);
64- self.print_xml_fragment('<run>', 0, 1);
65- end;
76+ end loop items;
77+ self.print_end_node('suites');
78+ self.print_node('totalNumberOfTests', to_char(total_number_of_tests));
79+ self.print_end_node('preRun');
80+ self.print_start_node('runEvents');
81+ end before_calling_run;
82+
83+ overriding member procedure after_calling_run(
84+ self in out nocopy ut_realtime_reporter,
85+ a_run in ut_run
86+ ) is
87+ begin
88+ self.print_xml_fragment('</runEvents>', -1);
89+ self.print_xml_fragment('</report>', -1);
90+ end after_calling_run;
6691
67- overriding member procedure before_calling_test(self in out nocopy ut_realtime_reporter, a_test in ut_test) as
92+ overriding member procedure before_calling_suite(
93+ self in out nocopy ut_realtime_reporter,
94+ a_suite in ut_logical_suite
95+ ) is
6896 begin
69- self.print_xml_fragment('<test path="' || a_test.path || '"'
70- || ' executable_type="' || a_test.item.executable_type || '"'
71- || ' owner_name="' || a_test.item.owner_name || '"'
72- || ' object_name="' || a_test.item.object_name || '"'
73- || ' procedure_name="' || a_test.item.procedure_name || '"'
74- || ' disabled="' || case when a_test.get_disabled_flag() then 'true' else 'false' end || '"/>', 1, -1);
75- end;
97+ self.print_start_node('startSuiteEvent', a_suite.path);
98+ self.print_end_node('startSuiteEvent');
99+ end before_calling_suite;
100+
101+ overriding member procedure after_calling_suite(
102+ self in out nocopy ut_realtime_reporter,
103+ a_suite in ut_logical_suite
104+ ) is
105+ begin
106+ self.print_start_node('endSuiteEvent', a_suite.path);
107+ self.print_node('startTime', to_char(a_suite.start_time, 'YYYY-MM-DD"T"HH24:MI:SS.FF6'));
108+ self.print_node('endTime', to_char(a_suite.end_time, 'YYYY-MM-DD"T"HH24:MI:SS.FF6'));
109+ self.print_node('executionTime', ut_utils.to_xml_number_format(a_suite.execution_time()));
110+ self.print_start_node('counter');
111+ self.print_node('disabled', to_char(a_suite.results_count.disabled_count));
112+ self.print_node('success', to_char(a_suite.results_count.success_count));
113+ self.print_node('failure', to_char(a_suite.results_count.failure_count));
114+ self.print_node('error', to_char(a_suite.results_count.errored_count));
115+ self.print_node('warning', to_char(a_suite.results_count.warnings_count));
116+ self.print_end_node('counter');
117+ self.print_cdata_node('errorStack', ut_utils.table_to_clob(a_suite.get_error_stack_traces()));
118+ self.print_cdata_node('serverOutput', a_suite.get_serveroutputs());
119+ self.print_end_node('endSuiteEvent');
120+ end after_calling_suite;
121+
122+ overriding member procedure before_calling_test(
123+ self in out nocopy ut_realtime_reporter,
124+ a_test in ut_test
125+ ) is
126+ begin
127+ current_test_number := current_test_number + 1;
128+ self.print_start_node('startTestEvent', a_test.path);
129+ self.print_node('testNumber', to_char(current_test_number));
130+ self.print_node('totalNumberOfTests', to_char(total_number_of_tests));
131+ self.print_end_node('startTestEvent');
132+ end before_calling_test;
76133
77- overriding member procedure after_calling_test(self in out nocopy ut_realtime_reporter, a_test in ut_test) as
134+ overriding member procedure after_calling_test(
135+ self in out nocopy ut_realtime_reporter,
136+ a_test in ut_test
137+ ) is
78138 begin
79- self.print_xml_fragment('');
80- end;
139+ self.print_start_node('endTestEvent', a_test.path);
140+ self.print_node('testNumber', to_char(current_test_number));
141+ self.print_node('totalNumberOfTests', to_char(total_number_of_tests));
142+ self.print_node('startTime', to_char(a_test.start_time, 'YYYY-MM-DD"T"HH24:MI:SS.FF6'));
143+ self.print_node('endTime', to_char(a_test.end_time, 'YYYY-MM-DD"T"HH24:MI:SS.FF6'));
144+ self.print_node('executionTime', ut_utils.to_xml_number_format(a_test.execution_time()));
145+ self.print_start_node('counter');
146+ self.print_node('disabled', to_char(a_test.results_count.disabled_count));
147+ self.print_node('success', to_char(a_test.results_count.success_count));
148+ self.print_node('failure', to_char(a_test.results_count.failure_count));
149+ self.print_node('error', to_char(a_test.results_count.errored_count));
150+ self.print_node('warning', to_char(a_test.results_count.warnings_count));
151+ self.print_end_node('counter');
152+ self.print_cdata_node('errorStack', ut_utils.table_to_clob(a_test.get_error_stack_traces()));
153+ self.print_cdata_node('serverOutput', a_test.get_serveroutputs());
154+ if a_test.failed_expectations.count > 0 then
155+ self.print_start_node('failedExpectations');
156+ <<expectations>>
157+ for i in 1 .. a_test.failed_expectations.count loop
158+ self.print_start_node('expectation');
159+ self.print_node('description', a_test.failed_expectations(i).description);
160+ self.print_cdata_node('message', a_test.failed_expectations(i).message);
161+ self.print_cdata_node('caller', a_test.failed_expectations(i).caller_info);
162+ self.print_end_node('expectation');
163+ end loop expectations;
164+ self.print_end_node('failedExpectations');
165+ end if;
166+ self.print_end_node('endTestEvent');
167+ end after_calling_test;
81168
82- overriding member procedure after_calling_suite(self in out nocopy ut_realtime_reporter, a_suite in ut_logical_suite) as
169+ overriding member function get_description return varchar2 is
83170 begin
84- self.print_xml_fragment('') ;
85- end;
171+ return 'Provides test results in a XML format, for clients such as SQL Developer interested progressing details.' ;
172+ end get_description ;
86173
87- overriding member procedure after_calling_run(self in out nocopy ut_realtime_reporter, a_run in ut_run) as
174+ member procedure print_start_node(
175+ self in out nocopy ut_realtime_reporter,
176+ a_name in varchar2,
177+ a_id in varchar2 default null
178+ ) is
88179 begin
89- self.print_xml_fragment('</run>', -1);
90- self.print_xml_fragment('</report>', -1);
91- end;
180+ self.print_xml_fragment(
181+ '<' || a_name
182+ || case
183+ when a_id is not null then
184+ ' id="' || dbms_xmlgen.convert(a_id) || '"'
185+ end
186+ || '>',
187+ 0, 1
188+ );
189+ end print_start_node;
190+
191+ member procedure print_end_node(
192+ self in out nocopy ut_realtime_reporter,
193+ a_name in varchar2
194+ ) is
195+ begin
196+ self.print_xml_fragment('</' || a_name || '>', -1);
197+ end print_end_node;
92198
93- overriding member function get_description return varchar2 as
199+ member procedure print_node(
200+ self in out nocopy ut_realtime_reporter,
201+ a_name in varchar2,
202+ a_content in clob
203+ ) is
94204 begin
95- return 'Provides test results in a XML format, to consumed by clients such as SQL Developer interested progressing details.';
96- end;
205+ if a_content is not null then
206+ self.print_xml_fragment('<' || a_name || '>' || dbms_xmlgen.convert(a_content) || '</' || a_name || '>');
207+ end if;
208+ end print_node;
209+
210+ member procedure print_cdata_node(
211+ self in out nocopy ut_realtime_reporter,
212+ a_name in varchar2,
213+ a_content in clob
214+ ) is
215+ begin
216+ if a_content is not null then
217+ self.print_xml_fragment('<' || a_name || '><![CDATA[' || a_content || ']]></' || a_name || '>');
218+ end if;
219+ end print_cdata_node;
97220
98221 member procedure print_xml_fragment(
99222 self in out nocopy ut_realtime_reporter,
100- a_fragment in varchar2 ,
101- a_indent_summand_before in integer default 0,
102- a_indent_summand_after in integer default 0
103- ) as
223+ a_fragment in clob ,
224+ a_indent_summand_before in integer default 0,
225+ a_indent_summand_after in integer default 0
226+ ) is
104227 begin
105228 current_indent := current_indent + a_indent_summand_before;
106229 self.print_text(lpad(' ', 2 * current_indent) || a_fragment);
107230 current_indent := current_indent + a_indent_summand_after;
108- end;
231+ end print_xml_fragment ;
109232
110233end;
111234/
0 commit comments