Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed running single test procedure in context by path #695

Merged
merged 3 commits into from
Jun 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions docs/userguide/annotations.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ We strongly recommend putting package level annotations at the very top of packa
| `--%aftertest(<procedure_name>)` | Procedure | Denotes that mentioned procedure should be executed after the annotated `%test` procedure. |
| `--%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) |
| `--%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. |
| `--%context(<description>)` | Package | Denotes start of a nested context (sub-suite) in a suite package |
| `--%context(<name>)` | Package | Denotes start of a named context (sub-suite) in a suite package |
| `--%endcontext` | Package | Denotes end of a nested context (sub-suite) in a suite package |

### Suite
Expand Down Expand Up @@ -863,7 +863,7 @@ In essence, context behaves like a suite within a suite.

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


--%context(remove_rooms_by_name)
--%description(Remove rooms by name)

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


--%context(add_rooms_content)
--%description(Add content to a room)

--%test(Fails when room name is not valid)
--%throws(-1403)
Expand Down
3 changes: 2 additions & 1 deletion source/core/events/ut_event_manager.pkb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ create or replace package body ut_event_manager as
procedure trigger_event( a_event_name t_event_name, a_event_object ut_event_item ) is
begin
if a_event_name is not null and g_event_listeners_index.exists(a_event_name)
and g_event_listeners_index(a_event_name) is not null
-- disabled due to compiler warning: PLW-06023: invocation of IS NOT NULL computes trivial value
-- and g_event_listeners_index(a_event_name) is not null
then
for listener_number in 1 .. g_event_listeners_index(a_event_name).count loop
g_listeners(listener_number).on_event(a_event_name, a_event_object);
Expand Down
4 changes: 2 additions & 2 deletions source/core/types/ut_suite.tpb
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ create or replace type body ut_suite as
*/

constructor function ut_suite (
self in out nocopy ut_suite, a_object_owner varchar2, a_object_name varchar2, a_suite_name varchar2 := null
self in out nocopy ut_suite, a_object_owner varchar2, a_object_name varchar2
) return self as result is
begin
self.self_type := $$plsql_unit;
self.init(a_object_owner, a_object_name, nvl(a_suite_name, a_object_name));
self.init(a_object_owner, a_object_name, a_object_name);
self.items := ut_suite_items();
before_all_list := ut_executables();
after_all_list := ut_executables();
Expand Down
4 changes: 2 additions & 2 deletions source/core/types/ut_suite.tps
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ create or replace type ut_suite under ut_logical_suite (
*/
after_all_list ut_executables,
constructor function ut_suite (
self in out nocopy ut_suite, a_object_owner varchar2, a_object_name varchar2, a_suite_name varchar2 := null
self in out nocopy ut_suite, a_object_owner varchar2, a_object_name varchar2
) return self as result,
overriding member function do_execute(self in out nocopy ut_suite) return boolean,
overriding member function get_error_stack_traces(self ut_suite) return ut_varchar2_list,
overriding member function get_serveroutputs return clob
)
) not final
/
32 changes: 32 additions & 0 deletions source/core/types/ut_suite_context.tpb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
create or replace type body ut_suite_context as
/*
utPLSQL - Version 3
Copyright 2016 - 2017 utPLSQL Project

Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

constructor function ut_suite_context (
self in out nocopy ut_suite_context, a_object_owner varchar2, a_object_name varchar2, a_context_name varchar2 := null
) return self as result is
begin
self.self_type := $$plsql_unit;
self.init(a_object_owner, a_object_name, a_context_name);
self.items := ut_suite_items();
before_all_list := ut_executables();
after_all_list := ut_executables();
return;
end;

end;
/
22 changes: 22 additions & 0 deletions source/core/types/ut_suite_context.tps
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
create or replace type ut_suite_context under ut_suite (
/*
utPLSQL - Version 3
Copyright 2016 - 2017 utPLSQL Project

Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
constructor function ut_suite_context (
self in out nocopy ut_suite_context, a_object_owner varchar2, a_object_name varchar2, a_context_name varchar2 := null
) return self as result
)
/
2 changes: 1 addition & 1 deletion source/core/types/ut_suite_item.tpb
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ final member procedure do_execute(self in out nocopy ut_suite_item) is
return transaction_invalidators;
end;

member procedure add_transaction_invalidator(a_object_name varchar2) is
member procedure add_transaction_invalidator(self in out nocopy ut_suite_item, a_object_name varchar2) is
begin
if a_object_name not member of transaction_invalidators then
transaction_invalidators.extend();
Expand Down
2 changes: 1 addition & 1 deletion source/core/types/ut_suite_item.tps
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ create or replace type ut_suite_item force under ut_event_item (
member function create_savepoint_if_needed return varchar2,
member procedure rollback_to_savepoint(self in out nocopy ut_suite_item, a_savepoint varchar2),
member function get_transaction_invalidators return ut_varchar2_list,
member procedure add_transaction_invalidator(a_object_name varchar2),
member procedure add_transaction_invalidator(self in out nocopy ut_suite_item, a_object_name varchar2),
/*
Returns execution time in seconds (with miliseconds)
*/
Expand Down
26 changes: 15 additions & 11 deletions source/core/ut_suite_builder.pkb
Original file line number Diff line number Diff line change
Expand Up @@ -552,8 +552,8 @@ create or replace package body ut_suite_builder is
procedure add_annotated_procedures(
a_annotations tt_package_annotations,
a_suite in out nocopy ut_suite,
a_before_each_list out ut_executables,
a_after_each_list out ut_executables
a_before_each_list out nocopy ut_executables,
a_after_each_list out nocopy ut_executables
) is
l_position t_annotation_position;
begin
Expand Down Expand Up @@ -653,9 +653,10 @@ create or replace package body ut_suite_builder is
) is
l_context_pos t_annotation_position;
l_end_context_pos t_annotation_position;
l_package_ann_index tt_annotations_index;
l_context_ann_index tt_annotations_index;
l_context_name t_object_name;
l_annotations tt_package_annotations;
l_suite ut_suite;
l_context ut_suite_context;
l_context_no binary_integer := 1;

