@@ -21,36 +21,51 @@ create or replace package body ut_suite_builder is
2121 subtype t_procedure_name is varchar2(500);
2222 subtype t_annotation_position is binary_integer;
2323
24- type tt_annotations is table of t_annotation_text index by t_annotation_name;
2524
26- type t_package_annotation is record(
25+ --list of annotation texts for a given annotation indexed by annotation position:
26+ --This would hold: ('some', 'other') for a single annotation name recurring in a single procedure example
27+ -- --%beforetest(some)
28+ -- --%beforetest(other)
29+ -- --%test(some test with two before test procedures)
30+ -- procedure some_test ...
31+ -- when you'd like to have two beforetest procedures executed in a single test
32+ type tt_annotation_texts is table of t_annotation_text index by t_annotation_position;
33+
34+ type tt_annotations_by_name is table of tt_annotation_texts index by t_annotation_name;
35+
36+ type t_object_annotation is record(
2737 text varchar2(4000),
2838 name varchar2(4000),
2939 procedure_name varchar2(500),
30- procedure_annotations tt_annotations
40+ procedure_annotations tt_annotations_by_name
3141 );
3242
33- type tt_package_annotations is table of t_package_annotation index by t_annotation_position;
43+ --holds a list of package level annotations indexed (order) by position.
44+ type tt_object_annotations is table of t_object_annotation index by t_annotation_position;
45+
46+ --holds all annotations for object
3447 type t_package_annotations_info is record(
3548 owner t_procedure_name,
3649 name t_procedure_name,
37- annotations tt_package_annotations
50+ annotations tt_object_annotations
3851 );
3952
40- type tt_positions is table of boolean index by t_annotation_position;
41- type tt_annotations_index is table of tt_positions index by t_annotation_name;
53+ --list of all package level annotation positions for a given annotaion name
54+ type tt_package_annot_positions is table of boolean index by t_annotation_position;
55+ --index used to lookup package level annotations by package-level annotation name
56+ type tt_annotations_index is table of tt_package_annot_positions index by t_annotation_name;
4257
4358 function is_last_annotation_for_proc(a_annotations ut_annotations, a_index binary_integer) return boolean is
4459 begin
4560 return a_index = a_annotations.count or a_annotations(a_index).subobject_name != nvl(a_annotations(a_index+1).subobject_name, ' ');
4661 end;
4762
48- function get_procedure_annotations(a_annotations ut_annotations, a_index binary_integer) return tt_annotations is
49- l_result tt_annotations ;
63+ function get_procedure_annotations(a_annotations ut_annotations, a_index binary_integer) return tt_annotations_by_name is
64+ l_result tt_annotations_by_name ;
5065 i binary_integer := a_index;
5166 begin
5267 loop
53- l_result(a_annotations(i).name) := a_annotations(i).text;
68+ l_result(a_annotations(i).name)(i) := a_annotations(i).text;
5469 exit when is_last_annotation_for_proc(a_annotations, i);
5570 i := a_annotations.next(i);
5671 end loop;
@@ -71,14 +86,16 @@ create or replace package body ut_suite_builder is
7186 else
7287 l_result.annotations(l_annotation_no).procedure_name := a_object.annotations(l_annotation_no).subobject_name;
7388 l_result.annotations(l_annotation_no).procedure_annotations := get_procedure_annotations(a_object.annotations, l_annotation_no);
74- l_annotation_no := l_annotation_no + l_result.annotations(l_annotation_no).procedure_annotations.count - 1;
89+ if l_result.annotations(l_annotation_no).procedure_annotations.count > 0 then
90+ l_annotation_no := l_annotation_no + l_result.annotations(l_annotation_no).procedure_annotations.count - 1;
91+ end if;
7592 end if;
7693 l_annotation_no := a_object.annotations.next(l_annotation_no);
7794 end loop;
7895 return l_result;
7996 end;
8097
81- function build_annotation_index(a_annotations tt_package_annotations ) return tt_annotations_index is
98+ function build_annotation_index(a_annotations tt_object_annotations ) return tt_annotations_index is
8299 l_result tt_annotations_index;
83100 i binary_integer;
84101 begin
@@ -137,6 +154,20 @@ create or replace package body ut_suite_builder is
137154 return l_exception_number_list;
138155 end;
139156
157+ procedure add_to_throws_numbers_list(
158+ a_list in out nocopy ut_integer_list,
159+ a_throws_ann_text tt_annotation_texts
160+ ) is
161+ l_annotation_pos binary_integer;
162+ begin
163+ a_list := ut_integer_list();
164+ l_annotation_pos := a_throws_ann_text.first;
165+ while l_annotation_pos is not null loop
166+ a_list := a_list multiset union build_exception_numbers_list( a_throws_ann_text(l_annotation_pos));
167+ l_annotation_pos := a_throws_ann_text.next(l_annotation_pos);
168+ end loop;
169+ end;
170+
140171 procedure add_to_list(
141172 a_executables in out nocopy ut_executables,
142173 a_procedure_name varchar2,
@@ -151,9 +182,24 @@ create or replace package body ut_suite_builder is
151182 a_executables(a_executables.last) := ut_executable(a_suite_item, a_procedure_name, a_event_name);
152183 end;
153184
185+ procedure add_to_list(
186+ a_executables in out nocopy ut_executables,
187+ a_annotation_texts tt_annotation_texts,
188+ a_event_name ut_utils.t_event_name,
189+ a_suite_item ut_suite_item
190+ ) is
191+ l_annotation_pos binary_integer;
192+ begin
193+ l_annotation_pos := a_annotation_texts.first;
194+ while l_annotation_pos is not null loop
195+ add_to_list(a_executables, a_annotation_texts(l_annotation_pos), a_event_name, a_suite_item );
196+ l_annotation_pos := a_annotation_texts.next( l_annotation_pos);
197+ end loop;
198+ end;
199+
154200 procedure warning_on_extra_annotations(
155201 a_suite in out nocopy ut_suite_item,
156- a_procedure_info t_package_annotation ,
202+ a_procedure_info t_object_annotation ,
157203 a_for_annotation varchar2
158204 ) is
159205 l_annotation_name t_annotation_name;
@@ -176,20 +222,26 @@ create or replace package body ut_suite_builder is
176222 procedure add_test(
177223 a_suite in out nocopy ut_suite,
178224 a_procedure_name varchar2,
179- a_annotations tt_annotations
225+ a_annotations tt_annotations_by_name
180226 ) is
181- l_test ut_test;
227+ l_test ut_test;
228+ l_annotation_texts tt_annotation_texts;
229+ l_annotation_pos binary_integer;
182230 begin
183231 l_test := ut_test(a_suite.object_owner, a_suite.object_name, a_procedure_name);
184232
185233 if a_annotations.exists('displayname') then
186- l_test.description := a_annotations('displayname');
234+ l_annotation_texts := a_annotations('displayname');
235+ --take the last definition if more than one was provided
236+ l_test.description := l_annotation_texts(l_annotation_texts.last);
237+ --TODO if more than one - warning
187238 end if;
188- l_test.description := coalesce(l_test.description,a_annotations('test'));
239+ l_test.description := coalesce(l_test.description,a_annotations('test')(a_annotations('test').last) );
189240 l_test.path := a_suite.path ||'.'||a_procedure_name;
190241
191242 if a_annotations.exists('rollback') then
192- l_test.rollback_type := get_rollback_type(a_annotations('rollback'));
243+ l_annotation_texts := a_annotations('rollback');
244+ l_test.rollback_type := get_rollback_type(l_annotation_texts(l_annotation_texts.last));
193245 end if;
194246
195247 if a_annotations.exists('beforetest') then
@@ -199,7 +251,7 @@ create or replace package body ut_suite_builder is
199251 add_to_list( l_test.after_test_list, a_annotations('aftertest'), ut_utils.gc_after_test, l_test );
200252 end if;
201253 if a_annotations.exists('throws') then
202- l_test.expected_error_codes := build_exception_numbers_list( a_annotations('throws'));
254+ add_to_throws_numbers_list( l_test.expected_error_codes, a_annotations('throws'));
203255 end if;
204256 l_test.disabled_flag := ut_utils.boolean_to_int(a_annotations.exists('disabled'));
205257
@@ -224,7 +276,7 @@ create or replace package body ut_suite_builder is
224276 end;
225277
226278 procedure add_procedures_from_annot(
227- l_annotations tt_package_annotations ,
279+ l_annotations tt_object_annotations ,
228280 l_suite in out nocopy ut_suite,
229281 l_before_each_list out ut_executables,
230282 l_after_each_list out ut_executables
@@ -256,9 +308,24 @@ create or replace package body ut_suite_builder is
256308 end loop;
257309 end;
258310
259- function build_suite(a_package t_package_annotations_info) return ut_logical_suite is
311+ procedure add_suite_context(
312+ a_suite in out nocopy ut_suite,
313+ a_package_ann_index in out nocopy tt_annotations_index,
314+ a_annotations in out nocopy tt_object_annotations
315+ ) is
316+ begin
317+ null;
318+ -- while l_package_ann_index.exists('context') loop
319+ -- if l_package_ann_index.exists('endcontext')
320+ -- and l_package_ann_index.exists('endcontext').first > l_package_ann_index.exists('context').first then
321+ -- null;
322+ -- end if;
323+ -- end loop;
324+ end;
325+
326+ function create_suite(a_package t_package_annotations_info) return ut_logical_suite is
260327 l_package_ann_index tt_annotations_index;
261- l_annotations tt_package_annotations ;
328+ l_annotations tt_object_annotations ;
262329 l_suite ut_suite;
263330 l_before_each_list ut_executables;
264331 l_after_each_list ut_executables;
@@ -323,7 +390,7 @@ create or replace package body ut_suite_builder is
323390
324391 function create_suite(a_object ut_annotated_object) return ut_logical_suite is
325392 begin
326- return build_suite (convert_object_annotations(a_object));
393+ return create_suite (convert_object_annotations(a_object));
327394 end create_suite;
328395
329396 function build_suites_hierarchy(a_suites_by_path tt_schema_suites) return tt_schema_suites is
0 commit comments