Skip to content

Commit 4f8caa4

Browse files
committed
Fixed running single test procedure in context by path
Changed context naming (context name can be now explicit) Context description is now only set from `--%displayname` annotation Resolves utPLSQL#679 Resolves utPLSQL#674 Fixed most of compiler-warnings
1 parent eb1088e commit 4f8caa4

21 files changed

Lines changed: 286 additions & 81 deletions

docs/userguide/annotations.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ We strongly recommend putting package level annotations at the very top of packa
3030
| `--%aftertest(<procedure_name>)` | Procedure | Denotes that mentioned procedure should be executed after the annotated `%test` procedure. |
3131
| `--%rollback(<type>)` | Package/procedure | Defines transaction control. Supported values: `auto`(default) - a savepoint is created before invocation of each "before block" is and a rollback to specific savepoint is issued after each "after" block; `manual` - rollback is never issued automatically. Property can be overridden for child element (test in suite) |
3232
| `--%disabled` | Package/procedure | Used to disable a suite or a test. Disabled suites/tests do not get executed, they are however marked and reported as disabled in a test run. |
33-
| `--%context(<description>)` | Package | Denotes start of a nested context (sub-suite) in a suite package |
33+
| `--%context(<name>)` | Package | Denotes start of a named context (sub-suite) in a suite package |
3434
| `--%endcontext` | Package | Denotes end of a nested context (sub-suite) in a suite package |
3535

3636
### Suite
@@ -863,7 +863,7 @@ In essence, context behaves like a suite within a suite.
863863

864864
Context have following characteristics:
865865
- start with the `--%context` annotation and ends with `--%endcontext`
866-
- can have a name provided a parameter for example `--%context(Remove rooms by name)`
866+
- can have a name provided as parameter for example `--%context(remove_rooms_by_name)`
867867
- when no name is provided for context, the context is names `context_N` where `N` is the number of the context in suite
868868
- can have their own `--%beforeall`, `--%beforeeach`, `--%afterall` and `--%aftereach` procedures
869869
- `--%beforeall`, `--%beforeeach`, `--%afterall` and `--%aftereach` procedures defined at suite level, propagate to context
@@ -945,6 +945,7 @@ create or replace package test_rooms_management is
945945

946946

947947
--%context(remove_rooms_by_name)
948+
--%description(Remove rooms by name)
948949

949950
--%test(Removes a room without content in it)
950951
procedure remove_empty_room;
@@ -957,6 +958,7 @@ create or replace package test_rooms_management is
957958

958959

959960
--%context(add_rooms_content)
961+
--%description(Add content to a room)
960962

961963
--%test(Fails when room name is not valid)
962964
--%throws(-1403)

source/core/events/ut_event_manager.pkb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ create or replace package body ut_event_manager as
3333
procedure trigger_event( a_event_name t_event_name, a_event_object ut_event_item ) is
3434
begin
3535
if a_event_name is not null and g_event_listeners_index.exists(a_event_name)
36-
and g_event_listeners_index(a_event_name) is not null
36+
-- disabled due to compiler warning: PLW-06023: invocation of IS NOT NULL computes trivial value
37+
-- and g_event_listeners_index(a_event_name) is not null
3738
then
3839
for listener_number in 1 .. g_event_listeners_index(a_event_name).count loop
3940
g_listeners(listener_number).on_event(a_event_name, a_event_object);

source/core/types/ut_suite.tpb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ create or replace type body ut_suite as
1717
*/
1818

1919
constructor function ut_suite (
20-
self in out nocopy ut_suite, a_object_owner varchar2, a_object_name varchar2, a_suite_name varchar2 := null
20+
self in out nocopy ut_suite, a_object_owner varchar2, a_object_name varchar2
2121
) return self as result is
2222
begin
2323
self.self_type := $$plsql_unit;
24-
self.init(a_object_owner, a_object_name, nvl(a_suite_name, a_object_name));
24+
self.init(a_object_owner, a_object_name, a_object_name);
2525
self.items := ut_suite_items();
2626
before_all_list := ut_executables();
2727
after_all_list := ut_executables();

source/core/types/ut_suite.tps

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ create or replace type ut_suite under ut_logical_suite (
2727
*/
2828
after_all_list ut_executables,
2929
constructor function ut_suite (
30-
self in out nocopy ut_suite, a_object_owner varchar2, a_object_name varchar2, a_suite_name varchar2 := null
30+
self in out nocopy ut_suite, a_object_owner varchar2, a_object_name varchar2
3131
) return self as result,
3232
overriding member function do_execute(self in out nocopy ut_suite) return boolean,
3333
overriding member function get_error_stack_traces(self ut_suite) return ut_varchar2_list,
3434
overriding member function get_serveroutputs return clob
35-
)
35+
) not final
3636
/
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
create or replace type body ut_suite_context as
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+
constructor function ut_suite_context (
20+
self in out nocopy ut_suite_context, a_object_owner varchar2, a_object_name varchar2, a_context_name varchar2 := null
21+
) return self as result is
22+
begin
23+
self.self_type := $$plsql_unit;
24+
self.init(a_object_owner, a_object_name, a_context_name);
25+
self.items := ut_suite_items();
26+
before_all_list := ut_executables();
27+
after_all_list := ut_executables();
28+
return;
29+
end;
30+
31+
end;
32+
/
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
create or replace type ut_suite_context under ut_suite (
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+
constructor function ut_suite_context (
19+
self in out nocopy ut_suite_context, a_object_owner varchar2, a_object_name varchar2, a_context_name varchar2 := null
20+
) return self as result
21+
)
22+
/

