@@ -66,33 +66,37 @@ create or replace package body ut_suite_builder is
6666 end;
6767
6868 function get_procedure_annotations(a_annotations ut_annotations, a_index binary_integer) return tt_procedure_annotations is
69- l_result tt_procedure_annotations;
70- l_index binary_integer := a_index;
69+ l_result tt_procedure_annotations;
70+ l_index binary_integer := a_index;
71+ l_annotation_pos binary_integer;
7172 begin
7273 loop
73- l_result(a_annotations(l_index).name)(l_index) := a_annotations(l_index).text;
74+ l_annotation_pos := a_annotations(l_index).position;
75+ l_result(a_annotations(l_index).name)(l_annotation_pos) := a_annotations(l_index).text;
7476 exit when is_last_annotation_for_proc(a_annotations, l_index);
7577 l_index := a_annotations.next(l_index);
7678 end loop;
7779 return l_result;
7880 end;
7981
8082 function convert_package_annotations(a_object ut_annotated_object) return t_package_annotations_info is
81- l_result t_package_annotations_info;
82- l_annotation_no binary_integer;
83+ l_result t_package_annotations_info;
84+ l_annotation_no binary_integer;
85+ l_annotation_pos binary_integer;
8386 begin
8487 l_result.owner := a_object.object_owner;
8588 l_result.name := a_object.object_name;
8689 l_annotation_no := a_object.annotations.first;
8790 while l_annotation_no is not null loop
91+ l_annotation_pos := a_object.annotations(l_annotation_no).position;
8892 if a_object.annotations(l_annotation_no).subobject_name is null then
89- l_result.annotations(l_annotation_no ).name := a_object.annotations(l_annotation_no).name;
90- l_result.annotations(l_annotation_no ).text := a_object.annotations(l_annotation_no).text;
93+ l_result.annotations(l_annotation_pos ).name := a_object.annotations(l_annotation_no).name;
94+ l_result.annotations(l_annotation_pos ).text := a_object.annotations(l_annotation_no).text;
9195 else
92- l_result.annotations(l_annotation_no ).procedure_name := a_object.annotations(l_annotation_no).subobject_name;
93- l_result.annotations(l_annotation_no ).procedure_annotations := get_procedure_annotations(a_object.annotations, l_annotation_no);
94- if l_result.annotations(l_annotation_no ).procedure_annotations.count > 0 then
95- l_annotation_no := l_annotation_no + l_result.annotations(l_annotation_no ).procedure_annotations.count - 1;
96+ l_result.annotations(l_annotation_pos ).procedure_name := a_object.annotations(l_annotation_no).subobject_name;
97+ l_result.annotations(l_annotation_pos ).procedure_annotations := get_procedure_annotations(a_object.annotations, l_annotation_no);
98+ if l_result.annotations(l_annotation_pos ).procedure_annotations.count > 0 then
99+ l_annotation_no := l_annotation_no + l_result.annotations(l_annotation_pos ).procedure_annotations.count - 1;
96100 end if;
97101 end if;
98102 l_annotation_no := a_object.annotations.next(l_annotation_no);
@@ -101,15 +105,15 @@ create or replace package body ut_suite_builder is
101105 end;
102106
103107 function build_annotation_index(a_annotations tt_package_annotations ) return tt_annotations_index is
104- l_result tt_annotations_index;
105- l_idx binary_integer;
108+ l_result tt_annotations_index;
109+ l_annotation_pos binary_integer;
106110 begin
107- l_idx := a_annotations.first;
108- while l_idx is not null loop
109- if a_annotations(l_idx ).name is not null then
110- l_result(a_annotations(l_idx ).name)(l_idx ) := true;
111+ l_annotation_pos := a_annotations.first;
112+ while l_annotation_pos is not null loop
113+ if a_annotations( l_annotation_pos ).name is not null then
114+ l_result(a_annotations( l_annotation_pos ).name)( l_annotation_pos ) := true;
111115 end if;
112- l_idx := a_annotations.next(l_idx );
116+ l_annotation_pos := a_annotations.next( l_annotation_pos );
113117 end loop;
114118 return l_result;
115119 end;
@@ -204,17 +208,23 @@ create or replace package body ut_suite_builder is
204208
205209 procedure warning_on_duplicate_annot(
206210 a_suite in out nocopy ut_suite_item,
207- a_annoations tt_annotations_index,
211+ a_annotations tt_annotations_index,
208212 a_for_annotation varchar2
209213 ) is
210214 l_annotation_name t_annotation_name;
211- l_warning varchar2(32767) ;
215+ line_no binary_integer ;
212216 begin
213- if a_annoations.exists(a_for_annotation) then
214- if a_annoations(a_for_annotation).count > 1 then
215- a_suite.put_warning(
216- 'Multiple occurrences of annotation "--%'||a_for_annotation||'" were found. Last occurrence of annotation was used.'
217- );
217+ if a_annotations.exists(a_for_annotation) then
218+ if a_annotations(a_for_annotation).count > 1 then
219+ --start from second occurrence of annotation
220+ line_no := a_annotations(a_for_annotation).next( a_annotations(a_for_annotation).first );
221+ while line_no is not null loop
222+ a_suite.put_warning(
223+ 'Duplicate annotation "--%' || a_for_annotation || '". Annotation ignored.' || chr( 10 )
224+ || 'at "' || upper( a_suite.object_owner || '.' || a_suite.object_name ) || '", line ' || line_no
225+ );
226+ line_no := a_annotations(a_for_annotation).next(line_no);
227+ end loop;
218228 end if;
219229 end if;
220230 end;
@@ -228,19 +238,23 @@ create or replace package body ut_suite_builder is
228238 ) is
229239 l_annotation_name t_annotation_name;
230240 l_warning varchar2(32767);
241+ line_no binary_integer;
231242 begin
232243 l_annotation_name := a_proc_annotations.first;
233244 while l_annotation_name is not null loop
234245 if l_annotation_name member of a_invalid_annotations then
235- l_warning := l_warning ||'"--%'|| l_annotation_name || '", ';
246+ line_no := a_proc_annotations(l_annotation_name).first;
247+ while line_no is not null loop
248+ a_suite.put_warning(
249+ 'Annotation "--%' || l_annotation_name || '" cannot be used with annotation: "--%' || a_for_annotation || '"'
250+ || chr( 10 ) || 'at "' || upper( a_suite.object_owner || '.' || a_suite.object_name||'.'||a_procedure_name )
251+ || '", line ' || line_no
252+ );
253+ line_no := a_proc_annotations(l_annotation_name).next(line_no);
254+ end loop;
236255 end if;
237256 l_annotation_name := a_proc_annotations.next(l_annotation_name);
238257 end loop;
239- if l_warning is not null then
240- a_suite.put_warning(
241- 'Annotations: '||rtrim(l_warning,', ')||' were ignored for procedure "'||upper(a_procedure_name)||'".' ||
242- ' Those annotations cannot be used with annotation: "--%'||a_for_annotation||'"');
243- end if;
244258 end;
245259
246260 procedure add_test(
@@ -257,17 +271,21 @@ create or replace package body ut_suite_builder is
257271 if a_annotations.exists('displayname') then
258272 l_annotation_texts := a_annotations('displayname');
259273 --take the last definition if more than one was provided
260- l_test.description := l_annotation_texts(l_annotation_texts.last );
274+ l_test.description := l_annotation_texts(l_annotation_texts.first );
261275 --TODO if more than one - warning
262276 end if;
263- l_test.description := coalesce(l_test.description,a_annotations('test')(a_annotations('test').last ));
277+ l_test.description := coalesce(l_test.description,a_annotations('test')(a_annotations('test').first ));
264278 l_test.path := a_suite.path ||'.'||a_procedure_name;
265279
266280 if a_annotations.exists('rollback') then
267281 l_annotation_texts := a_annotations('rollback');
268- l_test.rollback_type := get_rollback_type(l_annotation_texts(l_annotation_texts.last ));
282+ l_test.rollback_type := get_rollback_type(l_annotation_texts(l_annotation_texts.first ));
269283 if l_test.rollback_type is null then
270- a_suite.put_warning('"--%rollback" annotation requires one of values: "auto" or "manual". Annotation ignored.');
284+ a_suite.put_warning(
285+ '"--%rollback" annotation requires one of values: "auto" or "manual". Annotation ignored.'
286+ || chr( 10 ) || 'at "' || upper( a_suite.object_owner || '.' || a_suite.object_name||'.'||a_procedure_name )
287+ || '", line ' || l_annotation_texts.first
288+ );
271289 end if;
272290 end if;
273291
@@ -388,34 +406,50 @@ create or replace package body ut_suite_builder is
388406 l_object_name := a_suite.object_name;
389407 end if;
390408 if a_package_ann_index.exists('suitepath') then
391- l_annotation_text := trim(a_annotations(a_package_ann_index('suitepath').last ).text);
409+ l_annotation_text := trim(a_annotations(a_package_ann_index('suitepath').first ).text);
392410 if l_annotation_text is not null then
393411 if regexp_like(l_annotation_text,'^((\w|[$#])+\.)*(\w|[$#])+$') then
394412 a_suite.path := l_annotation_text||'.'||l_object_name;
395413 else
396- a_suite.put_warning('Invalid path value in annotation "--%suitepath('||l_annotation_text||')". Annotation ignored.');
414+ a_suite.put_warning(
415+ 'Invalid path value in annotation "--%suitepath('||l_annotation_text||')". Annotation ignored.'
416+ || chr( 10 ) || 'at "' || upper( a_suite.object_owner || '.' || a_suite.object_name )
417+ || '", line ' || a_package_ann_index('suitepath').first
418+ );
397419 end if;
398420 else
399- a_suite.put_warning('"--%suitepath" annotation requires a non-empty value. Annotation ignored.');
421+ a_suite.put_warning(
422+ '"--%suitepath" annotation requires a non-empty value. Annotation ignored.'
423+ || chr( 10 ) || 'at "' || upper( a_suite.object_owner || '.' || a_suite.object_name )
424+ || '", line ' || a_package_ann_index('suitepath').first
425+ );
400426 end if;
401427 warning_on_duplicate_annot(a_suite, a_package_ann_index, 'suitepath');
402428 end if;
403429 a_suite.path := lower(coalesce(a_suite.path, l_object_name));
404430
405431 if a_package_ann_index.exists('displayname') then
406- l_annotation_text := trim(a_annotations(a_package_ann_index('displayname').last ).text);
432+ l_annotation_text := trim(a_annotations(a_package_ann_index('displayname').first ).text);
407433 if l_annotation_text is not null then
408434 a_suite.description := l_annotation_text;
409435 else
410- a_suite.put_warning('"--%displayname" annotation requires a non-empty value. Annotation ignored.');
436+ a_suite.put_warning(
437+ '"--%displayname" annotation requires a non-empty value. Annotation ignored.'
438+ || chr( 10 ) || 'at "' || upper( a_suite.object_owner || '.' || a_suite.object_name )
439+ || '", line ' || a_package_ann_index('displayname').first
440+ );
411441 end if;
412442 warning_on_duplicate_annot(a_suite, a_package_ann_index, 'displayname');
413443 end if;
414444
415445 if a_package_ann_index.exists('rollback') then
416- l_rollback_type := get_rollback_type(a_annotations(a_package_ann_index('rollback').last ).text);
446+ l_rollback_type := get_rollback_type(a_annotations(a_package_ann_index('rollback').first ).text);
417447 if l_rollback_type is null then
418- a_suite.put_warning('"--%rollback" annotation requires one of values: "auto" or "manual". Annotation ignored.');
448+ a_suite.put_warning(
449+ '"--%rollback" annotation requires one of values: "auto" or "manual". Annotation ignored.'
450+ || chr( 10 ) || 'at "' || upper( a_suite.object_owner || '.' || a_suite.object_name )
451+ || '", line ' || a_package_ann_index('rollback').first
452+ );
419453 end if;
420454 warning_on_duplicate_annot(a_suite, a_package_ann_index, 'rollback');
421455 end if;
@@ -526,15 +560,21 @@ create or replace package body ut_suite_builder is
526560 l_annotation_pos := a_package_ann_index('context').first;
527561 while l_annotation_pos is not null loop
528562 a_suite.put_warning(
529- 'Annotation "--%context('||a_annotations(l_annotation_pos).text||')" was ignored. Cannot find following "--%endcontext".');
563+ 'Annotation "--%context('||a_annotations(l_annotation_pos).text||')" was ignored. Cannot find following "--%endcontext".'
564+ || chr( 10 ) || 'at "' || upper( a_suite.object_owner || '.' || a_suite.object_name )
565+ || '", line ' || a_package_ann_index('context').first
566+ );
530567 l_annotation_pos := a_package_ann_index('context').next(l_annotation_pos);
531568 end loop;
532569 end if;
533570 if a_package_ann_index.exists('endcontext') then
534571 l_annotation_pos := a_package_ann_index('endcontext').first;
535572 while l_annotation_pos is not null loop
536573 a_suite.put_warning(
537- 'Annotation "--%endcontext" was ignored. Cannot find preceding "--%context".');
574+ 'Annotation "--%endcontext" was ignored. Cannot find preceding "--%context".'
575+ || chr( 10 ) || 'at "' || upper( a_suite.object_owner || '.' || a_suite.object_name )
576+ || '", line ' || a_package_ann_index('endcontext').first
577+ );
538578 l_annotation_pos := a_package_ann_index('endcontext').next(l_annotation_pos);
539579 end loop;
540580 end if;
@@ -553,7 +593,7 @@ create or replace package body ut_suite_builder is
553593 --create an incomplete suite
554594 l_suite := ut_suite(a_package_annotations.owner, a_package_annotations.name);
555595
556- l_suite.description := l_annotations(l_package_ann_index('suite').last ).text;
596+ l_suite.description := l_annotations(l_package_ann_index('suite').first ).text;
557597 warning_on_duplicate_annot(l_suite, l_package_ann_index, 'suite');
558598
559599 add_suite_contexts( l_suite, l_annotations, l_package_ann_index );
0 commit comments