Skip to content

Commit 722498d

Browse files
committed
Merge branch 'develop' into feature/include_encoding_in_xml_and_html
2 parents 49b5fba + ee8e0c4 commit 722498d

26 files changed

Lines changed: 367 additions & 95 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)