source/core/types/ut_suite_item.tpb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ final member procedure do_execute(self in out nocopy ut_suite_item) is
9898
return transaction_invalidators;
9999
end;
100100

101-
member procedure add_transaction_invalidator(a_object_name varchar2) is
101+
member procedure add_transaction_invalidator(self in out nocopy ut_suite_item, a_object_name varchar2) is
102102
begin
103103
if a_object_name not member of transaction_invalidators then
104104
transaction_invalidators.extend();

source/core/types/ut_suite_item.tps

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ create or replace type ut_suite_item force under ut_event_item (
6161
member function create_savepoint_if_needed return varchar2,
6262
member procedure rollback_to_savepoint(self in out nocopy ut_suite_item, a_savepoint varchar2),
6363
member function get_transaction_invalidators return ut_varchar2_list,
64-
member procedure add_transaction_invalidator(a_object_name varchar2),
64+
member procedure add_transaction_invalidator(self in out nocopy ut_suite_item, a_object_name varchar2),
6565
/*
6666
Returns execution time in seconds (with miliseconds)
6767
*/

source/core/ut_suite_builder.pkb

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -552,8 +552,8 @@ create or replace package body ut_suite_builder is
552552
procedure add_annotated_procedures(
553553
a_annotations tt_package_annotations,
554554
a_suite in out nocopy ut_suite,
555-
a_before_each_list out ut_executables,
556-
a_after_each_list out ut_executables
555+
a_before_each_list out nocopy ut_executables,
556+
a_after_each_list out nocopy ut_executables
557557
) is
558558
l_position t_annotation_position;
559559
begin
@@ -653,9 +653,10 @@ create or replace package body ut_suite_builder is
653653
) is
654654
l_context_pos t_annotation_position;
655655
l_end_context_pos t_annotation_position;
656-
l_package_ann_index tt_annotations_index;
656+
l_context_ann_index tt_annotations_index;
657+
l_context_name t_object_name;
657658
l_annotations tt_package_annotations;
658-
l_suite ut_suite;
659+
l_context ut_suite_context;
659660
l_context_no binary_integer := 1;
660661

