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

Skip to content

Commit 203f6a1

Browse files
committed
Separated suite building from suite run management.
Added ability to pass cursor to build suites.
1 parent fac6a80 commit 203f6a1

5 files changed

Lines changed: 294 additions & 209 deletions

File tree

source/core/ut_suite_builder.pkb

Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
create or replace package body ut_suite_builder is
2+
/*
3+
utPLSQL - Version 3
4+
Copyright 2016 - 2017 utPLSQL Project
5+
6+
Licensed under the Apache License, Version 2.0 (the "License"):
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
*/
18+
19+
------------------
20+
21+
function create_suite(a_object ut_annotated_object) return ut_logical_suite is
22+
l_is_suite boolean := false;
23+
l_is_test boolean := false;
24+
l_suite_disabled boolean := false;
25+
l_test_disabled boolean := false;
26+
l_suite_items ut_suite_items := ut_suite_items();
27+
l_suite_name varchar2(4000);
28+
29+
l_default_setup_proc varchar2(250 char);
30+
l_default_teardown_proc varchar2(250 char);
31+
l_suite_setup_proc varchar2(250 char);
32+
l_suite_teardown_proc varchar2(250 char);
33+
l_suite_path varchar2(4000 char);
34+
35+
l_proc_name varchar2(250 char);
36+
37+
l_suite ut_logical_suite;
38+
l_test ut_test;
39+
40+
l_suite_rollback integer;
41+
42+
l_beforetest_procedure varchar2(250 char);
43+
l_aftertest_procedure varchar2(250 char);
44+
l_rollback_type integer;
45+
l_displayname varchar2(4000);
46+
47+
begin
48+
l_suite_rollback := ut_utils.gc_rollback_auto;
49+
for i in 1 .. a_object.annotations.count loop
50+
51+
if a_object.annotations(i).subobject_name is null then
52+
53+
if a_object.annotations(i).name in ('suite','displayname') then
54+
l_suite_name := a_object.annotations(i).text;
55+
if a_object.annotations(i).name = 'suite' then
56+
l_is_suite := true;
57+
end if;
58+
elsif a_object.annotations(i).name = 'disabled' then
59+
l_suite_disabled := true;
60+
elsif a_object.annotations(i).name = 'suitepath' and a_object.annotations(i).text is not null then
61+
l_suite_path := a_object.annotations(i).text || '.' || lower(a_object.object_name);
62+
elsif a_object.annotations(i).name = 'rollback' then
63+
if lower(a_object.annotations(i).text) = 'manual' then
64+
l_suite_rollback := ut_utils.gc_rollback_manual;
65+
else
66+
l_suite_rollback := ut_utils.gc_rollback_auto;
67+
end if;
68+
end if;
69+
70+
elsif l_is_suite then
71+
72+
l_proc_name := a_object.annotations(i).subobject_name;
73+
74+
if a_object.annotations(i).name = 'beforeeach' and l_default_setup_proc is null then
75+
l_default_setup_proc := l_proc_name;
76+
elsif a_object.annotations(i).name = 'aftereach' and l_default_teardown_proc is null then
77+
l_default_teardown_proc := l_proc_name;
78+
elsif a_object.annotations(i).name = 'beforeall' and l_suite_setup_proc is null then
79+
l_suite_setup_proc := l_proc_name;
80+
elsif a_object.annotations(i).name = 'afterall' and l_suite_teardown_proc is null then
81+
l_suite_teardown_proc := l_proc_name;
82+
83+
84+
elsif a_object.annotations(i).name = 'disabled' then
85+
l_test_disabled := true;
86+
elsif a_object.annotations(i).name = 'beforetest' then
87+
l_beforetest_procedure := a_object.annotations(i).text;
88+
elsif a_object.annotations(i).name = 'aftertest' then
89+
l_aftertest_procedure := a_object.annotations(i).text;
90+
elsif a_object.annotations(i).name in ('displayname','test') then
91+
l_displayname := a_object.annotations(i).text;
92+
if a_object.annotations(i).name = 'test' then
93+
l_is_test := true;
94+
end if;
95+
elsif a_object.annotations(i).name = 'rollback' then
96+
if lower(a_object.annotations(i).text) = 'manual' then
97+
l_rollback_type := ut_utils.gc_rollback_manual;
98+
elsif lower(a_object.annotations(i).text) = 'auto' then
99+
l_rollback_type := ut_utils.gc_rollback_auto;
100+
end if;
101+
end if;
102+
103+
if l_is_test
104+
and (i = a_object.annotations.count
105+
or l_proc_name != nvl(a_object.annotations(i+1).subobject_name, ' ') ) then
106+
l_suite_items.extend;
107+
l_suite_items(l_suite_items.last) :=
108+
ut_test(a_object_owner => a_object.object_owner
109+
,a_object_name => a_object.object_name
110+
,a_name => l_proc_name
111+
,a_description => l_displayname
112+
,a_rollback_type => coalesce(l_rollback_type, l_suite_rollback)
113+
,a_disabled_flag => l_suite_disabled or l_test_disabled
114+
,a_before_test_proc_name => l_beforetest_procedure
115+
,a_after_test_proc_name => l_aftertest_procedure);
116+
117+
l_is_test := false;
118+
l_test_disabled := false;
119+
l_aftertest_procedure := null;
120+
l_beforetest_procedure := null;
121+
l_rollback_type := null;
122+
end if;
123+
124+
end if;
125+
end loop;
126+
127+
if l_is_suite then
128+
l_suite := ut_suite (
129+
a_object_owner => a_object.object_owner,
130+
a_object_name => a_object.object_name,
131+
a_name => a_object.object_name, --this could be different for sub-suite (context)
132+
a_path => l_suite_path, --a patch for this suite (excluding the package name of current suite)
133+
a_description => l_suite_name,
134+
a_rollback_type => l_suite_rollback,
135+
a_disabled_flag => l_suite_disabled,
136+
a_before_all_proc_name => l_suite_setup_proc,
137+
a_after_all_proc_name => l_suite_teardown_proc
138+
);
139+
for i in 1 .. l_suite_items.count loop
140+
l_test := treat(l_suite_items(i) as ut_test);
141+
l_test.set_beforeeach(l_default_setup_proc);
142+
l_test.set_aftereach(l_default_teardown_proc);
143+
l_test.path := l_suite.path || '.' || l_test.name;
144+
l_suite.add_item(l_test);
145+
end loop;
146+
end if;
147+
148+
return l_suite;
149+
150+
end create_suite;
151+
152+
function build_suites_hierarchy(a_suites_by_path tt_schema_suites) return tt_schema_suites is
153+
l_result tt_schema_suites;
154+
l_suite_path varchar2(4000 char);
155+
l_parent_path varchar2(4000 char);
156+
l_name varchar2(4000 char);
157+
l_suites_by_path tt_schema_suites;
158+
begin
159+
l_suites_by_path := a_suites_by_path;
160+
--were iterating in reverse order of the index by path table
161+
-- so the first paths will be the leafs of hierarchy and next will their parents
162+
l_suite_path := l_suites_by_path.last;
163+
ut_utils.debug_log('Input suites to process = '||l_suites_by_path.count);
164+
165+
while l_suite_path is not null loop
166+
l_parent_path := substr( l_suite_path, 1, instr(l_suite_path,'.',-1)-1);
167+
ut_utils.debug_log('Processing l_suite_path = "'||l_suite_path||'", l_parent_path = "'||l_parent_path||'"');
168+
--no parent => I'm a root element
169+
if l_parent_path is null then
170+
ut_utils.debug_log(' suite "'||l_suite_path||'" is a root element - adding to return list.');
171+
l_result(l_suite_path) := l_suites_by_path(l_suite_path);
172+
-- not a root suite - need to add it to a parent suite
173+
else
174+
--parent does not exist and needs to be added
175+
if not l_suites_by_path.exists(l_parent_path) then
176+
l_name := substr( l_parent_path, instr(l_parent_path,'.',-1)+1);
177+
ut_utils.debug_log(' Parent suite "'||l_parent_path||'" not found in the list - Adding suite "'||l_name||'"');
178+
l_suites_by_path(l_parent_path) :=
179+
ut_logical_suite(
180+
a_object_owner => l_suites_by_path(l_suite_path).object_owner,
181+
a_object_name => l_name, a_name => l_name, a_path => l_parent_path
182+
);
183+
else
184+
ut_utils.debug_log(' Parent suite "'||l_parent_path||'" found in list of suites');
185+
end if;
186+
ut_utils.debug_log(' adding suite "'||l_suite_path||'" to "'||l_parent_path||'" items');
187+
l_suites_by_path(l_parent_path).add_item( l_suites_by_path(l_suite_path) );
188+
end if;
189+
l_suite_path := l_suites_by_path.prior(l_suite_path);
190+
end loop;
191+
ut_utils.debug_log(l_result.count||' root suites created.');
192+
return l_result;
193+
end;
194+
195+
function build_suites(a_annotated_objects sys_refcursor) return t_schema_suites_info is
196+
l_suite ut_logical_suite;
197+
l_annotated_objects ut_annotated_objects;
198+
l_all_suites tt_schema_suites;
199+
l_result t_schema_suites_info;
200+
begin
201+
fetch a_annotated_objects bulk collect into l_annotated_objects;
202+
close a_annotated_objects;
203+
204+
for i in 1 .. l_annotated_objects.count loop
205+
l_suite := create_suite(l_annotated_objects(i));
206+
if l_suite is not null then
207+
l_all_suites(l_suite.path) := l_suite;
208+
l_result.suite_paths(l_suite.object_name) := l_suite.path;
209+
end if;
210+
end loop;
211+
212+
--build hierarchical structure of the suite
213+
-- Restructure single-dimension list into hierarchy of suites by the value of %suitepath attribute value
214+
l_result.schema_suites := build_suites_hierarchy(l_all_suites);
215+
216+
return l_result;
217+
end;
218+
219+
function build_schema_suites(a_owner_name varchar2) return t_schema_suites_info is
220+
l_annotations_cursor sys_refcursor;
221+
begin
222+
-- form the single-dimension list of suites constructed from parsed packages
223+
open l_annotations_cursor for
224+
q'[select value(x)
225+
from table(
226+
]'||ut_utils.ut_owner||q'[.ut_annotation_manager.get_annotated_objects(:a_owner_name, 'PACKAGE')
227+
)x ]'
228+
using a_owner_name;
229+
230+
return build_suites(l_annotations_cursor);
231+
end;
232+
233+
end ut_suite_builder;
234+
/