function get_endcontext_position(
Expand Down Expand Up @@ -705,17 +706,20 @@ create or replace package body ut_suite_builder is

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

l_suite := ut_suite(a_suite.object_owner, a_suite.object_name, gc_context||'_'||l_context_no);
l_context_name := coalesce(
l_annotations( l_context_pos ).text
, gc_context||'_'||l_context_no
);
l_context := ut_suite_context(a_suite.object_owner, a_suite.object_name, l_context_name );

l_suite.description := l_annotations(l_package_ann_index(gc_context).first).text;
l_suite.description := l_annotations(l_context_pos).text;
warning_on_duplicate_annot( l_suite, l_package_ann_index, gc_suite );
l_context.description := l_annotations(l_context_pos).text;
warning_on_duplicate_annot( l_context, l_context_ann_index, gc_suite );

populate_suite_contents( l_suite, l_annotations, l_package_ann_index, gc_context||'_'||l_context_no );
populate_suite_contents( l_context, l_annotations, l_context_ann_index, l_context_name );

a_suite.add_item(l_suite);
a_suite.add_item(l_context);

-- remove annotations within context after processing them
a_annotations.delete(l_context_pos, l_end_context_pos);
Expand Down
83 changes: 62 additions & 21 deletions source/core/ut_suite_manager.pkb
Original file line number Diff line number Diff line change
Expand Up @@ -213,26 +213,64 @@ create or replace package body ut_suite_manager is
end;

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

for i in 1 .. l_suite.items.count loop
l_item := l_suite.items(i);
if lower(l_item.name) = c_root then
filter_suite_by_path(l_item, c_rest_path);
l_items.extend;
l_items(l_items.count) := l_item;
function find_item_in_suite(a_suite ut_logical_suite, a_item_name varchar2) return ut_suite_item is
l_item_index binary_integer;
begin
l_item_index := a_suite.items.first;
while l_item_index is not null loop
if lower(a_suite.items(l_item_index).name) = a_item_name then
return a_suite.items(l_item_index);
end if;
l_item_index := a_suite.items.next(l_item_index);
end loop;
return null;
end;

if l_items.count = 0 then
raise_application_error(-20203, 'Suite not found');
function find_item_in_suite_contexts(a_suite ut_logical_suite, a_item_name varchar2) return ut_suite_item is
l_item_index binary_integer;
l_context ut_suite_context;
l_item ut_suite_item;
begin
l_item_index := a_suite.items.first;
while l_item_index is not null loop
if a_suite.items(l_item_index) is of (ut_suite_context) then
l_item := find_item_in_suite(
treat(a_suite.items(l_item_index) as ut_suite_context)
, a_item_name
);
end if;

if l_item is not null then
l_context := treat(a_suite.items(l_item_index) as ut_suite_context);
l_context.items := ut_suite_items(l_item);
exit;
end if;
l_item_index := a_suite.items.next(l_item_index);
end loop;
return l_context;
end;
begin
if a_suite is of (ut_logical_suite) then
l_suite := treat(a_suite as ut_logical_suite);

l_item := coalesce(
find_item_in_suite(l_suite, c_item_name)
, find_item_in_suite_contexts(l_suite, c_item_name)
);
if l_item is not null then
if c_child_filter_path is not null then
filter_suite_by_path(l_item, c_child_filter_path);
end if;
l_items.extend;
l_items(l_items.count) := l_item;
else
raise_application_error(-20203, 'Suite item '||c_item_name||' not found');
end if;

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

function get_suite_filtered_by_path(a_path varchar2, a_schema_suites tt_schema_suites) return ut_logical_suite is
l_suite ut_logical_suite;
c_suite_path constant varchar2(4000) := regexp_substr(a_path, ':(.+)', subexpression => 1);
c_root_suite_name constant varchar2(4000) := regexp_substr(c_suite_path, '^[A-Za-z0-9$#_]+');
l_suite ut_logical_suite;
c_suite_path constant varchar2(32767) := regexp_substr(a_path, ':(.+)', subexpression => 1);
c_root_suite_name constant varchar2(32767) := regexp_substr(c_suite_path, '^[A-Za-z0-9$#_]+');
c_child_filter_path constant varchar2(32767) := regexp_substr(c_suite_path, '\.(.+)', subexpression => 1);
begin
l_suite := a_schema_suites(c_root_suite_name);
filter_suite_by_path(l_suite, regexp_substr(c_suite_path, '\.(.+)', subexpression => 1));
if c_child_filter_path is not null then
filter_suite_by_path(l_suite, c_child_filter_path);
end if;
return l_suite;
exception
when no_data_found then
Expand Down Expand Up @@ -293,7 +334,7 @@ create or replace package body ut_suite_manager is
l_index varchar2(4000 char);
l_suite ut_logical_suite;
l_objects_to_run ut_suite_items;
l_schema_paths t_schema_paths;
l_schema_paths t_schema_paths;
begin
--resolve schema names from paths and group paths by schema name
resolve_schema_names(l_paths);
Expand Down
2 changes: 1 addition & 1 deletion source/core/ut_suite_manager.pks
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ create or replace package ut_suite_manager authid current_user is
*/

/**
* Reads database source code, parses it and returns annotations
* Resposible for building hierarhy of sutes from individual suites created by suite_builder
*/

/**
Expand Down
4 changes: 0 additions & 4 deletions source/core/ut_utils.pkb
Original file line number Diff line number Diff line change
Expand Up @@ -571,10 +571,6 @@ procedure append_to_clob(a_src_clob in out nocopy clob, a_clob_table t_clob_tab,
l_newlines_count binary_integer;
l_offset binary_integer := 1;
l_length binary_integer := coalesce(dbms_lob.getlength(a_source), 0);
function is_before(a_x binary_integer, a_y binary_integer) return boolean is
begin
return a_x < a_y or a_y = 0;
end;
begin
l_ml_comment_start := instr(a_source,'/*');
l_comment_start := instr(a_source,'--');
Expand Down
14 changes: 7 additions & 7 deletions source/expectations/data_values/ut_compound_data_value.tpb
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,13 @@ create or replace type body ut_compound_data_value as

function get_diff_message (a_row_diff ut_compound_data_helper.t_row_diffs,a_compare_type varchar2) return varchar2 is
begin
if a_compare_type = ut_compound_data_helper.gc_compare_join_by and a_row_diff.pk_value is not null then
return ' PK '||a_row_diff.pk_value||' - '||rpad(a_row_diff.diff_type,10)||a_row_diff.diffed_row;
elsif a_compare_type = ut_compound_data_helper.gc_compare_join_by or a_compare_type = ut_compound_data_helper.gc_compare_normal then
return ' Row No. '||a_row_diff.rn||' - '||rpad(a_row_diff.diff_type,10)||a_row_diff.diffed_row;
elsif a_compare_type = ut_compound_data_helper.gc_compare_unordered then
return rpad(a_row_diff.diff_type,10)||a_row_diff.diffed_row;
end if;
if a_compare_type = ut_compound_data_helper.gc_compare_join_by and a_row_diff.pk_value is not null then
return ' PK '||a_row_diff.pk_value||' - '||rpad(a_row_diff.diff_type,10)||a_row_diff.diffed_row;
elsif a_compare_type = ut_compound_data_helper.gc_compare_join_by or a_compare_type = ut_compound_data_helper.gc_compare_normal then
return ' Row No. '||a_row_diff.rn||' - '||rpad(a_row_diff.diff_type,10)||a_row_diff.diffed_row;
elsif a_compare_type = ut_compound_data_helper.gc_compare_unordered then
return rpad(a_row_diff.diff_type,10)||a_row_diff.diffed_row;
end if;
end;

begin
Expand Down
Loading