Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1adf35d

Browse files
committed
Changed the way reporters events are registered.
Fixed issue with invalid object type passed to events `before_calling_test_execute` `after_calling_test_execute` Fixed cutting of multi-line comments when parsing-annotations. Annotation position now indicates line number of annotation in package.
1 parent 9cd61bf commit 1adf35d

15 files changed

Lines changed: 280 additions & 106 deletions

source/core/annotations/ut_annotation_parser.pkb

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ create or replace package body ut_annotation_parser as
2222
type tt_comment_list is table of varchar2(32767) index by pls_integer;
2323

2424
gc_annotation_qualifier constant varchar2(1) := '%';
25-
gc_multiline_comment_pattern constant varchar2(50) := '/\*.*?\*/';
2625
gc_annot_comment_pattern constant varchar2(30) := '^( |'||chr(09)||')*-- *('||gc_annotation_qualifier||'.*?)$'; -- chr(09) is a tab character
2726
gc_comment_replacer_patter constant varchar2(50) := '{COMMENT#%N%}';
2827
gc_comment_replacer_regex_ptrn constant varchar2(25) := '{COMMENT#(\d+)}';
@@ -32,13 +31,6 @@ create or replace package body ut_annotation_parser as
3231
gc_annotation_pattern constant varchar2(50) := gc_annotation_qualifier || gc_regexp_identifier || '[ '||chr(9)||']*(\(.*?\)\s*?$)?';
3332

3433

