-
Notifications
You must be signed in to change notification settings - Fork 189
Bugfix/nested context mixup #1035
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
Changes from 4 commits
e8f4532
8df3f7d
a4d92de
4d1500f
3c547ec
b4c1d72
86185a8
89df1dd
c61abfa
35acf14
3327fc3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -704,21 +704,69 @@ create or replace package body ut_suite_builder is | |
| set_seq_no(a_suite.after_all_list); | ||
| end; | ||
|
|
||
| function get_endcontext_position( | ||
| a_context_ann_pos t_annotation_position, | ||
| function get_next_annotation_of_type( | ||
| a_start_position t_annotation_position, | ||
| a_annotation_type varchar2, | ||
| a_package_annotations in out nocopy tt_annotations_by_name | ||
| ) return t_annotation_position is | ||
| l_result t_annotation_position; | ||
| begin | ||
| if a_package_annotations.exists(gc_endcontext) then | ||
| l_result := a_package_annotations(gc_endcontext).first; | ||
| while l_result <= a_context_ann_pos loop | ||
| l_result := a_package_annotations(gc_endcontext).next(l_result); | ||
| if a_package_annotations.exists(a_annotation_type) then | ||
| l_result := a_package_annotations(a_annotation_type).first; | ||
| while l_result <= a_start_position loop | ||
| l_result := a_package_annotations(a_annotation_type).next(l_result); | ||
| end loop; | ||
| end if; | ||
| return l_result; | ||
| end; | ||
|
|
||
| function get_endcontext_position( | ||
| a_context_ann_pos t_annotation_position, | ||
| a_package_annotations in out nocopy tt_annotations_by_name | ||
| ) return t_annotation_position is | ||
| l_next_endcontext_pos t_annotation_position; | ||
| l_next_context_pos t_annotation_position; | ||
| l_open_count integer := 0; | ||
| begin | ||
| if a_package_annotations.exists(gc_endcontext) and a_package_annotations.exists(gc_context) then | ||
| l_next_endcontext_pos := get_next_annotation_of_type(a_context_ann_pos, gc_endcontext, a_package_annotations); | ||
| l_next_context_pos := a_package_annotations(gc_context).next(a_context_ann_pos); | ||
|
pesse marked this conversation as resolved.
Outdated
|
||
|
|
||
| loop | ||
| -- Get all the %context annotations between start and first %endcontext | ||
| while l_next_context_pos is not null and l_next_context_pos < l_next_endcontext_pos loop | ||
| l_open_count := l_open_count+1; | ||
| l_next_context_pos := a_package_annotations(gc_context).next(l_next_context_pos); | ||
| end loop; | ||
| -- Skip as many %endcontexts as we had additional contexts open | ||
| while l_open_count > 0 loop | ||
| l_open_count := l_open_count-1; | ||
| l_next_endcontext_pos := a_package_annotations(gc_endcontext).next(l_next_endcontext_pos); | ||
| end loop; | ||
| -- Repeat until the next %context is later than next %endcontext | ||
| exit when l_next_context_pos is null or l_next_context_pos > l_next_endcontext_pos; | ||
|
pesse marked this conversation as resolved.
Outdated
|
||
| end loop; | ||
| end if; | ||
| return l_next_endcontext_pos; | ||
| end; | ||
|
|
||
| function has_nested_context( | ||
| a_context_ann_pos t_annotation_position, | ||
| a_package_annotations in out nocopy tt_annotations_by_name | ||
|
pesse marked this conversation as resolved.
Outdated
|
||
| ) return boolean is | ||
| l_next_endcontext_pos t_annotation_position; | ||
| l_next_context_pos t_annotation_position; | ||
| begin | ||
| if ( a_package_annotations.exists(gc_endcontext) and a_package_annotations.exists(gc_context)) then | ||
| l_next_endcontext_pos := get_next_annotation_of_type(a_context_ann_pos, gc_endcontext, a_package_annotations); | ||
| l_next_context_pos := a_package_annotations(gc_context).next(a_context_ann_pos); | ||
| if ( l_next_context_pos < l_next_endcontext_pos ) then | ||
| return true; | ||
|
pesse marked this conversation as resolved.
Outdated
|
||
| end if; | ||
| end if; | ||
| return false; | ||
| end; | ||
|
|
||
| function get_annotations_in_context( | ||
| a_annotations t_annotations_info, | ||
| a_context_pos t_annotation_position, | ||
|
|
@@ -753,7 +801,8 @@ create or replace package body ut_suite_builder is | |
| a_parent in out nocopy ut_suite, | ||
| a_annotations in out nocopy t_annotations_info, | ||
| a_suite_items out nocopy ut_suite_items, | ||
| a_parent_context_pos in integer := 0 | ||
| a_parent_context_pos in integer := 0, | ||
| a_parent_end_context_pos in integer default null | ||
| ) is | ||
| l_context_pos t_annotation_position; | ||
| l_next_context_pos t_annotation_position; | ||
|
|
@@ -768,26 +817,35 @@ create or replace package body ut_suite_builder is | |
| l_default_context_name t_object_name; | ||
| function get_context_name( | ||
| a_parent in out nocopy ut_suite, | ||
| a_context_names in tt_annotation_texts, | ||
| a_start_position binary_integer, | ||
| a_end_position binary_integer | ||
| a_start_position binary_integer | ||
| ) return varchar2 is | ||
| l_result t_annotation_name; | ||
| l_found boolean; | ||
| l_end_position binary_integer; | ||
| l_annotation_pos binary_integer; | ||
| l_context_names tt_annotation_texts; | ||
| begin | ||
| l_annotation_pos := a_context_names.first; | ||
| while l_annotation_pos is not null loop | ||
| if l_annotation_pos > a_start_position and l_annotation_pos < a_end_position then | ||
| if l_found then | ||
| add_annotation_ignored_warning(a_parent, gc_name,'Duplicate annotation %%%.', l_annotation_pos); | ||
| else | ||
| l_result := a_context_names(l_annotation_pos); | ||
| end if; | ||
| l_found := true; | ||
| end if; | ||
| l_annotation_pos := a_context_names.next(l_annotation_pos); | ||
| end loop; | ||
| if a_annotations.by_name.exists(gc_name) then | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks really great. |
||
| l_context_names := a_annotations.by_name( gc_name ); | ||
| l_end_position := | ||
| least( | ||
| coalesce( get_endcontext_position(a_start_position, a_annotations.by_name), a_annotations.by_line.last ), | ||
| coalesce( a_annotations.by_name(gc_context).next(a_start_position), a_annotations.by_line.last ) | ||
|
pesse marked this conversation as resolved.
Outdated
|
||
| ); | ||
| l_annotation_pos := l_context_names.first; | ||
|
|
||
| while l_annotation_pos is not null loop | ||
| if l_annotation_pos > a_start_position and l_annotation_pos < l_end_position then | ||
| if l_found then | ||
| add_annotation_ignored_warning(a_parent, gc_name,'Duplicate annotation %%%.', l_annotation_pos); | ||
| else | ||
| l_result := l_context_names(l_annotation_pos); | ||
| end if; | ||
| l_found := true; | ||
| end if; | ||
| l_annotation_pos := l_context_names.next(l_annotation_pos); | ||
| end loop; | ||
| end if; | ||
| return l_result; | ||
| end; | ||
| begin | ||
|
|
@@ -802,20 +860,9 @@ create or replace package body ut_suite_builder is | |
| l_default_context_name := 'nested_context_#'||l_context_no; | ||
| l_context_name := null; | ||
| l_end_context_pos := get_endcontext_position(l_context_pos, a_annotations.by_name ); | ||
|
|
||
| l_next_context_pos := a_annotations.by_name(gc_context).next(l_context_pos); | ||
| if a_annotations.by_name.exists(gc_name) then | ||
| l_context_name := | ||
| get_context_name( | ||
| a_parent, | ||
| a_annotations.by_name( gc_name ), | ||
| l_context_pos, | ||
| least( | ||
| coalesce( l_end_context_pos, a_annotations.by_line.last ), | ||
| coalesce( l_next_context_pos, a_annotations.by_line.last ) | ||
| ) | ||
| ); | ||
| end if; | ||
| l_context_name := get_context_name(a_parent, l_context_pos); | ||
|
|
||
| if not regexp_like( l_context_name, '^(\w|[$#])+$' ) or l_context_name is null then | ||
| if not regexp_like( l_context_name, '^(\w|[$#])+$' ) then | ||
| a_parent.put_warning( | ||
|
|
@@ -841,9 +888,8 @@ create or replace package body ut_suite_builder is | |
| l_context.parse_time := a_annotations.parse_time; | ||
|
|
||
| --if nested context found | ||
| if l_next_context_pos < l_end_context_pos or l_end_context_pos is null then | ||
| get_context_items( l_context, a_annotations, l_context_items, l_context_pos ); | ||
| l_end_context_pos := get_endcontext_position(l_context_pos, a_annotations.by_name ); | ||
| if has_nested_context(l_context_pos, a_annotations.by_name) then | ||
| get_context_items( l_context, a_annotations, l_context_items, l_context_pos, l_end_context_pos ); | ||
| else | ||
| l_context_items := ut_suite_items(); | ||
| end if; | ||
|
|
@@ -870,6 +916,10 @@ create or replace package body ut_suite_builder is | |
| exit when not a_annotations.by_name.exists( gc_context); | ||
|
|
||
| l_context_pos := a_annotations.by_name( gc_context).next( l_context_pos); | ||
| -- don't go on when the next context is outside the parent's context boundaries | ||
| if ( a_parent_end_context_pos is not null and a_parent_end_context_pos <= l_context_pos ) then | ||
|
pesse marked this conversation as resolved.
Outdated
|
||
| l_context_pos := null; | ||
| end if; | ||
| l_context_no := l_context_no + 1; | ||
| end loop; | ||
| end; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -767,6 +767,74 @@ create or replace package body test_suite_builder is | |
| ); | ||
| end; | ||
|
|
||
| procedure nested_contexts_2 is | ||
| l_actual clob; | ||
| l_annotations ut3.ut_annotations; | ||
| begin | ||
| --Arrange | ||
| l_annotations := ut3.ut_annotations( | ||
| ut3.ut_annotation( 1, 'suite','Cool', null), | ||
| ut3.ut_annotation( 2, 'suitepath','path', null), | ||
| ut3.ut_annotation( 3, 'context','Level 1', null), | ||
| ut3.ut_annotation( 4, 'name','context_1', null), | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add some tests in parent context of nested context before/after nested context.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't that already done with
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right |
||
| ut3.ut_annotation( 5, 'context','Level 1.1', null), | ||
| ut3.ut_annotation( 6, 'name','context_1_1', null), | ||
| ut3.ut_annotation( 7, 'test', 'Test 1.1.1', 'test_1_1_1'), | ||
| ut3.ut_annotation( 8, 'test', 'Test 1.1.2', 'test_1_1_2'), | ||
| ut3.ut_annotation( 9, 'endcontext', null, null), | ||
| ut3.ut_annotation(10, 'endcontext', null, null), | ||
| ut3.ut_annotation(11, 'context','Level 2', null), | ||
| ut3.ut_annotation(12, 'name','context_2', null), | ||
| ut3.ut_annotation(13, 'test', 'Test 2.1', 'test_2_1'), | ||
| ut3.ut_annotation(14, 'endcontext',null, null) | ||
| ); | ||
| --Act | ||
| l_actual := invoke_builder_for_annotations(l_annotations, 'SOME_PACKAGE'); | ||
| --Assert | ||
| ut.expect(l_actual).to_be_like( | ||
| '<ROWSET><ROW>'|| | ||
| '<UT_LOGICAL_SUITE>' || | ||
| '%<ITEMS>%' || | ||
| '<UT_SUITE_ITEM>' || | ||
| '%<NAME>context_1</NAME><DESCRIPTION>Level 1</DESCRIPTION><PATH>path.some_package.context_1</PATH>' || | ||
| '%<ITEMS>' || | ||
| '<UT_SUITE_ITEM>' || | ||
| '%<NAME>context_1_1</NAME><DESCRIPTION>Level 1.1</DESCRIPTION><PATH>path.some_package.context_1.context_1_1</PATH>' || | ||
| '%<ITEMS>' || | ||
| '<UT_SUITE_ITEM>' || | ||
| '%<NAME>test_1_1_1</NAME><DESCRIPTION>Test 1.1.1</DESCRIPTION><PATH>path.some_package.context_1.context_1_1.test_1_1_1</PATH>' || | ||
| '%</UT_SUITE_ITEM>' || | ||
| '<UT_SUITE_ITEM>' || | ||
| '%<NAME>test_1_1_2</NAME><DESCRIPTION>Test 1.1.2</DESCRIPTION><PATH>path.some_package.context_1.context_1_1.test_1_1_2</PATH>' || | ||
| '%</UT_SUITE_ITEM>' || | ||
| '</ITEMS>' || | ||
| '%<BEFORE_ALL_LIST/>' || | ||
| '%</UT_SUITE_ITEM>' || | ||
| '</ITEMS>' || | ||
| '%</UT_SUITE_ITEM>' || | ||
| '%</ITEMS>' || | ||
| '%</UT_LOGICAL_SUITE>'|| | ||
| '</ROW></ROWSET>' | ||
| ); | ||
| -- Test both contexts separately due to ordering | ||
| ut.expect(l_actual).to_be_like( | ||
| '<ROWSET><ROW>'|| | ||
| '<UT_LOGICAL_SUITE>' || | ||
| '%<ITEMS>%' || | ||
| '<UT_SUITE_ITEM>' || | ||
| '%<NAME>context_2</NAME><DESCRIPTION>Level 2</DESCRIPTION><PATH>path.some_package.context_2</PATH>' || | ||
| '%<ITEMS>' || | ||
| '<UT_SUITE_ITEM>' || | ||
| '%<NAME>test_2_1</NAME><DESCRIPTION>Test 2.1</DESCRIPTION><PATH>path.some_package.context_2.test_2_1</PATH>' || | ||
| '%</UT_SUITE_ITEM>' || | ||
| '%</ITEMS>' || | ||
| '%</UT_SUITE_ITEM>' || | ||
| '%</ITEMS>' || | ||
| '%</UT_LOGICAL_SUITE>'|| | ||
| '</ROW></ROWSET>' | ||
| ); | ||
| end; | ||
|
|
||
|
|
||
| procedure before_after_in_context is | ||
| l_actual clob; | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.