source/core/ut_suite_builder.pks

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
create or replace package ut_suite_builder authid current_user is
2+
/*
3+
utPLSQL - Version 3
4+
Copyright 2016 - 2017 utPLSQL Project
5+
6+
Licensed under the Apache License, Version 2.0 (the "License"):
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
*/
18+
19+
/**
20+
* Responsible for converting annotations into unit test suites
21+
*/
22+
23+
type tt_schema_suites is table of ut_logical_suite index by varchar2(4000 char);
24+
type t_object_suite_path is table of varchar2(4000) index by varchar2(4000 char);
25+
26+
type t_schema_suites_info is record (
27+
schema_suites tt_schema_suites,
28+
suite_paths t_object_suite_path
29+
);
30+
31+
/**
32+
* Builds set of hierarchical suites for a given schema
33+
*
34+
* @param a_owner_name name of the schema to builds suites for
35+
* @return list of suites organized into hierarchy
36+
*
37+
*/
38+
function build_schema_suites(a_owner_name varchar2) return t_schema_suites_info;
39+
40+
/**
41+
* Builds set of hierarchical suites for given annotations
42+
*
43+
* @param a_annotated_objects cursor returning ut_annotated_object type
44+
* @return list of suites organized into hierarchy
45+
*
46+
*/
47+
function build_suites(a_annotated_objects sys_refcursor) return t_schema_suites_info;
48+
49+
end ut_suite_builder;
50+
/

0 commit comments

Comments
 (0)