35-
function delete_multiline_comments(a_source in clob) return clob is
36-
begin
37-
return regexp_replace(srcstr => a_source
38-
,pattern => gc_multiline_comment_pattern
39-
,modifier => 'n');
40-
end;
41-
4234
procedure add_annotation(
4335
a_annotations in out nocopy ut_annotations,
4436
a_position positiven,
@@ -147,7 +139,8 @@ create or replace package body ut_annotation_parser as
147139

148140
function extract_and_replace_comments(a_source in out nocopy clob) return tt_comment_list is
149141
l_comments tt_comment_list;
150-
l_comment_pos pls_integer;
142+
l_comment_pos binary_integer;
143+
l_comment_line binary_integer;
151144
l_comment_replacer varchar2(50);
152145
l_source clob := a_source;
153146
begin
@@ -165,14 +158,15 @@ create or replace package body ut_annotation_parser as
165158
-- position index is shifted by 1 because gc_annot_comment_pattern contains ^ as first sign
166159
-- but after instr index already points to the char on that line
167160
l_comment_pos := l_comment_pos-1;
168-
l_comments(l_comments.count + 1) := trim(regexp_substr(srcstr => a_source
161+
l_comment_line := regexp_count(substr(a_source,1,l_comment_pos),chr(10),1,'m')+1;
162+
l_comments(l_comment_line) := trim(regexp_substr(srcstr => a_source
169163
,pattern => gc_annot_comment_pattern
170164
,occurrence => 1
171165
,position => l_comment_pos
172166
,modifier => 'm'
173167
,subexpression => 2));
174168

175-
l_comment_replacer := replace(gc_comment_replacer_patter, '%N%', l_comments.count);
169+
l_comment_replacer := replace(gc_comment_replacer_patter, '%N%', l_comment_line);
176170

177171
l_source := regexp_replace(srcstr => a_source
178172
,pattern => gc_annot_comment_pattern
@@ -203,7 +197,7 @@ create or replace package body ut_annotation_parser as
203197
l_comment_index positive;
204198
begin
205199

206-
l_source := delete_multiline_comments(l_source);
200+
l_source := ut_utils.replace_multiline_comments(l_source);
207201

208202
-- replace all single line comments with {COMMENT#12} element and store it's content for easier processing
209203
-- this call modifies l_source

source/core/coverage/ut_coverage_reporter_base.tpb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,11 @@ create or replace type body ut_coverage_reporter_base is
4949
ut_coverage.coverage_pause();
5050
end;
5151

52-
overriding final member procedure before_calling_test_execute(self in out nocopy ut_coverage_reporter_base, a_test in ut_test) is
52+
overriding final member procedure before_calling_test_execute(self in out nocopy ut_coverage_reporter_base, a_executable in ut_executable) is
5353
begin
5454
ut_coverage.coverage_resume();
5555
end;
56-
overriding final member procedure after_calling_test_execute (self in out nocopy ut_coverage_reporter_base, a_test in ut_test) is
56+
overriding final member procedure after_calling_test_execute (self in out nocopy ut_coverage_reporter_base, a_executable in ut_executable) is
5757
begin
5858
ut_coverage.coverage_pause();
5959
end;

source/core/coverage/ut_coverage_reporter_base.tps

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ create or replace type ut_coverage_reporter_base under ut_output_reporter_base(
2626
overriding final member procedure before_calling_before_test(self in out nocopy ut_coverage_reporter_base, a_executable in ut_executable),
2727
overriding final member procedure after_calling_before_test (self in out nocopy ut_coverage_reporter_base, a_executable in ut_executable),
2828

29-
overriding final member procedure before_calling_test_execute(self in out nocopy ut_coverage_reporter_base, a_test in ut_test),
30-
overriding final member procedure after_calling_test_execute (self in out nocopy ut_coverage_reporter_base, a_test in ut_test),
29+
overriding final member procedure before_calling_test_execute(self in out nocopy ut_coverage_reporter_base, a_executable in ut_executable),
30+
overriding final member procedure after_calling_test_execute (self in out nocopy ut_coverage_reporter_base, a_executable in ut_executable),
3131

3232
overriding final member procedure before_calling_after_test(self in out nocopy ut_coverage_reporter_base, a_executable in ut_executable),
3333
overriding final member procedure after_calling_after_test (self in out nocopy ut_coverage_reporter_base, a_executable in ut_executable),

source/core/types/ut_reporter_base.tpb

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,11 @@ create or replace type body ut_reporter_base is
8383
null;
8484
end;
8585

86-
member procedure before_calling_test_execute(self in out nocopy ut_reporter_base, a_test in ut_test) is
86+
member procedure before_calling_test_execute(self in out nocopy ut_reporter_base, a_executable in ut_executable) is
8787
begin
8888
null;
8989
end;
90-
member procedure after_calling_test_execute (self in out nocopy ut_reporter_base, a_test in ut_test) is
90+
member procedure after_calling_test_execute (self in out nocopy ut_reporter_base, a_executable in ut_executable) is
9191
begin
9292
null;
9393
end;
@@ -137,16 +137,30 @@ create or replace type body ut_reporter_base is
137137
end;
138138

139139
overriding member function get_supported_events return ut_varchar2_list is
140-
l_events_list ut_varchar2_list;
141140
begin
142-
select lower(replace(procedure_name,'CALLING_'))
143-
bulk collect into l_events_list
144-
from user_procedures
145-
where object_name = upper(self_type)
146-
and (procedure_name like 'BEFORE_%' or procedure_name like 'AFTER_%');
147-
l_events_list.extend;
148-
l_events_list(l_events_list.last) := ut_utils.gc_finalize;
149-
return l_events_list;
141+
return ut_varchar2_list(
142+
ut_utils.gc_before_run,
143+
ut_utils.gc_before_suite,
144+
ut_utils.gc_before_test,
145+
ut_utils.gc_before_before_all,
146+
ut_utils.gc_before_before_each,
147+
ut_utils.gc_before_before_test,
148+
ut_utils.gc_before_test_execute,
149+
ut_utils.gc_before_after_test,
150+
ut_utils.gc_before_after_each,
151+
ut_utils.gc_before_after_all,
152+
ut_utils.gc_after_run,
153+
ut_utils.gc_after_suite,
154+
ut_utils.gc_after_test,
155+
ut_utils.gc_after_before_all,
156+
ut_utils.gc_after_before_each,
157+
ut_utils.gc_after_before_test,
158+
ut_utils.gc_after_test_execute,
159+
ut_utils.gc_after_after_test,
160+
ut_utils.gc_after_after_each,
161+
ut_utils.gc_after_after_all,
162+
ut_utils.gc_finalize
163+
);
150164
end;
151165

152166
overriding member procedure on_event( self in out nocopy ut_reporter_base, a_event_name varchar2, a_event_item ut_event_item) is
@@ -165,7 +179,7 @@ create or replace type body ut_reporter_base is
165179
when ut_utils.gc_before_before_test
166180
then self.before_calling_before_test(treat(a_event_item as ut_executable));
167181
when ut_utils.gc_before_test_execute
168-
then self.before_calling_test_execute(treat(a_event_item as ut_test));
182+
then self.before_calling_test_execute(treat(a_event_item as ut_executable));
169183
when ut_utils.gc_before_after_test
170184
then self.before_calling_after_test(treat(a_event_item as ut_executable));
171185
when ut_utils.gc_before_after_each
@@ -185,7 +199,7 @@ create or replace type body ut_reporter_base is
185199
when ut_utils.gc_after_before_test
186200
then self.after_calling_before_test(treat(a_event_item as ut_executable));
187201
when ut_utils.gc_after_test_execute
188-
then self.after_calling_test_execute(treat(a_event_item as ut_test));
202+
then self.after_calling_test_execute(treat(a_event_item as ut_executable));
189203
when ut_utils.gc_after_after_test
190204
then self.after_calling_after_test(treat(a_event_item as ut_executable));
191205
when ut_utils.gc_after_after_each

source/core/types/ut_reporter_base.tps

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ create or replace type ut_reporter_base under ut_event_listener (
3939
member procedure before_calling_before_test(self in out nocopy ut_reporter_base, a_executable in ut_executable),
4040
member procedure after_calling_before_test (self in out nocopy ut_reporter_base, a_executable in ut_executable),
4141

42-
member procedure before_calling_test_execute(self in out nocopy ut_reporter_base, a_test in ut_test),
43-
member procedure after_calling_test_execute (self in out nocopy ut_reporter_base, a_test in ut_test),
42+
member procedure before_calling_test_execute(self in out nocopy ut_reporter_base, a_executable in ut_executable),
43+
member procedure after_calling_test_execute (self in out nocopy ut_reporter_base, a_executable in ut_executable),
4444

4545
member procedure before_calling_after_test(self in out nocopy ut_reporter_base, a_executable in ut_executable),
4646
member procedure after_calling_after_test (self in out nocopy ut_reporter_base, a_executable in ut_executable),

source/core/ut_suite_builder.pkb

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ create or replace package body ut_suite_builder is
202202
end loop;
203203
end;
204204

205-
procedure duplicate_annotations_warning(
205+
procedure warning_on_duplicate_annot(
206206
a_suite in out nocopy ut_suite_item,
207207
a_annoations tt_annotations_index,
208208
a_for_annotation varchar2
@@ -290,15 +290,20 @@ create or replace package body ut_suite_builder is
290290
a_before_each_list ut_executables,
291291
a_after_each_list ut_executables
292292
) is
293-
l_test ut_test;
293+
l_test ut_test;
294+
l_context ut_logical_suite;
294295
begin
295296
if a_suite.items is not null then
296297
for i in 1 .. a_suite.items.count loop
297298
if a_suite.items(i) is of (ut_test) then
298299
l_test := treat( a_suite.items(i) as ut_test);
299-
l_test.before_each_list := a_before_each_list;
300-
l_test.after_each_list := a_after_each_list;
300+
l_test.before_each_list := coalesce(a_before_each_list,ut_executables()) multiset union all l_test.before_each_list;
301+
l_test.after_each_list := l_test.after_each_list multiset union all coalesce(a_after_each_list,ut_executables());
301302
a_suite.items(i) := l_test;
303+
elsif a_suite.items(i) is of (ut_logical_suite) then
304+
l_context := treat(a_suite.items(i) as ut_logical_suite);
305+
update_before_after_list(l_context, a_before_each_list, a_after_each_list);
306+
a_suite.items(i) := l_context;
302307
end if;
303308
end loop;
304309
end if;
@@ -393,7 +398,7 @@ create or replace package body ut_suite_builder is
393398
else
394399
a_suite.put_warning('"--%suitepath" annotation requires a non-empty value. Annotation ignored.');
395400
end if;
396-
duplicate_annotations_warning(a_suite, a_package_ann_index, 'suitepath');
401+
warning_on_duplicate_annot(a_suite, a_package_ann_index, 'suitepath');
397402
end if;
398403
a_suite.path := lower(coalesce(a_suite.path, l_object_name));
399404

@@ -404,15 +409,15 @@ create or replace package body ut_suite_builder is
404409
else
405410
a_suite.put_warning('"--%displayname" annotation requires a non-empty value. Annotation ignored.');
406411
end if;
407-
duplicate_annotations_warning(a_suite, a_package_ann_index, 'displayname');
412+
warning_on_duplicate_annot(a_suite, a_package_ann_index, 'displayname');
408413
end if;
409414

410415
if a_package_ann_index.exists('rollback') then
411416
l_rollback_type := get_rollback_type(a_annotations(a_package_ann_index('rollback').last).text);
412417
if l_rollback_type is null then
413418
a_suite.put_warning('"--%rollback" annotation requires one of values: "auto" or "manual". Annotation ignored.');
414419
end if;
415-
duplicate_annotations_warning(a_suite, a_package_ann_index, 'rollback');
420+
warning_on_duplicate_annot(a_suite, a_package_ann_index, 'rollback');
416421
end if;
417422

418423
a_suite.disabled_flag := ut_utils.boolean_to_int(a_package_ann_index.exists('disabled'));
@@ -491,7 +496,7 @@ create or replace package body ut_suite_builder is
491496

492497
l_suite.description := l_annotations(l_package_ann_index('context').first).text;
493498
l_suite.description := l_annotations(l_context_pos).text;
494-
duplicate_annotations_warning( l_suite, l_package_ann_index, 'suite' );
499+
warning_on_duplicate_annot( l_suite, l_package_ann_index, 'suite' );
495500

496501
populate_suite_contents( l_suite, l_annotations, l_package_ann_index, 'context_'||l_context_no );
497502

@@ -549,7 +554,7 @@ create or replace package body ut_suite_builder is
549554
l_suite := ut_suite(a_package_annotations.owner, a_package_annotations.name);
550555

551556
l_suite.description := l_annotations(l_package_ann_index('suite').last).text;
552-
duplicate_annotations_warning(l_suite, l_package_ann_index, 'suite');
557+
warning_on_duplicate_annot(l_suite, l_package_ann_index, 'suite');
553558

554559
add_suite_contexts( l_suite, l_annotations, l_package_ann_index );
555560
--by this time all contexts were consumed and l_annotations should not have any context/endcontext annotation in it.

source/core/ut_utils.pkb

Lines changed: 98 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ procedure append_to_clob(a_src_clob in out nocopy clob, a_clob_table t_clob_tab,
513513
if a_list is not null then
514514
l_trimmed_list := ut_varchar2_list();
515515
l_index := a_list.first;
516-
516+
517517
while (l_index is not null) loop
518518
l_trimmed_list.extend;
519519
l_trimmed_list(l_trimmed_list.count) := regexp_replace(a_list(l_index), '(^['||a_regexp_to_trim||']*)|(['||a_regexp_to_trim||']*$)');
@@ -531,7 +531,7 @@ procedure append_to_clob(a_src_clob in out nocopy clob, a_clob_table t_clob_tab,
531531
if a_list is not null then
532532
l_filtered_list := ut_varchar2_list();
533533
l_index := a_list.first;
534-
534+
535535
while (l_index is not null) loop
536536
if regexp_like(a_list(l_index), a_regexp_filter) then
537537
l_filtered_list.extend;
@@ -540,9 +540,104 @@ procedure append_to_clob(a_src_clob in out nocopy clob, a_clob_table t_clob_tab,
540540
l_index := a_list.next(l_index);
541541
end loop;
542542
end if;
543-
543+
544544
return l_filtered_list;
545545
end;
546546

547+
548+
549+
function replace_multiline_comments(a_source clob) return clob is
550+
l_result clob;
551+
l_ml_comment_start binary_integer := 1;
552+
l_comment_start binary_integer := 1;
553+
l_text_start binary_integer := 1;
554+
l_escaped_text_start binary_integer := 1;
555+
l_escaped_text_end_char varchar2(1 char);
556+
l_end binary_integer := 1;
557+
l_ml_comment clob;
558+
l_newlines_count binary_integer;
559+
l_offset binary_integer := 1;
560+
l_length binary_integer := coalesce(dbms_lob.getlength(a_source), 0);
561+
function is_before(a_x binary_integer, a_y binary_integer) return boolean is
562+
begin
563+
return a_x < a_y or a_y = 0;
564+
end;
565+
begin
566+
l_ml_comment_start := instr(a_source,'/*');
567+
l_comment_start := instr(a_source,'--');
568+
l_text_start := instr(a_source,'''');
569+
l_escaped_text_start := instr(a_source,q'[q']');
570+
while l_offset > 0 and l_ml_comment_start > 0 loop
571+
572+
if l_ml_comment_start > 0 and (l_ml_comment_start < l_comment_start or l_comment_start = 0)
573+
and (l_ml_comment_start < l_text_start or l_text_start = 0)and (l_ml_comment_start < l_escaped_text_start or l_escaped_text_start = 0)
574+
then
575+
l_end := instr(a_source,'*/',l_ml_comment_start+2);
576+
append_to_clob(l_result, dbms_lob.substr(a_source, l_ml_comment_start-l_offset, l_offset));
577+
if l_end > 0 then
578+
l_ml_comment := substr(a_source, l_ml_comment_start, l_end-l_ml_comment_start);
579+
l_newlines_count := length( l_ml_comment ) - length( translate( l_ml_comment, 'a'||chr(10), 'a') );
580+
if l_newlines_count > 0 then
581+
append_to_clob(l_result, lpad( chr(10), l_newlines_count, chr(10) ) );
582+
end if;
583+
l_end := l_end + 2;
584+
end if;
585+
else
586+
587+
if l_comment_start > 0 and (l_comment_start < l_ml_comment_start or l_ml_comment_start = 0)
588+
and (l_comment_start < l_text_start or l_text_start = 0) and (l_comment_start < l_escaped_text_start or l_escaped_text_start = 0)
589+
then
590+
l_end := instr(a_source,chr(10),l_comment_start+2);
591+
if l_end > 0 then
592+
l_end := l_end + 1;
593+
end if;
594+
elsif l_text_start > 0 and (l_text_start < l_ml_comment_start or l_ml_comment_start = 0)
595+
and (l_text_start < l_comment_start or l_comment_start = 0) and (l_text_start < l_escaped_text_start or l_escaped_text_start = 0)
596+
then
597+
l_end := instr(a_source,q'[']',l_text_start+1);
598+
599+
--skip double quotes while searching for end of quoted text
600+
while l_end > 0 and l_end = instr(a_source,q'['']',l_text_start+1) loop
601+
l_end := instr(a_source,q'[']',l_end+1);
602+
end loop;
603+
if l_end > 0 then
604+
l_end := l_end + 1;
605+
end if;
606+
607+
elsif l_escaped_text_start > 0 and (l_escaped_text_start < l_ml_comment_start or l_ml_comment_start = 0)
608+
and (l_escaped_text_start < l_comment_start or l_comment_start = 0) and (l_escaped_text_start < l_text_start or l_text_start = 0)
609+
then
610+
--translate char "[" from the start of quoted text "q'[someting]'" into "]"
611+
l_escaped_text_end_char := translate( substr(a_source, l_escaped_text_start + 2, 1), '[{(<', ']})>');
612+
l_end := instr(a_source,l_escaped_text_end_char||'''',l_escaped_text_start + 3 );
613+
if l_end > 0 then
614+
l_end := l_end + 2;
615+
end if;
616+
end if;
617+
618+
if l_end = 0 then
619+
append_to_clob(l_result, dbms_lob.substr(a_source, l_length-l_offset, l_offset));
620+
else
621+
append_to_clob(l_result, dbms_lob.substr(a_source, l_end-l_offset, l_offset));
622+
end if;
623+
end if;
624+
l_offset := l_end;
625+
if l_offset >= l_ml_comment_start then
626+
l_ml_comment_start := instr(a_source,'/*',l_offset);
627+
end if;
628+
if l_offset >= l_comment_start then
629+
l_comment_start := instr(a_source,'--',l_offset);
630+
end if;
631+
if l_offset >= l_text_start then
632+
l_text_start := instr(a_source,'''',l_offset);
633+
end if;
634+
if l_offset >= l_escaped_text_start then
635+
l_escaped_text_start := instr(a_source,q'[q']',l_offset);
636+
end if;
637+
end loop;
638+
append_to_clob(l_result, dbms_lob.substr(a_source, offset=>l_end));
639+
return l_result;
640+
end;
641+
547642
end ut_utils;
548643
/

source/core/ut_utils.pks

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,5 +322,10 @@ create or replace package ut_utils authid definer is
322322
/*It takes a collection of type ut_varchar2_list and it only returns the elements which meets the regular expression*/
323323
function filter_list(a_list IN ut_varchar2_list, a_regexp_filter in varchar2) return ut_varchar2_list;
324324

325+
/**
326+
* Replaces multi-line comments in given source-code with empty lines
327+
*/
328+
function replace_multiline_comments(a_source clob) return clob;
329+
325330
end ut_utils;
326331
/

0 commit comments

Comments
 (0)