661662
function get_endcontext_position(
@@ -705,17 +706,20 @@ create or replace package body ut_suite_builder is
705706

706707
--create a sub-set of annotations to process as sub-suite (context)
707708
l_annotations := get_annotations_in_context(a_annotations, l_context_pos, l_end_context_pos);
708-
l_package_ann_index := build_annotation_index(l_annotations);
709+
l_context_ann_index := build_annotation_index(l_annotations);
709710

710-
l_suite := ut_suite(a_suite.object_owner, a_suite.object_name, gc_context||'_'||l_context_no);
711+
l_context_name := coalesce(
712+
l_annotations( l_context_pos ).text
713+
, gc_context||'_'||l_context_no
714+
);
715+
l_context := ut_suite_context(a_suite.object_owner, a_suite.object_name, l_context_name );
711716

712-
l_suite.description := l_annotations(l_package_ann_index(gc_context).first).text;
713-
l_suite.description := l_annotations(l_context_pos).text;
714-
warning_on_duplicate_annot( l_suite, l_package_ann_index, gc_suite );
717+
l_context.description := l_annotations(l_context_pos).text;
718+
warning_on_duplicate_annot( l_context, l_context_ann_index, gc_suite );
715719

716-
populate_suite_contents( l_suite, l_annotations, l_package_ann_index, gc_context||'_'||l_context_no );
720+
populate_suite_contents( l_context, l_annotations, l_context_ann_index, l_context_name );
717721

718-
a_suite.add_item(l_suite);
722+
a_suite.add_item(l_context);
719723

720724
-- remove annotations within context after processing them
721725
a_annotations.delete(l_context_pos, l_end_context_pos);

source/core/ut_suite_manager.pkb

Lines changed: 62 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -213,26 +213,64 @@ create or replace package body ut_suite_manager is
213213
end;
214214

215215
procedure filter_suite_by_path(a_suite in out nocopy ut_suite_item, a_path varchar2) is
216-
c_root constant varchar2(32767) := lower(regexp_substr(a_path, '[A-Za-z0-9$#_]+'));
217-
c_rest_path constant varchar2(32767) := regexp_substr(a_path, '\.(.+)', subexpression => 1);
218-
l_suite ut_logical_suite;
219-
l_item ut_suite_item;
220-
l_items ut_suite_items := ut_suite_items();
221-
begin
222-
if a_path is not null and a_suite is not null and a_suite is of (ut_logical_suite) then
223-
l_suite := treat(a_suite as ut_logical_suite);
216+
c_item_name constant varchar2(32767) := lower(regexp_substr(a_path, '[A-Za-z0-9$#_]+'));
217+
c_child_filter_path constant varchar2(32767) := regexp_substr(a_path, '\.(.+)', subexpression => 1);
218+
l_suite ut_logical_suite;
219+
l_item ut_suite_item;
220+
l_items ut_suite_items := ut_suite_items();
224221

225-
for i in 1 .. l_suite.items.count loop
226-
l_item := l_suite.items(i);
227-
if lower(l_item.name) = c_root then
228-
filter_suite_by_path(l_item, c_rest_path);
229-
l_items.extend;
230-
l_items(l_items.count) := l_item;
222+
function find_item_in_suite(a_suite ut_logical_suite, a_item_name varchar2) return ut_suite_item is
223+
l_item_index binary_integer;
224+
begin
225+
l_item_index := a_suite.items.first;
226+
while l_item_index is not null loop
227+
if lower(a_suite.items(l_item_index).name) = a_item_name then
228+
return a_suite.items(l_item_index);
231229
end if;
230+
l_item_index := a_suite.items.next(l_item_index);
232231
end loop;
232+
return null;
233+
end;
233234

234-
if l_items.count = 0 then
235-
raise_application_error(-20203, 'Suite not found');
235+
function find_item_in_suite_contexts(a_suite ut_logical_suite, a_item_name varchar2) return ut_suite_item is
236+
l_item_index binary_integer;
237+
l_context ut_suite_context;
238+
l_item ut_suite_item;
239+
begin
240+
l_item_index := a_suite.items.first;
241+
while l_item_index is not null loop
242+
if a_suite.items(l_item_index) is of (ut_suite_context) then
243+
l_item := find_item_in_suite(
244+
treat(a_suite.items(l_item_index) as ut_suite_context)
245+
, a_item_name
246+
);
247+
end if;
248+
249+
if l_item is not null then
250+
l_context := treat(a_suite.items(l_item_index) as ut_suite_context);
251+
l_context.items := ut_suite_items(l_item);
252+
exit;
253+
end if;
254+
l_item_index := a_suite.items.next(l_item_index);
255+
end loop;
256+
return l_context;
257+
end;
258+
begin
259+
if a_suite is of (ut_logical_suite) then
260+
l_suite := treat(a_suite as ut_logical_suite);
261+
262+
l_item := coalesce(
263+
find_item_in_suite(l_suite, c_item_name)
264+
, find_item_in_suite_contexts(l_suite, c_item_name)
265+
);
266+
if l_item is not null then
267+
if c_child_filter_path is not null then
268+
filter_suite_by_path(l_item, c_child_filter_path);
269+
end if;
270+
l_items.extend;
271+
l_items(l_items.count) := l_item;
272+
else
273+
raise_application_error(-20203, 'Suite item '||c_item_name||' not found');
236274
end if;
237275

238276
l_suite.items := l_items;
@@ -241,12 +279,15 @@ create or replace package body ut_suite_manager is
241279
end filter_suite_by_path;
242280

243281
function get_suite_filtered_by_path(a_path varchar2, a_schema_suites tt_schema_suites) return ut_logical_suite is
244-
l_suite ut_logical_suite;
245-
c_suite_path constant varchar2(4000) := regexp_substr(a_path, ':(.+)', subexpression => 1);
246-
c_root_suite_name constant varchar2(4000) := regexp_substr(c_suite_path, '^[A-Za-z0-9$#_]+');
282+
l_suite ut_logical_suite;
283+
c_suite_path constant varchar2(32767) := regexp_substr(a_path, ':(.+)', subexpression => 1);
284+
c_root_suite_name constant varchar2(32767) := regexp_substr(c_suite_path, '^[A-Za-z0-9$#_]+');
285+
c_child_filter_path constant varchar2(32767) := regexp_substr(c_suite_path, '\.(.+)', subexpression => 1);
247286
begin
248287
l_suite := a_schema_suites(c_root_suite_name);
249-
filter_suite_by_path(l_suite, regexp_substr(c_suite_path, '\.(.+)', subexpression => 1));
288+
if c_child_filter_path is not null then
289+
filter_suite_by_path(l_suite, c_child_filter_path);
290+
end if;
250291
return l_suite;
251292
exception
252293
when no_data_found then
@@ -293,7 +334,7 @@ create or replace package body ut_suite_manager is
293334
l_index varchar2(4000 char);
294335
l_suite ut_logical_suite;
295336
l_objects_to_run ut_suite_items;
296-
l_schema_paths t_schema_paths;
337+
l_schema_paths t_schema_paths;
297338
begin
298339
--resolve schema names from paths and group paths by schema name
299340
resolve_schema_names(l_paths);

0 commit comments

Comments
 (0)